文章

Wireshark 网络分析实战:连不上、很慢、偶发断流的定位方法(由浅入深)

面向日常网络故障排查的 Wireshark 教程,从抓包基础到 TCP 重传、DNS 解析、TLS 握手与性能瓶颈分析,覆盖“连不上、太慢、时好时坏”等高频问题

Wireshark 网络分析实战:连不上、很慢、偶发断流的定位方法(由浅入深)

很多同学遇到网络问题时,第一反应是“重启一下”“换个网络试试”。这些方法有时有效,但不能解释为什么。而 Wireshark 的价值,就在于把“玄学网络问题”变成“可观测、可验证、可复现”的工程问题。

这篇文章会围绕三个最常见场景展开:

  • 连不上(连接失败、超时、拒绝)
  • 太慢(打开慢、下载慢、偶发卡顿)
  • 时好时坏(间歇性失败、偶发断流、重试后恢复)

并给出一套可以直接复用的排查路径。


一、先建立正确心智:Wireshark 不是“看日志”,而是“看现场”

Wireshark 抓到的是网卡上的数据包,通常比应用日志更接近真相。日志可能说“请求超时”,但 Wireshark 能告诉你:

  • 是 DNS 根本没解析出来?
  • 还是 TCP 三次握手失败?
  • 还是 TLS 握手卡住?
  • 或者服务端响应了,但客户端没收到?

一句话:日志告诉你“失败了”,抓包告诉你“怎么失败的”。


二、抓包前准备:避免一上来就抓“满天星”

2.1 选对网卡

常见网卡:

  • 有线网卡(Ethernet)
  • 无线网卡(Wi-Fi)
  • VPN 虚拟网卡(如 tun、utun、vEthernet)
  • 回环网卡(Loopback,抓本机 localhost 通信)

原则:流量走哪张卡,就抓哪张卡。不确定时可以同时观察网卡流量曲线,找到有波动的那一张。

2.2 抓包过滤器 vs 显示过滤器

很多新手的第一个坑是混用两类过滤器。

  • Capture Filter(抓包过滤器):在抓包前设置,减少采集量
  • Display Filter(显示过滤器):抓完再筛选,最常用

示例:

1
2
# 抓包过滤器(BPF 语法)
host 10.0.0.8 and tcp port 443
# 显示过滤器(Wireshark 语法)
ip.addr == 10.0.0.8 && tcp.port == 443

2.3 养成“带时间点抓包”的习惯

排障时请记录:

  • 出问题的精确时间(到秒)
  • 操作动作(点击登录、发请求、刷新页面)
  • 客户端 IP、服务端 IP、端口、域名

后面做时间线对齐会非常省命。


三、场景一:连不上(Connection failed / timeout)

这一类问题最适合用“分层排除法”:

  1. DNS 是否成功
  2. TCP 是否握手成功
  3. TLS 是否握手成功
  4. 应用层是否返回错误

3.1 先看 DNS:域名解析是否有结果

高频过滤器:

dns && (dns.qry.name contains "example.com" || dns.resp.name contains "example.com")

你要关注:

  • 是否有查询包发出
  • 是否有响应包返回
  • 响应码是否 NoError
  • 是否返回了错误 IP(例如内网 DNS 污染、解析到过期地址)

典型现象:

  • 只有查询无响应:DNS 服务器不可达、防火墙拦截、上游超时
  • 响应 NXDomain:域名不存在或拼写错误
  • 解析结果异常慢:DNS 递归链路慢,后续连接都会慢

3.2 再看 TCP 三次握手

过滤器:

tcp.flags.syn == 1 || tcp.flags.reset == 1

正常握手:

  • 客户端 SYN
  • 服务端 SYN, ACK
  • 客户端 ACK

异常模式速查:

  • 只有 SYN 重传,没有 SYN/ACK
    • 目标不可达
    • 中间设备丢包
    • 服务端端口未开放或被 ACL 丢弃
  • 收到 RST
    • 端口未监听
    • 防火墙主动拒绝
    • 负载均衡后端无可用实例

3.3 如果 TCP 成功,继续看 TLS

过滤器:

tls.handshake || tcp.port == 443

