如何实现超高性能的管线式HTTP请求实践?
- 内容介绍
- 文章标签
- 相关推荐
本文共计2051个文字,预计阅读时间需要9分钟。
这里的性能指标主要是指网络卡有多快。请求数量越多,发送速度就越快。一般来说,一台服务器的客户端压力下,就会出现明显的延迟。本篇实际是介绍pipe管道的原理,下面主要通过其高性能的测试实例来展示。
这里的高性能指的就是网卡有多快请求发送就能有多快,基本上一般的服务器在一台客户端的压力下就会出现明显延时。 该篇实际是介绍pipe管线的原理,下面主要通过其高性能的测试实践,解析背后数据流量及原理。最后附带一个简单的实现 实践 先直接看对比测试方法 测试内容单一客户的使用尽可能快的方式向服务器发送一定量(10000条)请求,并接收返回数据 对于单一客户端对服务器进行www.baidu.com HTTP/1.1 Content-Type: application/x-www-form-urlencoded Host: www.baidu.com Connection: Keep-Alive 这里就是测试最常用的baidu,如果测试接口性能不佳,大部分请求会在应用服务器排队,难以直观提现pipe的优势(其实就是还没有用到pipe的能力,服务器就先阻塞了) 下文中所有关于pipe的测试都是使用PipeHttpRuner(www.cnblogs.com/lulianqi/p/8167843.html 为该测试工具的下载地址,使用方法及介绍) 先直接看管道式的表现:(截图全部为windows自带任务管理器及资源管理器) 先解释下截图含义,后面的截图也都是同样的含义 第一副为任务管理器的截图实线为接收数据,虚线为发送数据,取样0.5s,每一个正方形的刻度为1.5s(因为任务管理器绘图策略速率上升太快过高的没有办法显示,不过还是可以看到时间线) 第二副为资源管理器,添加了3个采样器,红色为CPU占用率,蓝色为网络接收速率,绿色为网络发送速率。 测试中 一次原始请求大概130字节,加上tcp,ip包头,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的占用都几乎是满的(即是说为了完成测试计算机已经满负荷工作了,很难再有提高) 后面其实还针对jd,toabao,youku,包括公司自己的服务器进行过测试,测试结果都是类似的,只要服务器不出问题基本上都有超过10倍的差距(如果客户端带宽足够这个差距会更大)。 下面我们再对接口形式的HTTP进行简单一次测试 这里选用网易电商的接口(电商的接口一般可承受的压力比较大,这里前面已经确认测试不会对其正常使用造成实质的影响) you.163.com/xhr/globalinfo/queryTop.json?__timestamp=1514784144074 (这里是一个获取商品列表的接口) 测试数据设置如下 请求量还是10000条接收的response数据大概有326Mb 30s之内完成。基本上是网络的极限,此时cpu也基本无然后压力(100条管线,每条100个请求) 这里其实请求是带时间戳的,因为测试时使用的是同一个时间戳,所以实际对应用服务器的影响不大,真实测试时可以为每条请求设置不同时间戳(这里是因为要演示使用了线上公开服务,测试时请使用测试服务) 注意,这里的测试如果选择了性能较低的测试对象,大部分流量会在服务器端排队等候,导致吞吐量不大,这实际是服务器端处理过慢,与客户端关系不大。 一般情况下一台普通的pc在使用pipe进行测试时就可以让服务器出现明显延时 原理 正常的ask.wireshark.org/questions/29216/why-are-duplicate-tcp-acks-being-seen-in-wireshark-capture 产生原因可以参考这里) 其实就是说服务器没有发现下一个包后面又发了3次(一共4次·)TCP DUP ACK 都是针对353的,所以后面客户端很快就重传了TCP DUP ACK 所指定的丢失的包(即下面看到的362) 后面还可以看到由于过快的速度,还造成了部分的失序列(out of order)。不过需要说明的是,这些错误在tcp的传输中是很常见的,tcp有自己的一套高效的机制对这些错误进行恢复,即便有这些错误的存在也不会对pipe的实际性能造成影响。 如果服务器异常误包不能马上被恢复可能会造成指数退避的情况如下图 高速收发带来的问题,不仅有丢包,失序,重传,无论是客户端还是服务器都会有接收窗口耗尽的情况,如果接收端窗口耗尽会出现TCP ZeroWIndow / Window full。 所以无论是客户端还是服务器都需要快速读取tcp缓冲区数据本文共计2051个文字,预计阅读时间需要9分钟。
这里的性能指标主要是指网络卡有多快。请求数量越多,发送速度就越快。一般来说,一台服务器的客户端压力下,就会出现明显的延迟。本篇实际是介绍pipe管道的原理,下面主要通过其高性能的测试实例来展示。
这里的高性能指的就是网卡有多快请求发送就能有多快,基本上一般的服务器在一台客户端的压力下就会出现明显延时。 该篇实际是介绍pipe管线的原理,下面主要通过其高性能的测试实践,解析背后数据流量及原理。最后附带一个简单的实现 实践 先直接看对比测试方法 测试内容单一客户的使用尽可能快的方式向服务器发送一定量(10000条)请求,并接收返回数据 对于单一客户端对服务器进行www.baidu.com HTTP/1.1 Content-Type: application/x-www-form-urlencoded Host: www.baidu.com Connection: Keep-Alive 这里就是测试最常用的baidu,如果测试接口性能不佳,大部分请求会在应用服务器排队,难以直观提现pipe的优势(其实就是还没有用到pipe的能力,服务器就先阻塞了) 下文中所有关于pipe的测试都是使用PipeHttpRuner(www.cnblogs.com/lulianqi/p/8167843.html 为该测试工具的下载地址,使用方法及介绍) 先直接看管道式的表现:(截图全部为windows自带任务管理器及资源管理器) 先解释下截图含义,后面的截图也都是同样的含义 第一副为任务管理器的截图实线为接收数据,虚线为发送数据,取样0.5s,每一个正方形的刻度为1.5s(因为任务管理器绘图策略速率上升太快过高的没有办法显示,不过还是可以看到时间线) 第二副为资源管理器,添加了3个采样器,红色为CPU占用率,蓝色为网络接收速率,绿色为网络发送速率。 测试中 一次原始请求大概130字节,加上tcp,ip包头,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的占用都几乎是满的(即是说为了完成测试计算机已经满负荷工作了,很难再有提高) 后面其实还针对jd,toabao,youku,包括公司自己的服务器进行过测试,测试结果都是类似的,只要服务器不出问题基本上都有超过10倍的差距(如果客户端带宽足够这个差距会更大)。 下面我们再对接口形式的HTTP进行简单一次测试 这里选用网易电商的接口(电商的接口一般可承受的压力比较大,这里前面已经确认测试不会对其正常使用造成实质的影响) you.163.com/xhr/globalinfo/queryTop.json?__timestamp=1514784144074 (这里是一个获取商品列表的接口) 测试数据设置如下 请求量还是10000条接收的response数据大概有326Mb 30s之内完成。基本上是网络的极限,此时cpu也基本无然后压力(100条管线,每条100个请求) 这里其实请求是带时间戳的,因为测试时使用的是同一个时间戳,所以实际对应用服务器的影响不大,真实测试时可以为每条请求设置不同时间戳(这里是因为要演示使用了线上公开服务,测试时请使用测试服务) 注意,这里的测试如果选择了性能较低的测试对象,大部分流量会在服务器端排队等候,导致吞吐量不大,这实际是服务器端处理过慢,与客户端关系不大。 一般情况下一台普通的pc在使用pipe进行测试时就可以让服务器出现明显延时 原理 正常的ask.wireshark.org/questions/29216/why-are-duplicate-tcp-acks-being-seen-in-wireshark-capture 产生原因可以参考这里) 其实就是说服务器没有发现下一个包后面又发了3次(一共4次·)TCP DUP ACK 都是针对353的,所以后面客户端很快就重传了TCP DUP ACK 所指定的丢失的包(即下面看到的362) 后面还可以看到由于过快的速度,还造成了部分的失序列(out of order)。不过需要说明的是,这些错误在tcp的传输中是很常见的,tcp有自己的一套高效的机制对这些错误进行恢复,即便有这些错误的存在也不会对pipe的实际性能造成影响。 如果服务器异常误包不能马上被恢复可能会造成指数退避的情况如下图 高速收发带来的问题,不仅有丢包,失序,重传,无论是客户端还是服务器都会有接收窗口耗尽的情况,如果接收端窗口耗尽会出现TCP ZeroWIndow / Window full。 所以无论是客户端还是服务器都需要快速读取tcp缓冲区数据
