一次简单的 HTTP 调用,为什么时延这么大?抓个包分析下
如果 A 向 B 发一个数据包,B 由于 Delayed ACK 不会立即响应。而 A 使用 Nagle 算法,A 就会一直等 B 的 ACK,ACK 不来一直不发送第二个数据包,如果这两个数据包是应对同一个请求,那这个请求就会被耽误了 40ms。 5.5 抓个包玩玩吧 我们来抓个包验证下吧,在后端HTTP服务上执行以下脚本,就可以轻松完成抓包过程。
如下图,这是使用 Wireshark 分析包内容的展示,红框内是一个完整的 POST 请求处理过程,看 130 序号和 149 序号之间相差 40ms(0.1859 - 0.1448 = 0.0411s = 41ms),这个就是 Nagle 与 Delayed ACK 一起发送的化学反应,其中 10.48.159.165 运行的是 Delayed ACK,10.22.29.180 运行的是 Nagle 算法。10.22.29.180 在等 ACK,而 10.48.159.165 触发了 Delayed ACK,这样傻傻等了 40ms。 ![]() 这也就解释了为什么测试环境耗时是 39.2ms,因为大部分都被 Delayed ACK 的 40ms 给耽误了。 但是本地复现时,为什么本地测试的平均时延是 55ms,而不是 ping 的时延 26ms?我们也来抓个包吧。 如下图,红框内是一个完整的 POST 请求处理过程,看 8 序号和 9 序号之间相差 25ms 左右,再减去网络延时约是ping延时的一半 13ms,因此 Delayed Ack 约 12ms 左右(由于本地是 MAC 系统与 Linux 有些差异)。 ![]()
5.6 为什么 TCP_NODELAY 能够解决问题? TCPNODELAY 关闭了 Nagle 算法,即使上个数据包的 ACK 没有到达,也会发送下个数据包,进而打破 Delayed ACK 造成的影响。一般在网络编程中,强烈建议开启 TCPNODELAY,来提升响应速度。 当然也可以通过 Delayed ACK 相关系统的配置来解决问题,但由于需要修改机器配置,很不方便,因此,这种方式不太推荐。 6. 总结 (编辑:西安站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |