TCP协议Nagle算法和Delayed ACK相互影响实例分析

来源:互联网 发布:金蝶在线软件 编辑:程序博客网 时间:2024/05/18 01:28

建议:阅读本文之前,最好对于TCP的发送、重发以及ACK机制有所了解。

问题描述

最近在一个消息中间件系统(该消息中间件由客户端SDK和服务端Server组成)的性能测试时,发现每个请求的响应时间大概在40ms-50ms之间,这明显过大了。最终定位,是因为SDK没有禁用TCP的Nagle算法导致的。但其根本原理是因为TCP的Delayed Ack机制和Nagle Algorithm相互影响导致的。

概念详解

TCP-Delayed Ack
目的:用于防止只发送一个单独的Ack包,而是希望发送的包是一个Ack+一份数据组成一个包,这样能较少交互次数,减少网络资源消耗。这个设定是基于对于一般交互场景的一个基本假设:数据接收方会生成一个响应给数据发送方。
原理:当数据接收方收到一个TCP包之后,先不回应ACK包,而是等待一定的时间(本例中是40ms),直到
1. 数据接收方发送一份响应数据
当数据接收方,收到足够的数据,进行业务处理后,一般会返回业务响应,这时会立即返回:业务响应+ACK。
2. 接收到连续的TCP包
当服务接收端接收到1号TCP包后,会先延迟发送1号包的ACK,等待2号包到来,2号包到达时,则立即返回一次ACK;当3号包到来时,会延迟3号包的ACK,等待4号包到来,4号包到达时,则立即返回一次ACK……
那么,这样就造成偶数序号的TCP包到达的时候,就会立即返回一次ACK;而奇数序号的包到达时,则延迟ACK响应,等待后续的偶数包到来。
3. 超时
超过40ms。

TCP-Nagle Algorithm
目的:用于防止发送大量的小包,降低网络资源消耗。
原理:当数据发送方写入TCP缓冲区的数据小于MSS(最大报文长度),则暂不发送,等待写入的数据达到MSS再发送;除非在等待的过程中,发送端发送出去的所有TCP报文均已被ACK,这样就可以不用等待写入数据达到MSS,直接发送出去了。我们称没有达到MSS的报文为小包的话,那么其实TCP-Nagle Algorithm就保证了一个连接在一个时刻,有且只能有一个没有被确认的小包。
关于以上两点,可以参考这篇文章,介绍的很详细:http://www.stuartcheshire.org/papers/NagleDelayedAck/

过程分析

该消息中间件系统在做性能测试时,SDK没有禁用Nagle算法,而Server端禁用了;测试时的消息长度为消息头(12)+消息体(14)Byte,TCP MSS是1460Byte;服务端和SDK交互采用类似TCP三次握手的确认机制来保证高可靠性。那么考虑如下过程:
1. SDK端发送第一条消息,写入了TCP Buffer,虽然未达到MSS,但是因为没有需要确认的包,所以会立即发送;
2. Server端收到TCP包后,就延迟ACK响应;同时SDK端由于启用了Nagle算法,并且存在没有ACK的包,因此处于等待中;
3. Server端业务层解包进行业务处理,处理完成后,立即发送业务响应,并捎带ACK返回给SDK;
4. SDK端收到了Server端返回的响应和ACK后,立即回复业务确认消息,并捎带ACK;
5. 由于Server端收到业务确认消息后,不用再返回响应给SDK,因此延迟ACK确认;
6. SDK端发送第二条消息,但是因为启用了Nagle算法,所以必须等待ACK。直到第5步的延迟确认到达,则立即发送第二条消息。

Tcpdump抓包如下:

