实践先直接看对比测试方法测试内容单一客户的使用尽可能快的方式向服务器发送一定量10000条请求并接收返回数据对于单一客户端对服务器进行http请求一般我们的方式1单进程或线程轮询请求这个效能自然很低原因会讲到也不用测试2多条线程提前准备数据等待信号对客户端性能要求较高3提前准备一组线程同时轮询操作4使用系统/平台自带异步发送机制实际就是平台线程池的方式发送与接收使用从线程池中的不同线程对于测试方案1及方案2测试中性能较低没有可比性后面测试不会展示其结果以下展示后面2种测试方法及当前要说的管线式的方式先讲管线式pipe测试方案原理在后面会讲到测试中使用100条管线管道实际上更少甚至一条管线也是能达到近似的性能不过多数服务器nginx限制一条管可以持续发送request的数量大部分是100也有部分会是200或是更高每条管线发送100个请求。然后是线程组的方式准备100条线程100条线程并不是很多不会对系统本身有明显影响每条线程轮询发送100个request。异步方式的方式10000全部提交发送线程由线程池控制接收。测试环境普通家用PCi5 4核12G 100Mb电信带宽测试数据GET http://www.baidu.com HTTP/1.1Content-Type: application/x-www-form-urlencodedHost: www.baidu.comConnection: Keep-Alive这里就是测试最常用的baidu如果测试接口性能不佳大部分请求会在应用服务器排队难以直观提现pipe的优势其实就是还没有用到pipe的能力服务器就先阻塞了下文中所有关于pipe的测试都是使用PipeHttpRuner http://www.cnblogs.com/lulianqi/p/8167843.html 为该测试工具的下载地址使用方法及介绍先直接看管道式的表现截图全部为windows自带任务管理器及资源管理器先解释下截图含义后面的截图也都是同样的含义第一副为任务管理器的截图实线为接收数据虚线为发送数据,取样0.5s每一个正方形的刻度为1.5s(因为任务管理器绘图策略速率上升太快过高的没有办法显示不过还是可以看到时间线第二副为资源管理器添加了3个采样器红色为CPU占用率蓝色为网络接收速率绿色为网络发送速率。测试中 一次原始请求大概130字节加上tcpip包头10000条大概也只有1.5Mb包头不会太多因为管道式请求里会有多个请求放到一个包里的情况不过大部分服务器无法有这么快的响应速度会有大量重传的情况实际上传流量可能远大于理论值一次的回包大概在60Mb左右因为会有部分连接中途中断所以不一定每次测试都会有10000个完整回复可以看到使用pipe形式性能表现非常突出总体完成测试仅仅使用了5s左右发送本身压力比较小可以看到0.5秒即到达峰值,其实这个时候基本10000条request已经发送出去了后面的流量主要来自于服务器端缓存等待TCP window Full来不及处理而照成是重传后面会讲到。再来看看response的接收基本上也仅仅使用了0.5s即达到了接收峰值使用大概5s 即完成了全部接收因为测试中cpu占用上升并不明显而对于response的接收基本上是从tcp缓存区读出后直接就存在了内容里也没有涉及磁盘操作所以基本上可以说对于pipe这个测试并没有发挥出其全部性能瓶颈主要在网络带宽上。再来看下线程组的方式100条线程每条100次下面是异步接收的方式很明显的差距对于线程组的形式大概使用了25秒而异步接收使用了超过1分钟的时间异步接收的模式是平台推荐的发送模式正常应用情况下性能是十分优越的而对于过高的压力不如自定义的线程组主要还是因为其使用了默认的线程池而默认线程池不可能在短时间开100条线程出来用来接收数据所以大量的回复对线程池里的线程就会有大量的切换通过设置默认线程池数量可以提高测试中的性能。更为重要的是这2者中的无论哪一种方式在测试中cpu的占用都几乎是满的即是说为了完成测试计算机已经满负荷工作了很难再有提高后面其实还针对jdtoabaoyouku包括公司自己的服务器进行过测试测试结果都是类似的只要服务器不出问题基本上都有超过10倍的差距(如果客户端带宽足够这个差距会更大)。下面我们再对接口形式的HTTP进行简单一次测试这里选用网易电商的接口电商的接口一般可承受的压力比较大这里前面已经确认测试不会对其正常使用造成实质的影响http://you.163.com/xhr/globalinfo/queryTop.json?__timestamp1514784144074 这里是一个获取商品列表的接口测试数据设置如下请求量还是10000条接收的response数据大概有326Mb 30s之内完成。基本上是网络的极限此时cpu也基本无然后压力100条管线每条100个请求这里其实请求是带时间戳的因为测试时使用的是同一个时间戳所以实际对应用服务器的影响不大真实测试时可以为每条请求设置不同时间戳这里是因为要演示使用了线上公开服务测试时请使用测试服务注意这里的测试如果选择了性能较低的测试对象大部分流量会在服务器端排队等候导致吞吐量不大这实际是服务器端处理过慢与客户端关系不大。一般情况下一台普通的pc在使用pipe进行测试时就可以让服务器出现明显延时原理正常的http一般实现都是连接完成后tcp握手发生request流向服务器然后及进入等待收到response后才算结束如下图当然http1.1 即支持keep alive完成一次收发后完全可以不关闭连接使用同一个链接发生下一个请求如下图这种方式对性能的提升还是比较明显的特别早些年服务器性能有限网络资源匮乏RTT大网络时延大。不过对如今的情况其实这些都已经不是最主要的问题了可以明显看到上面的模式是一定要等到response到达后客户端才能发起下一个request的如果应用服务器需要时间处理所有后面的请求都需要等待即使不需要任何处理直接回复给客户端请求回复在网络上的时间也是必须完整的等下去而且由于tcp传输本身的特性速率是逐步上升的这样断断续续的发送接收十分影响tcp迅速达到线路性能最大值。pipe 管线式正是回避了上面的问题他不需要等回复达到即可直接发送事实上http1.1协议也从来没有讲过必须要等response到达后客户端才能发送下一个请求只是为了方便应用层业务实现一般的http库都是这样实现的而现在看到的绝大多少http服务器都是默认支持pipe的这样发送与接收即可以分离开来如下图