跳到正文

网络故障定位

环境:Windows 11 x64。本机网络的特殊性必须先声明:所有域名解析到 198.18.0.0/15(RFC 2544 基准测试段),tracert 显示一跳、ping 零延迟,应用层还有 127.0.0.1:1334 的本地代理——这是一个被完整接管的实验网络,公网路径级实测在本机不可信。本文因此把重点放在方法论:延迟怎么分解、重传怎么看、MTU 怎么测、以及怎么识别”你的测量被拦截了”(第一节就是活例)。协议层实测(TCP 行为、抓包)引用本站 net-socket / net-tcp 两节的本机测量。

一、第一课:识别你的测量对象是不是公网

排障前先确认”我在测什么”。本机的三个信号,全部指向”流量被本地接管”:

ping wty.blogs.abrdns.com → 来自 198.18.0.239 的回复: 时间<1ms TTL=128
tracert → 1 跳 198.18.0.239,跟踪完成
nslookup → 服务器 fdfe:dcba:9876::2,No response from server

判据(按可疑程度排序):

  1. 解析到保留段地址:198.18.0.0/15(网络设备基准测试)、192.0.2.0/24(TEST-NET-1)、203.0.113.0/24、fc00::/7——公网服务绝不该解析到这里。看到就是拦截器/抓包工具/沙箱在代答。
  2. tracert 一跳可达:公网任何地址至少几跳;一跳说明第一跳设备就是”终点”(本地代答)。
  3. ping 零延迟、TTL=128:TTL 128 是 Windows 默认初始值——回应来自同网段的 Windows 机器(或本机拦截器),不是远端服务器。
  4. 应用层计时和 ping 矛盾:curl total 270ms 但 ping <1ms——至少有一个在骗你(这里是 ping,它量的只是到拦截器)。

结论先于测量:在这个环境里,任何”到 GitHub 的 RTT”都是到拦截器的 RTT。正确的排障输出是”本机到 X 的路径被 Y 接管”,而不是一个假的毫秒数。这套判据在真实排障里同样有用——公司代理、抓包工具、安全网关都会制造同类假象。

二、延迟分解:把一次请求拆成四段

任何”网站慢”的定位都从分解开始(net-dns-http 那节用 curl -w 实测过分解输出):

DNS ──▶ TCP 连接 ──▶ TLS 握手 ──▶ 首字节(TTFB) ──▶ 内容下载
段慢病在哪验证方法
DNS解析器慢/黑洞/劫持换解析器对比(nslookup 指定不同 DNS)、看是否解析到保留段
TCP路径远/丢包/限速ping 的 RTT 和稳定性、tracert 看跳数、pathping 看逐跳丢包
TLS握手 RTT×2 + 证书链大小 + 服务端性能openssl s_client -trace 看握手的消息往返;对比恢复会话(net-tls 实测 Reused)
TTFB服务端生成慢/排队/反向代理链curl 对比静态资源与动态接口;换时段重测
下载带宽/拥塞/服务端限速curl 的 speed_download,多线程对比

实践顺序:先换一个已知快的静态资源(如一个 CDN 上的小文件)当基线——基线也慢,病在你这一侧(本机、代理、线路);基线快而目标慢,病在目标或路径。没有基区的毫秒数没有诊断价值。

三、重传、丢包与 RTO 的观测

丢包的三个观测层:

  1. 应用层:ping -n 100 看丢包率(本机 ping 到拦截器恒 0%,无诊断意义——见第一节);curl 的 total 波动(重传会让 total 从 60ms 跳到 200ms+)。
  2. TCP 层:netstat -s(Windows)或 ss -i(Linux)看 Segments Retransmitted 计数——重传率 = 增量/时间,健康值 < 0.1%。net-tcp-flow 那节实测过本机窗口调谐和零窗探测的行为,可对照。
  3. 抓包层:Wireshark 过滤 tcp.analysis.retransmission 直接看重传了哪些包;expert info 会把重传、重复 ACK、零窗标出来。net-layer 那节讲过抓包入口。

