网络故障定位
环境: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
判据(按可疑程度排序):
- 解析到保留段地址:
198.18.0.0/15(网络设备基准测试)、192.0.2.0/24(TEST-NET-1)、203.0.113.0/24、fc00::/7——公网服务绝不该解析到这里。看到就是拦截器/抓包工具/沙箱在代答。 - tracert 一跳可达:公网任何地址至少几跳;一跳说明第一跳设备就是”终点”(本地代答)。
- ping 零延迟、TTL=128:TTL 128 是 Windows 默认初始值——回应来自同网段的 Windows 机器(或本机拦截器),不是远端服务器。
- 应用层计时和 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 的观测
丢包的三个观测层:
- 应用层:
ping -n 100看丢包率(本机 ping 到拦截器恒 0%,无诊断意义——见第一节);curl的 total 波动(重传会让 total 从 60ms 跳到 200ms+)。 - TCP 层:
netstat -s(Windows)或ss -i(Linux)看Segments Retransmitted计数——重传率 = 增量/时间,健康值 < 0.1%。net-tcp-flow 那节实测过本机窗口调谐和零窗探测的行为,可对照。 - 抓包层: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 的边界)。
检测方法(分层):
ping -f -l <size>(Windows,-f置 DF 位)从 1472 字节(以太网标准)往下试:通 → 逐步加大找上限;返回”需要拆分数据包但是设置 DF”的那个尺寸就是路径 MTU。- 对比大小请求:
curl下一个小文件(1KB)和一个大文件(1MB)——小时通大时卡,就是 MTU/分片问题。 - 抓包看 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 代理 → 拦截器 → 目标。排查代理问题的抓手:
- 分清谁在做 DNS: proxied 环境里
time_namelookup只解析代理地址(本机实测 0.05ms 假象),真实解析在代理侧——应用层看不到的解析失败,症状是”所有域名都连不上但代理地址能 ping 通”。 curl -v看 CONNECT: proxied HTTPS 的第一跳是CONNECT host:443,代理回200 Connection Established才是真 TLS 开始。卡在 CONNECT = 代理侧问题;CONNECT 成功后卡 = 目标侧问题。这一行是代理链路的天然分界线。- 绕过对比:
curl --noproxy '*'(本机实测能通但走拦截器)——同参数两路径对比,差异全在代理上。 - 代理协议细节: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 环境,未测。