过多的“TCP Dup ACK”和“TCP 快速重传”会导致网络出现问题。这是什么原因造成的?

Ing*_*ram 8 tcp wireshark packet

当我通过 MetroEthernet 链接传输文件时,我在我们的网络上收到过多的 TCP Dup ACK 和 TCP 快速重传。这两个站点由一个 sonicwall 路由器连接,因此站点之间只有一跳。

是来自wireshark的屏幕截图,是整个捕获。在这个捕获中,客户端是 192.168.2.153,服务器是 192.168.1.101 这是从我的系统到服务器的跟踪路由(ping 时间通常稳定在 10 毫秒以下):

user@pc567:~$ ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:e0:b8:c8:0c:7e  
          inet addr:192.168.2.153  Bcast:192.168.2.255  Mask:255.255.255.0
          inet6 addr: fe80::2e0:b8ff:fec8:c7e/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:244994 errors:0 dropped:0 overruns:0 frame:0
          TX packets:149148 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:319571991 (319.5 MB)  TX bytes:12322180 (12.3 MB)
          Interrupt:16 

user@pc567:~$ traceroute -n 192.168.1.101
traceroute to 192.168.1.101 (192.168.1.101), 30 hops max, 60 byte packets
 1  192.168.2.254  0.747 ms  0.706 ms  0.806 ms
 2  192.168.1.101  8.995 ms  9.217 ms  9.477 ms
user@pc567:~$
Run Code Online (Sandbox Code Playgroud)

任何有关导致这种情况的帮助都会有所帮助!我可以发布更多需要的细节。

更新:从这开始,我用 1800 cisco 路由器替换了 sonicwall。安装了它的数据包捕获具有相同的结果。由于它是城域以太网电路,因此不需要路由器。因此,我还尝试将笔记本电脑直接连接到两个站点的服务提供商设备,并将它们放在同一个子网中。以这种方式进行的数据包捕获看起来是一样的。这使我相信城域以太网电路存在问题,即使他们继续说没有问题并且一切测试正常。

小智 5

我意识到这个答案很简单,并不像我希望的那么明确,所以如果您对某个步骤有疑问,请询问!

在 Wireshark 中打开此文件后向下滚动一点,我们会看到一些不同颜色的框架。看起来真的很糟糕,对吧?嗯,情况并没有那么糟糕。坚持住,我们会到达那里。

检查 SYN 数据包(第 37 帧),我们在 TCP 选项中看到 SACK 和窗口缩放。好的。SYN/ACK(第 38 帧)、SACK 和 Windows 缩放中也有同样的情况。惊人的。没有发现 SACK 有什么奇怪的地方。

卸载 RTT 的估计是 SYN 数据包和第一个 ACK​​(帧 39)之间的时间。大约为 9.3 毫秒,与您的发现相符。请注意,SYN/ACK 和 ACK(帧 38 和 39)之间的时间比 SYN 和 SYN/ACK(帧 37 和 38)之间的时间短得多。这意味着该捕获文件是在接收器处获取的,要了解为什么这不理想,我们必须返回学校。

发送方和接收方之间有一段网络路径最小,这限制了带宽。我们刚刚从握手中获得的 RTT 估计为我们提供了该网络路径长度的估计。衡量此管道中可以容纳多少数据包的指标是管道容量或带宽延迟乘积- PC [位] = R [位/秒] * RTT [秒],其中 R 是最小带宽。管道容量是体积的度量。

想象一下花园软管。它的体积是由它的长度和宽度以同样的方式测量的,对吗?为了从其中获得最多的水,它需要完全充​​满水,否则会出现空气间隙限制水流。如果我们设法完全填满它,它可能会溢出。我们可以使用水桶,这样就不会弄湿地板,而且如果水桶溢出也不会影响水流。

事实证明,在网络路径上是完全一样的。我们需要填满管道...换句话说,管道容量是发送者和接收者之间充分利用最小带宽(不会导致气隙)。因此,如果飞行中的字节数> PC,那么我们就很好了!

查看 TCP 跟踪 统计 -> TCP StreamGraph -> 时间序列图 (tcptrace),我们可以看到 Y 轴上的字节和 X 轴上的时间。该曲线的导数是字节/秒,或吞吐量。请注意黑色“线”是平坦的,这意味着吞吐量是稳定的!虽然它被蓝线中断了几次(这些是重复 ACK 中的 SACK 范围),但可以看出它不会影响吞吐量。

看看右下角的灰色实线(放大一点,那就是 ACK)是如何非常接近黑色 TCP 段的?TCP报文段和ACK之间的时间就是RTT,这里几乎为0!这意味着飞行中经过该捕获点的航段并不多。这反过来意味着我们不能用它来估计传输中的字节,这就是为什么发送方数据包捕获更好的原因。

这里的数据包在捕获点之前自然会丢失。丢失时正在传输的每个数据段都会触发重复的 ACK。因此,我们可以使用重复 ACK 的数量来估计丢包时传输中的字节数。这里我们看到大约 9、16 和 23 段。每个段有 1448 字节的数据,所以这给了我们 13k 到 33k 之间的字节数。这里的吞吐量约为 3 Mbit/s(来自IO 图),并且在获得管道容量之前测量的 RTT 小于 3e6 [bits/s] * 10e-3 [s] / 8 字节 = 3750 字节,或者少于3段。

因为这些丢失时传输的字节并不完全相同(这里很难用这么少的样本来判断),我真的不能说这些是随机丢失(这很糟糕)还是因为队列而发生的丢失/bucket 溢出,但它们发生在传输中的字节数 > PC 时,因此吞吐量不受影响。

您的回答似乎表明它们确实是随机的,但没有那么多导致吞吐量低。


sys*_*138 2

看看您提供的捕获(感谢您这样做!)我可以在开始时看到一个非常经典的重传模式。您可以在数据包 50 周围看到它。在 51 和 52 之间缺少一个数据包。发生的情况是这样的:

  1. --> 数据包 50 个数据
  2. <-- 数据包 51 ACK 数据包 50。
  3. --> 数据包 52 数据
  4. <-- 数据包 53 ACK 数据包 50。
  5. --> 数据包 54 数据
  6. <-- 数据包 55 ACK 数据包 50。

数据包被丢弃,接收方通过继续 ACK 数据包(直到目前为止看到的数据)来指示这一点。这里有趣的是,双方TCP SACK Permitted Option = True在协商连接时都已设置,因此数据包 55 中应该有 SACK 标头,但事实并非如此。选择性确认允许接收器指示“我已经看到了 51 以内的所有内容,但也看到了 53-55”,这减少了使内容恢复到全速所需的重传量。

由于它无法使用 SACK,因此会退回到标准 TCP 重传方法,即重复“我已看到最多 50 个”,直到另一方弄清楚并重传 50 及之后的所有内容。

数据包 66 中有一次重传,紧接着是一个 ACK​​,直到数据包 56。第二次重传(数据包 72)后,连接回到正轨。

首先,SACK 标头很可能被声波墙剥离,这导致重传无法像协商的那样快速恢复。就我个人而言,我认为剥离 SACK 是没有意义的,但其他人可能不同意。

从我在这张捕获中可以看出,您会看到偶尔出现数据包丢失,这导致 TCP 连接通过正常的重传协议。防火墙正在妨碍双方协商的重传方法不被允许。