滑动窗口 滑动窗口(Sliding window)是一种流量控制技术。 早期的网络通信中,通信双方不会考虑网络的拥挤情况直接发送数据。 由于大家不知道网络拥塞状况,同时发送数据,导致中间节点阻塞掉包,谁也发不了数据,所以就有了滑动窗口机制来解决此问题。 其实滑动窗口就是互相的协商, 发送的数据不能超过对方的处理能力. ?
image.png
#1 表示已经发送并确认的数据
#2 表示已经发送但是并未 Ack 的数据
#3 表示即将要发送还未发送的数据
#4 表示没有发送的数据
image.png
黑色的框就是我们说的滑动窗口, 它的大小为 20 字节, 当 #2 Ack回来的时候, 会重新返回对方的窗口大小, 然后发送方进行动态调节。 ?
image.png
上图展示了发送窗口和接收窗口两端的实际执行情况, 有意思的是最后出现了 窗口占满(window=0) 的情况, 通常这种情况会发生 RST 标志位进行重置, 这个不再此次范围讨论里面。 从图中我们可以看到 Server 端每次根据自身消费数据缓冲区情况,重新计算 RCV.WND 值大小, ACK 响应给 Client 端都会携带 window 字段, Client 端根据 Server端的 window 大小, 重新调整了 发送窗口 大小。
Nagle算法
John Nagle是Nagle算法的发明人,后者就是用他的名字来命名的,他在1984年首次用这种方法来尝试解决福特汽车公司的网络拥塞问题。 他解决的问题就是所谓的silly window syndrome,中文称“愚蠢窗口症候群”。 具体含义是,因为普遍终端应用程序每产生一次击键操作就会发送一个包,而典型情况下一个包会拥有一个字节的数据载荷以及40 个字节长的包头,于是产生4000%的过载,很轻易地就能令网络发生拥塞。 Nagle化后来成了一种标准并且立即在因特网上得以实现。 它现在已经成为缺省配置了,但在我们看来,有些场合下把这一选项关掉也是合乎需要的。
如果频繁的进行 TCP小包 通信, 网络效率是非常低下的, 对于发送方来说我们可以使用 Nagle 算法来提高传输效率。 Nagle 算法也是一种减少TCP小包发送数据包的一种优化算法,算法策略: 1.没有发送未确认报文时候,立刻发送;
- 如果存在未确认报文,需要等到【没有已发送未确认报文】或者【数据包长度达到MSS大小】,再发送数据。
只有收到前一数据的 ACK 消息时或者超时40ms、达到了 MSS 值时, Nagle 算法才发送下一份数据。 TCP 套接字默认使用的 Nagle 算法交换数据, 因此最大限度地进行缓冲, 直到收到 ACK。
借用网上一张图表示:
?
启用这个算法后,如果我们通过telnet慢速敲入HELLO,刚开始要发送H,虽然包很小,但是没有需要确认的包,可以立刻发送,但是发送完毕后,由于H的确认还没有来,所以还必须等待,直到H报文的ACK报文来的,报文也积累了ELL三个字符。 这个算法默认是开启的,可以通过设置socket 的TCP_NODELAY 选项来关闭。
TCP_NODELAY If set, disable the Nagle algorithm. This means that segments are always sent as soon as possible, even if there is only a small amount of data. When not set, data is buffered until there is a sufficient amount to send out, thereby avoiding the frequent sending of small packets, which results in poor utilization of the network. This option is overridden by TCP_CORK; however, setting this option forces an explicit flush of pending output, even if TCP_CORK is currently set. ?
## 关闭Nagle算法(设置on其实是关闭)
tcp_nodelay on;
## 开启Nagle算法(设置off是开启)
tcp_nodelay off;
延迟确认(tcp delayed ack)
接收方在收到数据后,并不会立即回复ACK, 而是延迟一定时间 或者 达到2x最大段数据长度为止 (不同操作系统实现并不一致)
- 这样做的目的是合并ACK,也就是指如果连续收到两个TCP包,并不一定需要ACK两次,只要回复最终的ACK就可以了,可以降低网络流量。
- 如果接收方有数据要发送,那么就会在发送数据的TCP数据包里,带上ACK信息。这样做,可以避免大量的ACK以一个单独的TCP包发送,减少了网络流量。
TCP 套接,默认情况下,采用的就是延迟确认机制。 查看TCP帮助,TCP_QUICKACK ,只有TCP套接字设置了这个选项才会开启快速确认。
TCP_QUICKACK (since Linux 2.4.4)
Enable quickack mode if set or disable quickack mode if cleared. In quickack mode, acks are sent immediately, rather than delayed if
needed in accordance to normal TCP operation. This flag is not permanent, it only enables a switch to or from quickack mode. Subsequent
operation of the TCP protocol will once again enter/leave quickack mode depending on internal protocol processing and factors such as
delayed ack timeouts occurring and data transfer. This option should not be used in code intended to be portable.
看到 40ms 这个值,你有没有想起什么东西呢? 实际上,这是 TCP 延迟确认(Delayed ACK)的最小超时时间。 只有RHEL可以通过/proc/sys/net/ipv4/tcp_delack_min修改(默认40ms),而其他发行版都不支持。 Nagle和延迟确认本身都没有问题,但一起用就会影响性能。 结合在一起的时候,就有可能导致延迟过大的问题: ?
1. 当 Sever 发送了第一个分组后,由于 Client 开启了延迟确认,就需要等待 40ms 后才会回复 ACK。
2. 同时,由于 Server 端开启了 Nagle,而这时还没收到第一个分组的 ACK,Server 也会在这里一直等着。
3. 直到 40ms 超时后,Client 才会回复 ACK,然后,Server 才会继续发送第二个分组。
解决方法很简单,要么在关闭Nagle算法(推荐),要么关闭延迟确认。 能设置客户端的TCP_QUICKACK解决吗? 只是客户端有可能在用户那儿,可能无法控制这些选项。 按理说,世界上到处都有启用了Nagle和延迟确认的设备在通信,为什么很少有人说起呢? 我猜测大多数受害者并没有发现这个原因,以为是带宽不足所致,所以就一直忍着。
小结 网络延迟,是最核心的网络性能指标。 由于网络传输、网络包处理等各种因素的影响,网络延迟不可避免。但过大的网络延迟,会直接影响用户的体验。 在发现网络延迟增大后,你可以用 traceroute、hping3、tcpdump、Wireshark、strace 等多种工具,来定位网络中的潜在问题。比如,
- 使用 hping3 以及 wrk 等工具,确认单次请求和并发请求情况的网络延迟是否正常。
- 使用 traceroute,确认路由是否正确,并查看路由中每一跳网关的延迟。
- 使用 tcpdump 和 Wireshark,确认网络包的收发是否正常。
- 使用 strace 等,观察应用程序对网络套接字的调用情况是否正常。
这样,你就可以依次从路由、网络包的收发、再到应用程序等,逐层排查,直到定位问题根源。 参考 Nagle算法和延迟确认结合的奇妙反应 https://mp.weixin.qq.com/s/e2dKgP5rLO3SDgI9trgDcg wireshark排查网络延迟问题 https://mp.weixin.qq.com/s/XTNSdLJGVVSZbGETOrLjRQ TCP/IP 之 滑动窗口和延迟确认 https://mp.weixin.qq.com/s/biPusaXG_pKiDqRFO0Jc-A TCP Performance problems caused by interaction between Nagle’s Algorithm and Delayed ACK http://www.stuartcheshire.org/papers/nagledelayedack 网络请求延迟变大了,我该怎么办? https://time.geekbang.org/column/article/82833 ?
参考博客链接:https://www.jianshu.com/p/da0cd673209c
更多C/C++ Linux 服务器后端技术解说以及面试经验面题请关注狮,会不定期更新的哦~
|