1 优化目标

降低网络拥塞。总是有效吗?并不是,它们有特定的使用场景。

2 Nagle算法和Delayed ACK算法

在TCP/IP协议中,每一个报文都是由报文头(header)和报文体(payload)组成。就像我们网上买的书到了,书是装在一个袋子里,然后会贴一个标签,上面包含了一些关键信息,比如:发件人姓名、发件人电话、发件人地址、收件人姓名、收件人电话、收件人地址、物品简介。这里书类似报文体,标签上的关键信息类似报文头。

如果一个报文的报文体尺寸非常小,甚至比报文头还小,没有有效利用带宽,在网络流量很大是,这种报文会给网络带来更多的负担。比如你在同一家网店买30本书,如果分为30个快递邮寄给你,那么店家会下单30次,快递员会分拣送货30次,你也会拆30次快递,整个流程就会很低效,快递成本也会增加很多。因此最好将这30本书合并为一个快递邮寄给你。TCP报文头最多可占用40 Byte,每次只发送1 Byte的数据的程序是很常见的。如果系统立刻发送这种报文,那么一个报文总共有41 Byte,但是只有1 Byte是应用要发送的数据。我们的卡车本次只运输了一双拖鞋,这太低效了,会增加交通拥堵。发送报文时,Nagle算法会合并同一TCP流中的多个报文,保证合并后报文的报文头与报文体的比例处于合理范围,提高带宽利用效率,降低网络拥塞。Nagle算法延迟了报文的发送,增加了延迟,对于一些强调交互的场景,会降低用户体验。

延迟ACK(Delayed ACK)是降低拥塞的另一种方案。在TCP协议中,报文接收方会对收到的每个bit发送确认,就像我们在淘宝上确认收货一样,发送方才会继续发送后续的报文。如下图,ACK报文只有报文头,报文体为0 Byte,如果报文特别多,频繁进行确认,大量的ACK报文占用了带宽,造成网络拥塞。延迟ACK的策略就是设置一个定时器(200~500ms),延迟ACK收到的报文,待定时器超时后对这些报文一次性进行批量ACK。有缺点,有些场景下会增加程序网络延迟,比如这条TCP流中报文不是很多。这个策略我们收快递时也会使用,双11买了很多东西,一般不会收到一个后立马就确认收货,而是等差不多都收到后的某一天集中确认收货,省事儿。

然而这两种算法并不适合一起协作。延迟ACK算法延迟了ACK的发送,但是Nagle算法却在等待ACK报文,以便继续发送其他报文。

3 Socket选项

配置TCP_NODELAY选项可以关闭Negal算法,内核就会立刻将Socket缓存中的数据交给网卡。配置TCP_QUICKACK选项可以关闭延迟ACK机制,收到报文后,会立刻发送ACK报文。

4 如何确定是否需要打开TCP_NODELAY选项(关闭Negal算法)?

对于一些强调吞吐量而不是延迟的非交互式场景,比如大文件传输,关闭TCP_NODELAY选项,即使用Negle算法可能是一个好的选择。

像网络游戏、即时聊天、流媒体等高度交互式的场景,延迟是衡量服务质量的一个重要指标,因此打开TCP_NODELAY选项对提升用户体验可能会更有帮助。

总的来说,没有一个非常有效的规则来判断是否需要打开TCP_NODELAY选项,最好在做出决定前有一些基准测试数据(打开vs关闭)。

5 参考资料

https://www.extrahop.com/company/blog/2016/tcp-nodelay-nagle-quickack-best-practices/

内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/sniperlx/p/14405648.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!