重点看:

  • Client Hello 是否发出
  • Server Hello 是否返回
  • 是否出现 Alert(如 Handshake FailureUnknown CA

常见问题:

  • 证书链不完整
  • SNI 不匹配(多域名场景)
  • 客户端/服务端 TLS 版本不兼容

四、场景二:太慢(页面慢、接口慢、下载慢)

“慢”不是一个问题,而是一组问题。Wireshark 的关键是把“慢”拆成多个阶段。

4.1 用时间线拆分延迟

一次 HTTPS 请求通常可拆为:

  1. DNS 解析
  2. TCP 连接建立
  3. TLS 握手
  4. 请求发送
  5. 服务端处理
  6. 响应传输

你要找的是:哪一段突然变长

实战建议:在包列表中右键关键包,使用 Set/Unset Time Reference 设参考时间,再观察后续包的时间差。

4.2 看 TCP 重传与乱序

过滤器:

tcp.analysis.retransmission || tcp.analysis.fast_retransmission || tcp.analysis.out_of_order

当你看到大量重传时,一般意味着:

  • 链路丢包(Wi-Fi 干扰、弱网、拥塞)
  • MTU 不匹配导致分片/黑洞
  • 中间设备(防火墙/NAT)状态异常

重传会直接拉高 RTT 和整体吞吐,表现为“偶发卡顿、下载忽快忽慢”。

4.3 看窗口与吞吐受限

过滤器:

tcp.window_size_value || tcp.analysis.zero_window

关键指标:

  • Zero Window:接收端来不及读数据,窗口归零
  • Window Full:发送端受窗口限制
  • ACK 间隔变大:接收端处理慢或系统繁忙

这类问题往往不是“网络线差”,而是接收端应用处理不过来

4.4 用统计视图做“全局体检”

菜单建议:

  • Statistics -> Conversations:看主要会话、流量分布
  • Statistics -> Endpoints:看谁在发、谁在收
  • Statistics -> Protocol Hierarchy:看协议占比
  • Statistics -> I/O Graphs:看吞吐、包速率、突发抖动

如果你只盯一个请求,容易误判;加上全局统计,才能看出是局部问题还是整体拥塞。


五、场景三:时好时坏(间歇性失败)

间歇性问题最难,因为你抓到时它可能“刚好正常”。建议:

5.1 长时间环形抓包

  • 开启 ring buffer(分文件轮转)
  • 每个文件例如 100MB,保留最近 N 个
  • 出现问题后立即停止抓包并标记时间

这样不会把磁盘打满,也能保留“事故现场前后文”。

5.2 对齐应用日志与抓包时间

把应用日志里的 request-id、错误码、时间戳与 Wireshark 时间线对齐,常能快速定位:

  • 某一跳偶发超时
  • 某 DNS 服务器抖动
  • 某后端节点频繁 RST

5.3 识别“重试掩盖故障”

很多系统有自动重试,表面看成功率高,但首包失败率可能很高。抓包可以看到:

  • 第 1 次连接超时
  • 第 2 次重试成功
  • 用户体感仍然慢

这类问题不看抓包很容易被平均指标掩盖。


六、给新手的一套万能过滤器清单

# DNS
dns

# TCP 三次握手相关
tcp.flags.syn == 1 || tcp.flags.reset == 1

# 重传/乱序
tcp.analysis.retransmission || tcp.analysis.fast_retransmission || tcp.analysis.out_of_order

# RTT 异常(需要已建立会话)
tcp.analysis.ack_rtt

# HTTP/HTTPS(HTTPS 主要看 TCP/TLS 元数据)
http || tls || tcp.port == 443

# 只看某个主机
ip.addr == 10.10.10.20

# 只看某个会话五元组(示例)
ip.src == 10.10.10.5 && ip.dst == 10.10.10.20 && tcp.srcport == 51532 && tcp.dstport == 443

七、一个可复用的排障流程(建议收藏)

  1. 明确症状:连不上 / 慢 / 间歇性
  2. 锁定范围:客户端、服务端、中间网络
  3. 按层检查:DNS → TCP → TLS → 应用层
  4. 先看时间线:问题发生前后 5~30 秒
  5. 再看统计视图:确认是否全局异常
  6. 提取证据:关键包编号、时间戳、五元组
  7. 形成结论:现象 + 证据 + 推断 + 下一步验证

输出结论时尽量用工程化表达,例如:

  • “10:21:33~10:21:41 客户端对 10.0.12.8:443 连续 6 次 SYN 重传,无 SYN/ACK,判定连接建立失败发生在 TCP 层,优先排查目标安全组与四层负载均衡健康状态。”

八、常见误区

  • 误区 1:只抓客户端,不抓服务端
    • 正解:双端对抓可快速判断丢包发生在哪一侧
  • 误区 2:看到重传就认定“网络差”
    • 正解:应用阻塞、窗口限制也会触发类似现象
  • 误区 3:只看单个失败请求
    • 正解:必须看同时间段正常请求做对照
  • 误区 4:抓包文件太大,事后无法分析
    • 正解:前置过滤 + 环形抓包 + 标记时间点

九、写在最后

Wireshark 最难的不是工具本身,而是排障思维。建议你从今天开始建立一个习惯:

  • 发生问题时,先画出链路(客户端 → DNS → 网关/防火墙 → LB → 服务)
  • 再用抓包逐层验证,而不是直接猜

当你能稳定回答“包发出去了吗?回来了没有?在哪一层断的?”时,网络问题基本就不再玄学。

如果你愿意,我下一篇可以继续写:

  • 如何用 tshark 做命令行自动化排障(适合服务器无图形界面场景)
  • 如何结合 mtr / ss / netstat / tcpdump 做 Linux 端到端网络诊断
本文由作者按照 CC BY 4.0 进行授权