如何使用 Wireshark 分析 TCP 吞吐瓶颈

公众号关注 「奇妙的 Linux 世界」

设为「星标」,每天带你玩转 Linux !

b684430fe5e6d376935b6d1d35e11767.png

作者:laixintao

出处:https://www.kawabangga.com/posts/4794

Debug 网络质量的时候,我们一般会关注两个因素:延迟和吞吐量(带宽)。延迟比较好验证,Ping 一下或者 mtr[1] 一下就能看出来。这篇文章分享一个 debug 吞吐量的办法。

看重吞吐量的场景一般是所谓的长肥管道(Long Fat Networks, LFN, rfc7323[2]). 比如下载大文件。吞吐量没有达到网络的上限,主要可能受 3 个方面的影响:

  1. 发送端出现了瓶颈

  2. 接收端出现了瓶颈

  3. 中间的网络层出现了瓶颈

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

149114a7ae3f2fef365e6aecb96ac15c.png

发送端出现瓶颈一般都比较好排查,甚至通过应用的日志看何时阻塞住了即可。大部分情况都是第 2,3 种情况,比较难以排查。这种情况发生在,发送端的应用已经将内容写入到了系统的 buffer 中,但是系统并没有很快的发送出去。

TCP 为了优化传输效率(注意这里的传输效率,并不是单纯某一个 TCP 连接的传输效率,而是整体网络的效率),会:

  1. 保护接收端,发送的数据不会超过接收端的 buffer 大小 (Flow control)。数据发送到接受端,也是和上面介绍的过程类似,kernel 先负责收好包放到 buffer 中,然后上层应用程序处理这个 buffer 中的内容,如果接收端的 buffer 过小,那么很容易出现瓶颈,即应用程序还没来得及处理就被填满了。那么如果数据继续发过来,buffer 存不下,接收端只能丢弃。

  2. 保护网络,发送的数据不会 overwhelming 网络 (Congestion Control, 拥塞控制), 如果中间的网络出现瓶颈,会导致长肥管道的吞吐不理想;

对于接收端的保护,在两边连接建立的时候,会协商好接收端的 buffer 大小 (receiver window size, rwnd), 并且在后续的发送中,接收端也会在每一个 ack 回包中报告自己剩余和接受的 window 大小。这样,发送端在发送的时候会保证不会发送超过接收端 buffer 大小的数据。(意思是,发送端需要负责,receiver 没有 ack 的总数,不会超过 receiver 的 buffer.)

8b881499b732f9be5e71a9177347f5ce.png

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

怎么找到这个 cwnd 的值呢?

这个就是关键了,默认的算法是 cubic, 也有其他算法可以使用,比如 Google 的 BBR[3].

主要的逻辑是,慢启动(Slow start), 发送数据来测试,如果能正确收到 receiver 那边的 ack,说明当前网络能容纳这个吞吐,将 cwnd x 2,然后继续测试。直到下面一种情况发生:

  1. 发送的包没有收到 ACK

  2. cwnd 已经等于 rwnd 了

第 2 点很好理解,说明网络吞吐并不是一个瓶颈,瓶颈是在接收端的 buffer 不够大。cwnd 不能超过 rwnd,不然会 overload 接收端。

对于第 1 点,本质上,发送端是用丢包来检测网络状况的,如果没有发生丢包,表示一切正常,如果发生丢包,说明网络处理不了这个发送速度,这时候发送端会直接将 cwnd 减半。

但实际造成第 1 点的情况并不一定是网络吞吐瓶颈,而可能是以下几种情况:

  1. 网络达到了瓶颈

  2. 网络质量问题丢包

  3. 中间网络设备延迟了包的送达,导致发送端没有在预期时间内收到 ACK

2 和 3 原因都会造成 cwnd 下降,无法充分利用网络吞吐。

以上就是基本的原理,下面介绍如何定位这种问题。

rwnd 查看方式

这个 window size 直接就在 TCP header 里面,抓下来就能看这个字段。

e2f9d811acc9688c8a02c737e47110ca.png

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

d62b380e1553edaf8ce430bbb1d88527.png

cwnd 查看方式

Congestion control 是发送端通过算法得到的一个动态变量,会试试调整,并不会体现在协议的传输数据中。所以要看这个,必须在发送端的机器上看。

在 Linux 中可以使用 ss -i 选项将 TCP 连接的参数都打印出来。

0f1de17e2c9589466db3950be0354548.png

这里展示的单位是 TCP MSS.[5] 即实际大小是 1460bytes * 10.

Wireshark 分析

Wireshark 提供了非常使用的统计功能,可以让你一眼就能看出当前的瓶颈是发生在了哪里。但是第一次打开这个图我不会看,一脸懵逼,也没查到资料要怎么看。好在我同事[6]会,他把我教会了,我在这里记录一下,把你也教会。

首先,打开的方式如下:

deaf45225fcd55d8b6d1a0cc0ef779c5.png

然后你会看到如下的图。

5d1f29ac1dc1fe427306a6e47fda817d.png

首先需要明确,tcptrace 的图表示的是单方向的数据发送,因为 tcp 是双工协议,两边都能发送数据。其中最上面写了你当前在看的图数据是从 10.0.0.1 发送到 192.168.0.1 的,然后按右下角的按钮可以切换看的方向。

X 轴表示的是时间,很好理解。

然后理解一下 Y 轴表示的 Sequence Number, 就是 TCP 包中的 Sequence Number,这个很关键。图中所有的数据,都是以 Sequence Number 为准的。

所以,你如果看到如上图所示,那么说明你看反了,因为数据的 Sequence Number 并没有增加过,说明几乎没有发送过数据,需要点击 Switch Direction。

3e6a5d434765f143c476b591b6483403.png

这就对了,可以看到我们传输的 Sequence Number 在随着时间增加而增加。

这里面有 3 条线,含义如下:

21fb1b0792de868625d2e7c1051078b2.png

除此之外,另外还有两种线:

eda5dd31c74fa77f34536cdb70c52fcd.png

需要始终记住的是 Y 轴是 Sequence Number,红色的线表示 SACK 的线表示这一段 Sequence Number 我已经收到了,然后配合黄色线表示 ACK 过的 Sequence Number,那么发送端就会知道,在中间这段空挡,包丢了,红色线和黄色线纵向的空白,是没有被 ACK 的包。所以,需要重新传输。而蓝色的线就是表示又重新传输了一遍。

学会了看这些图,我们可以认识几种常见的 pattern:

丢包

ad0d931e7fb6fd55d42dda0acbcddee3.png

很多红色 SACK,说明接收端那边重复在说:中间有一个包我没有收到,中间有一个包我没有收到。

吞吐受到接收 window size 限制

d5c276f057d1efa10a777f06d21df84c.png

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

吞吐受到网络质量限制

e5c6edadb0a6e57d1f65d1a1ccc71940.png

从这张图中可以看出,接收端的 window size 远远不是瓶颈,还有很多空闲。

745d91a375d6590ddd4f451480eb7fbd.png

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

参考资料

[1]

mtr: https://www.kawabangga.com/posts/4275

[2]

rfc7323: https://datatracker.ietf.org/doc/html/rfc7323

[3]

BBR: https://www.kawabangga.com/posts/4086

[4]

TCP 握手节点通过 TCP Options 协商的: https://en.wikipedia.org/wiki/TCP_window_scale_option

[5]

TCP MSS.: https://www.cloudflare.com/learning/network-layer/what-is-mss/

[6]

spate: https://github.com/royzhr/spate

本文转载自:「进击云原生」,原文:https://url.hi-linux.com/CVxLR,版权归原作者所有。欢迎投稿,投稿邮箱: editor@hi-linux.com。

1a73972a81a4f66e1204670ce1060220.gif

最近,我们建立了一个技术交流微信群。目前群里已加入了不少行业内的大神,有兴趣的同学可以加入和我们一起交流技术,在 「奇妙的 Linux 世界」 公众号直接回复 「加群」 邀请你入群。

a1f5131ce3d6fd7a3ef21aaeb5c18f32.png

你可能还喜欢

点击下方图片即可阅读

f08185be94b9790b938464b246f5f072.png

AFFiNE: 下一代全能知识库工具,可取代 Notion 和 Miro 的免费开源替代品

566a1bf940add658a82279c37f42a3cd.png
点击上方图片,『美团|饿了么』外卖红包天天免费领

3ebcff81f18122a19bfd864429f73ff4.png

更多有趣的互联网新鲜事,关注「奇妙的互联网」视频号全了解!

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值