wireshark分析TCP吞吐瓶颈

———— 原文:https://www.kawabangga.com/posts/4794
words: 1.2k    views:    time: 4min
tcp


理解下吞吐量低的原因,以及如何通过wireshark来确认

吞吐量低的原因

关于网络质量一般会关注两个因素:延迟和吞吐量(带宽)。延迟比较好验证,ping一下或者mtr一下就能看出来,而吞吐量则可能有3个方面的影响:

  • 发送端出现了瓶颈
  • 接收端出现了瓶颈
  • 中间的网络层出现了瓶颈

发送端出现瓶颈一般的情况是buffer不够大,因为发送的过程是,应用调用syscall,将要发送的数据放到buffer,然后由系统负责发送出去。如果buffer满了,那么应用会阻塞住(如果使用block的API的话),直到buffer可用了再继续write,生产者和消费者模式。

所以发送端出现瓶颈一般都比较好排查,甚至通过应用的日志看何时阻塞住了即可。后面两种情况比较麻烦,此时发送端的应用已经将内容写入到了系统的 buffer 中,但是系统并没有很快的发送出去。

Tcp保护

TCP为了优化传输效率,(这里的传输效率,并不是单纯某一个TCP连接的传输效率,而是整体网络的效率),会对接收端和网络进行保护

接收端保护

在连接建立的时候,会协商接收端的buffer大小(receiver window size, rwnd), 并且在后续的发送中,接收端也会在每一个ack回包中报告自己剩余和接受的window大小。这样,发送端在发送的时候会保证不会发送超过接收端buffer大小的数据。

网络保护

对于网络的保护,原理也是维护一个Window,叫做拥塞窗口(Congestion window, cwnd),这个窗口就是当前网络的限制,发送端不会发送超过这个窗口的容量(未收到ack的总数不会超过cwnd)。

默认通过算法cubic来确定,思路是通过慢启动(slow start)发送数据来测试,如果能正确收到receiver那边的ack,说明当前网络能容纳这个吞吐,然后将cwnd翻倍,继续测试,直到下面一种情况发生:

  1. 发送的包没有收到ACK
  2. cwnd已经等于rwnd了

第2种情况很好理解,说明瓶颈不在网络,而在于接收端的buffer不够大。对于第1情况,其实就是发送端是用丢包来检测网络状况的,如果发生丢包,说明网络处理不了这个发送速度,这时候发送端会直接将cwnd减半。但造成第1种情况的并不一定是网络吞吐瓶颈,而可能有以下几种情况:

  • 网络达到了瓶颈
  • 网络质量问题丢包
  • 中间网络设备延迟了包的送达,导致发送端没有在预期时间内收到ACK

所以下面就是想通过wireshark来分析吞吐量的原因,是在接受端还是中间网络,是真的网络吞吐量低还是别的原因

wireshark分析

  • 接收端rwnd查看

真正的window size需要乘以factor, factor是在TCP握手节点通过TCP Options协商的。所以要分析一条TCP连接的window size,必须抓到握手阶段的包,不然不知道factor是多少。

  • 中间网络cwnd查看方式

cwnd是发送端通过算法得到的一个动态变量,会实时调整,并不会体现在协议的传输数据中,只能在发送端的机器上看。

在Linux中可以使用ss -i选项将TCP连接的参数都打印出来,不过这里展示的单位是TCP MSS(数据包数),通常每包1460bytes

  • wireshark统计分析

使用wireshark的统计功能

因为tcptrace图表示的是单方向的数据,如果数据为空,说明看反了

一共有3条线,最上面表示接收端的窗口,中间的表示已经发出去等待Ack的包,最下面表示收到了Ack的包

如果出现了红色SACK,表示出现了丢包重传

接收端窗口限制

图中可以看出,黄色的线一上升(收到接收端ACK),蓝色就跟着上升(发送端开始发),直到填满绿色的线(接收端窗口),说明还可以调大接收端的buffer,网络并不是瓶颈。

网络限制

图中可以看出,接收端的窗口还有很多空闲,但是发送端发送的数据包上不去

放大可以看出,中间有很多丢包和重传,并且每次只发送一点点数据,说明很有可能是cwnd太小了,受到了拥塞控制算法的限制


参考: