«

TCP时延对HTTP性能的影响-IT中华

IT中华 发布于 阅读:244 网络安全与技术分享


我们都知道HTTP是在TCP/IP协议上建立的,那么和TCP/IP相关的内容也都会影响着HTTP,今天我们来了解一下都有哪些方面会影响到HTTP的传输性能。

那么在聊主题之前,先来说说从客户端到服务器都经历了哪些:

DNS请求
发送TCP建联请求
响应TCP建联请求
确认响应
发送HTTP请求
服务端处理请求
响应HTTP请求
关闭连接

  1. TCP连接的握手时延:
    TCP的三次握手是每次在创建新的连接时必不可少的,他需要花费一定的时间,如果响应的HTTP内容很少的话,那么TCP连接的时间可能就会占据多一半的时间。

比如我这请求的数据很小,10ms就可以传完,但是我要先和你建联,我们建联就花了30ms,那么我总共花了40ms才得到这个数据。这里TCP的时延就对HTTP的请求造成了很大的影响。发送大量类似的这种包还有个专有名词,叫“发送端傻窗口综合症”(发送端即响应端)。

  1. 延迟确认:
    延迟确认中的“确认”其实就是对应上图【7.响应HTTP请求】中的前两个包,这两个包的LEN=0,作用就是告诉5中那两个请求包,我收到了请求。因为每一个或多个请求包都会有一个对应的回应包,这样发送方才能确保之前发的对方已经全部收到了,不然如果发送方在特定时间内没有收到回应包,是会重传请求包的。那么延迟确认就指的是对于【7.响应HTTP请求】中的前两个包,它们觉得就为了回应请求包,我就专门发两个包出去有点浪费,如果大家都这么发容易网络拥挤。所以我想先等等,如果一会还有回应请求的数据包要发,我就把这个回应包“捎带”过去,这就减少了回应的次数,也就相当于减少了网络中的数据包数。默认这个回应包等待时间是40ms,如果每次确认都需要等待,要是有其它响应包给你捎带还好,要是没有需要等待40ms,这就会比较影响HTTP的传输性能了。上面那个截图我计算了一下,没有40ms延迟,估计是Linux服务器对这个延迟确认的时间做了优化,应该是调低了,我知道的红帽的实时内核延迟确认给调到了4ms,其他的操作系统目前不太清楚。

3.TCP慢启动
在连接成功后,如果请求方需要请求获取一个大的文件,需要响应方发送40个响应包。此时响应方并不会一次将40个数据包全部发送给请求方,而是先发送1个响应包,请求方收到这1个响应后,回应响应方收到该包,然后响应方再发送2个响应包,请求方收到并回应,然后响应方依次4,8,16个等成倍数的发送,直到达到一个特定的值之后才开始比较稳定快速的发包,比如每次16个,18个,20个这样。那么,我们管前期成倍发包的方式称为“TCP慢启动”。TCP慢启动的作用是为了减少网络拥塞或突然过载,和延迟确认的作用差不多。既然TCP存在慢启动,那么无疑HTTP在传输开始也会受到它的影响,会慢一点。

4.Nagle算法(根据发明者John Nagle命名)
Nagle算法其实就是每次响应数据包要凑够固定大小(Linux默认为1500字节)再发送,除非请求方其他数据包全部确认收到,就差这一个了,响应方才可以把这个不满1500字节的数据包发出去。可是面临了两个性能问题:

和延迟确认类似,如果有1500字节,那就直接发出去了,如果没有的话,需要在缓冲区等待其他数据,凑够1500字节再发送,这无疑会增加延迟。
请求方开启了延迟确认,响应方开启了Nagle算法,那么响应方再发送最后一个包时(不满1500字节),会等待响应方后续的响应数据或请求方发送的最后一个分组的确认包,因为是最后一个包了,所以响应方后续没有包了,那么只能等待请求方发送的最后一个分组的确认包,这个不足1500字节的响应包才会被发出去,但是这个时候请求方开启了延迟确认,它需要等40ms才发出去,那么那个最后的响应包也要相应的等待这40ms。
不过这个Nagle算法在HTTP应用程序中一般是被关闭的,那就作为一个了解吧。

5.性能测试下的一种特殊情况——端口耗尽
首先会出现这个特殊情况的原因是,每个主动关闭TCP连接的一方(一般为请求方),都会将请求方的ip与端口和响应方的ip与端口在内存中保留一小段时间,通常为2MSL(可以为2分钟 1分钟 30秒),以确保不会再有相同地址和端口的请求包发送,此时请求方的连接状态为TIME_WAIT。如下图:

现在特殊情况就是:假设只有一台用来测试的客户端和一台web服务器,我想用来测试服务端的性能。每次客户端发送一个请求,就会占用一个端口。假设客户端一共有6W个端口可以使用,那我可以做到每秒6W次的请求来测试吗?答案是不可以的,因为第一次6W次请求,下一次要等待2MSL(假设为120秒),平均算下只能60000/120=500秒/次,这个也就是单台测试的瓶颈了,再快,客户端的可用端口没有了,因为还处于TIME_WAIT状态中。如果没有注意到这点的话,测试可能会与实际结果不一致的。所以如果做大访问量的性能测试,可增加客户端负载生成器的数量或循环使用多个虚拟IP。

即使没有遇到端口耗尽的问题,也要特别小心有大量连接处于打开状态或TIME_WAIT状态的连接,因为在这些情况下,有些操作系统的速度会严重减缓。

以上内容多参考自《HTTP权威指南》。

推荐阅读:


扫描二维码,在手机上阅读