RTO 的指数退避:Linux 默认首次 RTO 1s,翻倍到 3 次后封顶(net-tcp-flow 实测过零窗后 315/605/1211ms 的探测节拍)。所以”偶发几百毫秒的卡顿”经常是一次丢包 + 一次 200ms–1s 的 RTO,不是带宽问题——这类病在抓包里一眼可见(重传包间隔翻倍),在应用层只能看到”总时间变成两截”。

四、MTU 黑洞:能 ping 通但传不动

MTU 黑洞的经典症状:小包(ping 默认 32 字节载荷)通,大包(HTTPS 握手、文件下载)卡住或超时。成因:路径上某设备的 MTU 小于源主机,且它不回 ICMP “需要拆分但 DF 置位”(net-ethernet 实测过 9000 MTU 链路上 8972/8973 的边界)。

检测方法(分层):

  1. ping -f -l <size>(Windows,-f 置 DF 位)从 1472 字节(以太网标准)往下试:通 → 逐步加大找上限;返回”需要拆分数据包但是设置 DF”的那个尺寸就是路径 MTU。
  2. 对比大小请求:curl 下一个小文件(1KB)和一个大文件(1MB)——小时通大时卡,就是 MTU/分片问题。
  3. 抓包看 ICMP:黑洞设备吞掉的是 ICMP 差错,正常设备会回 Fragmentation Needed。Wireshark 过滤 icmp.type == 3 && icmp.code == 4。

修法:源主机clamp MSS(TCPMSS/route ... advmss)或修正 VPN/隧道的 MTU(PPPoE 1492、WireGuard 1420 一类的固定值)。症状是”部分网站打不开、部分正常”时先查这个——不同路径 MTU 不同,只有特定链路中招。

五、代理链路:本机活例的排查法

本机代理链(net-dns-http 第一节量过):应用 → 127.0.0.1:1334 代理 → 拦截器 → 目标。排查代理问题的抓手:

  1. 分清谁在做 DNS: proxied 环境里 time_namelookup 只解析代理地址(本机实测 0.05ms 假象),真实解析在代理侧——应用层看不到的解析失败,症状是”所有域名都连不上但代理地址能 ping 通”。
  2. curl -v 看 CONNECT: proxied HTTPS 的第一跳是 CONNECT host:443,代理回 200 Connection Established 才是真 TLS 开始。卡在 CONNECT = 代理侧问题;CONNECT 成功后卡 = 目标侧问题。这一行是代理链路的天然分界线。
  3. 绕过对比:curl --noproxy '*'(本机实测能通但走拦截器)——同参数两路径对比,差异全在代理上。
  4. 代理协议细节:HTTP 代理走 CONNECT 隧道时,目标主机名对代理明文可见(SNI 之前的信息);SOCKS5 亦然。要隐藏目标域名只有 DoH + ECH 一整套,不是单点能解决的(net-tls 提过 ECH 未实测)。

六、跨网段与杂项

  • 防火墙 vs 丢包:防火墙丢包通常 RST 或静默丢(表现为超时),网络拥塞是随机丢。抓包看回的是 RST 还是什么都没有——RST = 有人故意拒绝,沉默 = 路径问题。
  • NAT 端口耗尽:高并发短连接场景,NAT 表项爆了的症状是”新建连接随机失败、 established 的正常”。netstat -n | findstr ESTABLISHED 看出口连接数分布;修法是开连接池/keep-alive(net-dns-http 第二节实测收益)。
  • IPv6 半开:系统优先走 IPv6 但路由器不转发时,症状是”浏览器转圈几秒后突然打开”——先试 IPv4(curl -4)验证,长期修法是关掉半死的 IPv6 或修好路由广告。

七、未实测清单

  • 本机公网路径(tracert 一跳、ping 零延迟全是拦截器假象)——见第一节,路径级数据不可信。
  • Wireshark 抓包细节(net-layer 那节有 Npcap 侧实测)——本文未新抓。
  • 跨运营商/跨境链路对比——被沙箱接管,未测。
  • iperf/netperf 带宽测试——未部署。
  • net-highperf 那节的 epoll 服务器——无 Linux 环境,未测。