实战网络问题排查(四) -- 利用 wireshark 排查 TCP 连接与重传问题

2021-06-18 18:18:21   最后更新: 2021-06-18 18:18:21   访问数量:289




上一篇文章中,我们较为详细的介绍了 wireshark 的用法:

实战网络问题排查(三) -- wireshark 使用详解

 

使用 wireshark 最为重要的当然是要利用它来诊断网络问题了。

本文我们就通过 wireshark 来看看遇到这几类网络问题时我们应该如何着手吧。

本文主要参考《Network Analysis Using Wireshark Cookbook》Chapter9 的前4节。

 

TCP 建立连接和通信的过程想必你早已经烂熟于心了,你也可以参看我之前写的这篇文章:

TCP连接的建立和终止

 

2.1 连接建立

如图所示,这三行就是 TCP 三次握手的过程:

 

 

首先,客户端 TCP 进程发送了一个 SYN 报文,初始序列号 Seq 为 0,除此之外,我们还能在 wireshark 中看到 MSS、Selective ACK 等等更为详细的信息:

 

 

这些信息里,你可能比较关心:

  • Maximum Segment Size (MSS) -- 最大报文长度,单个 TCP 报文的最大长度。
  • Windows Size (WSopt) -- 窗口大小。
  • SACK -- 也就是 Selective ACK,当需要重传时,只需要重传单个丢失的报文,只有两端均支持这一特性的时候才会启用。
  • Timestamps options (TSopt) -- 客户端与服务端之间的延时。

 

第二行的消息,是服务端 ACK 客户端的 SYN 报文,同时也包含了服务端的 SYN 信息。

报文中包含了服务器端的初始序列号以及服务端窗口大小等信息。

除了客户端报文的序列号外,第三行客户端 ACK 的报文中,再次指明了客户端窗口大小。

 

2.2 问题排查

很简单,如果你在抓包结果中看到客户端发送 SYN 报文后,服务端没有任何回复或者回复了 RST 报文,那么显然,服务端的对应端口可能没有被监听、主动拒绝,或者被防火墙拦截。

你可以确认客户端、服务端均正常运行后,检测防火墙配置,检查你传递的用户名、密码是否正确,以及你要访问的 ip、端口是否正确。

你可能会通过 ping 命令去检测服务端是否存活,但很多情况下,服务端会通过防火墙屏蔽 ICMP 报文,所以你无法 ping 通服务端,但这不代表 server 已经挂掉了。

 

TCP 通信过程中一个最常见的问题就是 TCP 重传。

TCP 重传是 TCP 用来恢复受损、丢失、重复或失序的一个重要机制,如果发送方一段时间内未收到已发送包的确认,发送方就会触发重传。

在通信过程中,如果 TCP 重传的报文达到 0.5%,就会对性能产生严重影响,如果达到了 5%,那 TCP 连接就将会中断。

在 wireshark 中,重传报文被标记为 TCP Retransmission。

通过配置显示过滤器获取当前抓包结果中所有的重传报文:

expert.message == "Retransmission (suspected)"

 

如图所示:

 

 

3.1 Case1. 对多个目的地址发生重传

就像上面这张图,你会发现 Destination 并不集中,分布于多个目的服务器,这通常是链路问题,可能是你的网卡负载过高。

通过 wireshark 的 Statistics 菜单的 IO Graph 选项,可以打开 wireshark 的 IO 负载监控,由此你可以看到当前机器上的通信是不是已经达到了网卡的负载瓶颈。

 

 

如果像上图这样,网卡负载不高,那有可能是因为网卡或链路中存在故障或其他挤占带宽的高负载链路。

你可以登录到链路中的通信设备查看丢包率。

 

3.2 Case2. 重传只发生在同一个目的地址

 

 

上图这样的情况,所有的重传都集中在同一个目的地址上,这通常是应用自己的处理性能低造成的。

想要进一步确认是否是这个原因引起的,你可以按照下面的步骤来看:

  1. 如上一节中介绍的,通过 wireshark 提供的 IO Graph 查看网络负载是否过高。
  2. 通过 Statistics 菜单的 Conversation 选项,打开网络会话窗口,在 IPv4 选项卡下,勾选 Limit to display filter 复选框,就可以看到所有发生重传的会话,可以进一步确认。
  3. 在网络会话窗口中,点击 TCP 选项卡,同样勾选 Limit to display filter 复选框,可以查看具体的重传端口,确认是哪个应用,从而定位具体的问题。

 

 

 

可以特殊关注一下,发生重传的时间是否符合一定的周期性或事件触发性,例如下图中,每 30ms 左右发生一次重传,这恰好与客户端在软件中执行某个操作的时间相符,这就很可能是这个操作触发了慢请求的发生。

 

 

3.3 Case3. 应用无响应导致重传

如果在建立连接时发送 SYN 或 ACK 包之后紧接着发生多次重传,并且重传间隔越来越大,这通常是由于应用无响应造成的。

 

 

在这样的情况下,排查应用无响应的原因,15 到 20 秒以后,应用可能会去尝试重新建立连接,你也可以手动重启应用去重新建立连接。

 

3.4 Case4. 网络抖动造成的重传

TCP 协议本身拥有 Nagle 算法、滑动窗口协议、慢启动、拥塞避免、快速恢复等方法来避免网络拥塞的发生,可以参看:

Nagle 算法与滑动窗口协议

发送端流量控制算法

 

但是网络抖动对于 TCP 协议来说是一个影响很大的问题,当网络抖动时,经常会触发 TCP 重传。

想要确认这一问题,可以执行 ping 目的地址,观察 time 值的变化,可以观察到是否有波动。

可以检查:

  1. 链路是否拥塞,链路状态是否稳定。
  2. 安装应用程序的服务器是否资源不足或存在硬件故障或者配置过低。
  3. 网络链路中是否有设备过载或资源不足。

 

上述这几类问题,总的来说,可以遵循以下思路来解决问题:

  1. 归纳总结:问题是否与某台主机、某个特定的 TCP 连接或者某种具体行为相关联。
  2. 逐一排查:链路是否负载过高,链路是否存在丢包,服务器或者客户端主机是否存在性能问题,应用程序是否存在性能问题。
  3. 最终问题:是否是网络抖动引起的。

 

我的经验是,绝大部分性能问题都是业务层面引起的,也就是说是应用代码造成的,所以最先需要排查的是应用代码是否在性能问题出现时有过某些修改,这些修改是否会带来这些性能问题,充分否定这一情况以后,再花费精力去借助工具抓包分析网络链路上的问题,否则最终很容易发现是南辕北辙,缘木求鱼。

通常,问题并不会是由于网络抖动引起的,虽然这是最轻松的归因,但大部分情况下归咎于网络抖动只是懒惰的表现。

 

欢迎关注微信公众号,以技术为主,涉及历史、人文等多领域的学习与感悟,每周都有精彩推文,全部原创,只有干货没有鸡汤

 

 

《Network Analysis Using Wireshark Cookbook》

https://subscription.packtpub.com/book/networking_and_servers/9781849517645/1

 

 

TCP/IP 详解






linux      network      tcp      tcpdump      wireshark      cookbook      retransimition     


京ICP备2021035038号