2015-05-25 18:42:49.736897 IP 100.84.52.90.58237 > 100.84.73.45.9090: P 71:101(30) ack 20 win 16420E..FU3@.=..OdT4ZdTI-.}#...(.R.mpP.@$.).......)....queueAThis is test 2015-05-25 18:42:49.737763 IP 100.84.73.45.9090 > 100.84.52.90.58237: P 20:39(19) ack 101 win 46E..;Fn@.@...dTI-dT4Z#..}R.mp..) P...F].......*......SUCCESS2015-05-25 18:42:49.744738 IP 100.84.52.90.58237 > 100.84.73.45.9090: P 101:113(12) ack 39 win 16415E..4U4@.=..`dT4ZdTI-.}#...) R.m.P.@.d........4......2015-05-25 18:42:49.784810 IP 100.84.73.45.9090 > 100.84.52.90.58237: . ack 113 win 46E..(Fo@.@..1dTI-dT4Z#..}R.m...).P.......2015-05-25 18:42:49.785438 IP 100.84.52.90.58237 > 100.84.73.45.9090: P 113:143(30) ack 39 win 16415E..FU5@.=..MdT4ZdTI-.}#...).R.m.P.@..........)....queueAThis is test 2015-05-25 18:42:49.785450 IP 100.84.73.45.9090 > 100.84.52.90.58237: . ack 143 win 46E..(Fp@.@..0dTI-dT4Z#..}R.m...)3P.......2015-05-25 18:42:49.786147 IP 100.84.73.45.9090 > 100.84.52.90.58237: P 39:58(19) ack 143 win 46E..;Fq@.@...dTI-dT4Z#..}R.m...)3P...F].......*......SUCCESS2015-05-25 18:42:49.790470 IP 100.84.52.90.58237 > 100.84.73.45.9090: P 143:173(30) ack 58 win 16410E..(Fo@.@..1dTI-dT4Z#..}R.m...).P.......

总结:通过以上过程可以发现,由于第5步的延迟ACK,导致SDK发送消息延迟,最终导致了性能下降。如果SDK端关闭的Nagle算法,SDK就可以立即发送第二条消息,而不会受到Nagle算法的约束,一直等待第5步的ACK到达。

代码说明

在Netty中,可以通过设置tcpNoDelay选项,开启或者禁用Nagle算法。

// 用来禁用TCP的Nagle算法。bootstrap.setOption("tcpNoDelay", true);// Netty底层其实就是使用JDK中的Socket.class的setTcpNoDelay方法来设置。/*** Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).*/public void setTcpNoDelay(boolean on) throws SocketException;
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 长春花长得太高怎么办 四季梅叶子蔫了怎么办 吸财树叶子蔫了怎么办 民族团结手抄报间单有漂亮怎么办 鹦鹉尾巴毛掉了怎么办 羊绒衫领子打太大了怎么办 内裤洗了还有一股味道怎么办 月经下不来内裤上总有脏东西怎么办 夏天外衣薄露出内衣怎么办 金毛体味很重怎么办 直筒连衣裙太短怎么办 托班社会下雨了怎么办 托班下雨了怎么办教案 吃鸡界面有鼠标怎么办 老年机成英语了怎么办 手机成了英语了怎么办 塑料袋融化粘到衣服上怎么办 厕所被卫生纸堵了怎么办 钻石画的胶不粘了怎么办 客厅沙发选大了怎么办 连衣裙腰大了怎么办呀 憋尿后出现尿急尿涨怎么办 脚有酸酸的味道怎么办 三星手机home键失灵怎么办 三星s6返回键失灵怎么办 三星s7屏幕漏液怎么办 三星s8出现蓝框怎么办 三星手机短信图标没了怎么办 ps没有足够的ram怎么办 ps性能调不了是怎么办 苹果6p照相模糊怎么办 相框玻璃碎了怎么办 word文档加密后忘记密码怎么办 手机wps密码忘了怎么办 苹果手表忘了密码怎么办 苹果系统忘了密码怎么办 ps画板建小了怎么办 wps表格密码忘了怎么办 word文档变成虚的怎么办 wps论文中表格跨页怎么办 word文档复制过来有边框怎么办