记一次wireshark分析问题实战与总结
作为一名后台软件开发者(coder),随时面临着复杂的网络原因导致的各类问题,排查问题也有一定的难度。好在有一把网络问题分析的屠龙宝刀,那就是wireshark神器,本文将举例使用wireshark分析一个产品的故障原因。
1、问题背景
某一天项目报了一个产品的现场问题,现场发现在早上8点~9点期间,该系统的A软件和另一侧系统的B软件不断的进行连接、断开。项目人员在这段时间内使用wireshark抓包发回来分析,在该项目中,A软件为客户端程序,B软件作为服务端。A软件需要连接B软件,并进行通信获取有效信息。于是,本次实战是基于这种断连场景的问题分析之旅。
根据项目反馈的配置信息,现场客户端A端的IP是10.255.68.42,服务器B端的IP是10.108.11.4,实时任务的端口是2608。在该产品的设计中,A端为客户端,B端为服务器端,采用的传统的C/S架构。
由于是反复断开、连接,因此我需要在wireshark抓包中看一下FIN报文有没有。于是使用过滤命令筛选如下:
tcp.flags.fin == 1 and (ip.dst == 10.255.68.42 and ip.src == 10.108.11.4) ;
我们发现,从服务器B端没有FIN报文发给客户端A。然后我们再看看是不是客户端A主动发起的断开连接,从而发送了FIN报文。
过滤命令如下:tcp.flags.fin == 1 and(ip.src == 10.255.68.42 and ip.dst==10.108.11.4)果然发现了FIN报文从客户端侧发送给服务端侧的。
然后,我们跟踪一个TCP链路的流看一下是什么原因导致客户端A侧主动发起close socket呢?
-
序号69462的报文是由服务端B发了最后一包Len=52字节的消息。
-
序号72481的报文由于客户端A检查超时,关闭连接。系统内核会生成一个FIN报文,然后序号72495报文由服务端B侧的内核进行了ACK应答。
-
序号为79702的报文继续使用之前的链路发送一个长度为14字节的心跳包,由于链路不可用,因此客户端A侧内核主动生成了RST报文,提醒此链路不可用。
然后和现场运维团队核对了一下配置,目前的应用层配置是心跳包周期是10秒,超时检查是15秒,断开与重连是因为心跳超时导致的。通过抓包分析说明,每次都是A作为客户端)主动断开的连接。至于15秒内为什么服务端B侧没有发送心跳包,则需要结合B侧软件业务和设计进行分析。
2、扩展与延伸
在抓包中也可以经常看到RST报文,比如在之前有一次另一个项目报过一个问题,与某其他厂商的系统没有数据导致服务不可用。于是现场的运维人员使用telnet命令测试了一下,发现对方服务端拒绝连接。
实际上这种场景,通过抓包也是可以看到RST报文的。比如我所在的虚拟机80端口没有监听,这个时候客户端想连接服务端的 80 端口会怎样呢?在客户端(10.211.55.10)开启 tcpdump 抓包,然后尝试连接服务器的 80 端口。
通过tcpdump可以看到客户端发了一个 SYN 包到服务器,服务器马上回了一个 RST 包,表示拒绝连接。
在上面分析该项目反复断连的时候,在一方发送了FIN报文且对端回复了ACK后继续使用此链路进行发送消息,也会自动产生RST报文进行重置连接。这种场景在我们另一个产品的BS架构下采用的Nginx作为反向代理,以常用的okhttp发送http为例。
比如Nginx的 keepalive 时间默认是 65s,客户端请求了第一次以后,开始闲下来,65s 倒计时到了以后 Nginx 主动发起连接要求正常分手断掉连接,客户端的操作系统回了一个ACK。但是okhttp连接池并不知道这个情况,没有关闭这个socket,而是继续用这个断掉的连接发起 http 请求,tcpdump 抓包结果如下:
- 第1~3包,是A 与B 三次握手过程过程。
- 第4~5包,是A 向B 发起 HTTP 请求报文,服务器 B 回了 ACK。
- 第6~7包,B 向A 发送 HTTP 响应报文,客户端 A 收到报文以后回了 ACK。
- 第8~9包,经过65s,客户端 A 没有任何后续请求,Nginx 决定断掉这个连接,于是发送了一个 FIN 给客户端 A。
- 第10包,客户端 A 继续发送 HTTP 请求报文到 B。
- 第11包,因为此时 B 已经不能发送任何报文到 A,于是发送了一个 RST 包给 A,让它可以尽早断开这条连接。
3、总结
wireshark和tcpdump确实是我们分析网络问题的利器。通过这次问题分析,也加强了与项目人员的沟通交流,对于我们来说也是一次实战与提升分析问题能力的机会。此外,在分析出问题原因之后,解决也就有针对性了。
在之前我介绍过一篇文章《深入理解TCP协议之滑动窗口》,是我在一次项目实战中通过滑动窗口分析出软件的性能瓶颈,为后续优化提供了支撑作用。
我们上面分析出由于心跳超时导致的网络断连,那么我们可以延伸下去思考如何在大量TCP连接的场景下判断心跳是否超时呢?我们后续再聊。
本文地址:https://blog.csdn.net/wengsuwei7683/article/details/109646671
上一篇: ae中继器怎么做环形旋转? ae中继器绕一个圆的技巧
下一篇: Java编写实现坦克大战小游戏