TCP 确认暂停,然后恢复,然后再次暂停。为什么?

TCP 确认暂停,然后恢复,然后再次暂停。为什么?

我希望得到一些帮助来找出我的应用程序中数据传输率降低的原因。

我有 12 个嵌入式系统和一个 Linux 服务器。嵌入式系统通过交换机在以太网链路上通过 TCP 向服务器发送数据。以下是使用 Wireshark 捕获一块主板的流量后生成的 TCP StreamGraph。

TCP 流图

如您所见,数据传输速度约为 5.8MBit/s,耗时约为 0.25 秒。这是我预期嵌入式系统能达到的最快速度。此后,传输中会出现延迟。下图是该图的特写:

缩放流图

底部标有 ACK 的阶梯形曲线显示服务器在任意时间确认了多少数据。标有 RWIN 的相应曲线显示数据计算机上的缓冲区中有多少空间。标有 SENT DATA 的较小垂直段是实际发送的数据包。

在点 A,服务器以与发送数据相同的速度确认数据,但随后 23 毫秒内服务器未发送任何确认。嵌入式系统可以不等待确认就向 RWIN 发送数据,但它没有这样做,因为它需要保留已发送的数据直到确认(以防需要重新传输),并且发送缓冲区空间有限。

然后,在点 B,所有接收到的数据都会被立即确认,并且正常确认和发送会在 2.5 毫秒内恢复,然后才会再次发生暂停。

Wireshark 捕获是从另一台 PC 进行的,该 PC 连接到交换机的一个端口,该端口设置为镜像嵌入式系统连接到的端口上发送和接收的所有数据。

Linux 服务器运行 Java 应用程序,用于处理数据并将其存储在磁盘上。它没有显示出 CPU 超负荷的迹象。操作系统是 Ubuntu Server 12.04,采用默认网络设置。

我可以看到,在嵌入式系统中分配更多的发送缓冲区空间以匹配 Linux 服务器中的接收窗口空间量可能会有所帮助,但这似乎不是这里的限制因素。

我的问题是:

  1. 尽管 Linux 服务器显然能够正常接收所有内容,但它暂停 ACK 的原因可能是什么?
  2. 我该如何调试这个问题?

答案1

尝试使用 关闭以太网 PAUSE 帧ethtool -A devname autoneg off rx off tx off

如果这没有帮助,则可能是 TCP 窗口缩放问题和/或发送或接收主机上的 IRQ 风暴问题。您可以尝试使用不同的设置和ethtoolsysctl 条目来调查这两个问题,以调节 TCP 流量。

如果没有其他信息,很难说出这里发生了什么...

答案2

另一个显而易见的问题是客户端为什么停止发送?通常,客户端不会停下来等待 ACK 再发送下一个 TCP 数据包。它们是否可能发送被 Nagle 算法延迟的单字节消息?

https://en.wikipedia.org/wiki/Nagle%27s_algorithm

如果是,并且您的 Linux 服务器正在使用 TCP 延迟确认,那么您可以预期 ACK 延迟长达 500 毫秒。

https://en.wikipedia.org/wiki/TCP_delayed_acknowledgment

如果是这种情况,那么可以通过使用更大的消息或在嵌入式系统 (TCP_NODELAY) 上禁用 Nagle 算法来轻松修复。

相关内容