1 网络排障要遵循什么证据链
终端里出现“连接超时”,只是使用者看到的结果。它没有说明故障发生在域名解析、主机选路、远端监听,还是响应返回途中。网络排障的目标,是把这个模糊结果变成可以检查的事实:哪个进程,在什么时间,从哪个地址,经哪个接口,访问哪个目标,在哪个阶段没有得到预期结果。只写“网络不通”,下一位值班人员几乎无法接着查。
可以把证据链写成“现象→假设→观测→对照→结论”。现象应包含范围,例如“主机 A 上的普通用户执行 HTTPS 请求,连接阶段超过 3 秒;同机访问另一个地址正常”。假设应能被推翻,例如“目的地址对应的路由不正确”。观测必须能区分这个假设与其他解释,例如检查实际选用的下一跳和出口。对照则改变 1 个条件,让结果的差异有解释力。结论要写清适用范围,不能从 1 次成功推出整个网络健康。
开始前先保存时间与上下文。使用 date -Is 记录带时区的时间,用 hostname 标识主机,并记下执行命令的用户、所在网络环境、目标域名与端口。若命令在容器内执行,就注明容器环境;宿主机成功不代表容器也成功。若应用由服务管理器启动,交互式 shell 中的代理变量、权限和工作目录可能与它不同。排查对象是实际失败的进程环境,而不只是眼前这个终端。
随后区分“事实”和“解释”。“curl 返回退出码 28”是事实,“链路丢包”是解释;“发起连接的报文重复出现,未见返回”是更具体的观测,仍不足以确定丢弃位置。返回报文可能走了其他接口,也可能被采集过滤条件排除。每增加 1 项证据,都应说明它排除了什么,又留下什么,而不是让工具输出替判断。

证据还需要和操作关联。修改前保存相关状态,修改时记下时间,修改后重复同样的探测。故障偶然恢复时,这些记录能够帮助判断恢复与操作是否相关。若缺少修改前的基线,即使服务恢复,也只能说“操作后恢复”,不能说“已证明该参数是根因”。这样的克制能避免把偶然结果固化成长期配置。
2 分层定位与对照实验
分层定位是一种缩小问题范围的方法,不要求背诵完整的层次表。实际可以依次询问:名称能否得到预期地址,主机是否选择了正确路径,目标端口是否接受连接,应用是否给出预期响应。每个问题都有不同的观测方式。名称解析成功,只能证明取得了地址;TCP 建立成功,也不能证明服务能读取文件、访问依赖并完成请求。
先用 getent ahosts example.com 查看当前主机通过系统名称解析机制得到的地址。它比随手查询某个公共解析器更接近许多普通应用的行为,但应用仍可能使用自己的缓存或解析方式。记录 IPv4 与 IPv6 的差别很有帮助:同一个名字可能对应多个地址,应用实际选中的地址才是后续排查对象。连续执行得到不同地址,也不一定是异常,需要与服务的地址分配方式对应。
接着用 ip -br addr 查看接口地址,用 ip route get 192.0.2.20 查看内核为这个目的地址选择的路径。这里的示例地址需要换成真实目标。关注输出中的 dev、via 与 src,分别对应出口接口、下一跳与源地址。它们说明本机打算怎样发送,不能保证沿途设备会转发,也不能保证远端能够把响应送回来。多网卡主机上,源地址错误常比“没有默认路由”更隐蔽。
端口与应用阶段可以借助 curl -v --connect-timeout 3 --max-time 8 https://example.com/ 区分。连接超时限制建立连接的等待,总时间限制约束整次操作;详细输出中还要辨认名称解析、连接、TLS 与响应的阶段。若 TLS 校验失败,已有证据说明连接走到了证书校验阶段,应检查主机时间、证书与访问名称,而不是直接认定没有网络。不要用关闭校验来掩盖这个差异。
对照实验要控制变量。比较同机不同目标,有助于判断故障是否只涉及某条路径;比较不同主机访问同一目标,有助于区分源端环境;比较同机 IPv4 与 IPv6,可以识别地址族差异。每次只改变 1 个主要条件,同时保留目标端口、测试时间与超时设置。若同时换主机、换域名、换协议,得到的成功结果几乎无法解释原故障。

需要固定地址又保留 HTTPS 名称时,可以用 curl --resolve example.com:443:192.0.2.20 https://example.com/。它让本次测试把该名称连接到指定地址,同时保留 URL 中的名称用于 TLS 和 HTTP。直接把 URL 改成 IP 可能引入证书名称或虚拟主机差异,形成新的失败原因。这个实验只能检验指定地址上的行为,不能代替对真实解析结果和其他地址的检查。
3 抓包、计数器与路径追踪
抓包、计数器和路径追踪分别回答不同问题。抓包展示某个观测点看到的报文;计数器展示某段时间累计发生的事件;路径追踪展示探测报文获得回应的位置。它们可以互相补充,却不能直接相互替代。接口错误计数增加,不代表每次应用超时都由它造成;抓包没有看到报文,也可能是抓错接口、方向或过滤条件。
先读低成本状态。ip -s link show dev eth0 可查看接口的收发与错误统计,接口名应替换为实际出口。保存测试前后的值,计算增量,再与探测时间对应。自系统启动以来累计的 20 次丢弃,不能证明当前这 10 秒发生丢包。计数器含义还可能随接口类型与系统实现变化,因此它适合提示调查方向,不能单凭某个字段定位到具体远端。
用 ss -lnt 检查 TCP 监听地址和端口,用 ss -nt 检查当前连接状态。若服务只监听 127.0.0.1:8080,其他主机无法直接连接这个监听点,修改网络路径不会让它自动开放。进一步查看进程信息通常需要合适权限。连接长期停在建立过程,和连接已经建立却迟迟没有应用响应,应当进入不同的排查分支。状态是某个时刻的快照,也可能错过很短的连接。
抓包要明确接口、目标和时间窗口。例如在获准的环境执行 sudo tcpdump -ni eth0 -c 40 'host 192.0.2.20 and tcp port 443',可以观察有限数量的相关报文。-n 避免名称转换干扰阅读,-i 指定观测位置,-c 限制报文数量,但流量不足时不会自动按时间结束。需要按时间限制时,可结合系统已有的 timeout 命令;保存文件则使用 -w,之后用 tcpdump -nn -r 阅读。

tracepath 或 traceroute 可以辅助观察路径和可能的 MTU 线索,但中间节点可能不回答探测,也可能限制回答频率。某一跳显示星号,只能说明该探测没有按预期收到回答;如果后续节点和最终目标仍回应,就不能把该跳认作丢弃业务流量的位置。探测协议、端口与业务不同,也可能选择不同路径。路径追踪应作为旁证,并与真实业务连接对照。
双端抓包能进一步缩小范围:源端看到发出,目标端未看到到达,问题范围落在这 2 个观测点之间;目标端收到并发回,源端未收到返回,重点转向回程或源端入口。即使如此,也不能直接点名某台中间设备。还要确认时钟、过滤条件、抓包丢弃统计与实际接口,并说明观测点之间还包含哪些无法直接看到的环节。
4 动手:复现并固定一次丢包证据
这个实验使用独立的 Linux 网络命名空间,把故障限制在临时环境。需要 ip、ping、tc、tcpdump 以及管理员权限,部分精简系统没有预装全部工具。只在可操作这些资源的实验机执行;如果工具缺失,先使用管理员提供的实验环境。目标是保留“正常→注入丢包→恢复”的证据,不是在生产接口上尝试网络损伤。
先确认下面的命名空间名称未被使用。通过 ip netns list 查看已有名称,若有冲突就统一替换命令中的名称。创建 2 个命名空间和 1 对虚拟接口,再把两端分别放进去。实验地址只属于这条隔离链路,不添加默认路由,也不承担外部访问。
sudo ip netns add s50a
sudo ip netns add s50b
sudo ip link add s50va type veth peer name s50vb
sudo ip link set s50va netns s50a
sudo ip link set s50vb netns s50b
sudo ip -n s50a addr add 192.0.2.1/30 dev s50va
sudo ip -n s50b addr add 192.0.2.2/30 dev s50vb
sudo ip -n s50a link set lo up
sudo ip -n s50b link set lo up
sudo ip -n s50a link set s50va up
sudo ip -n s50b link set s50vb up
在普通用户的工作目录创建 s50-evidence 目录,用 date -Is 保存开始时间。先执行 sudo ip netns exec s50a ping -n -c 20 -i 0.2 -W 1 192.0.2.2,把输出保存为 baseline.txt。基线应该能收到回应;若基线已经失败,停止注入,先检查命名空间、地址和接口状态。否则后来观察到的超时无法归因于新增的丢包设置。
接着在另一个终端启动有限时间的目标端抓包:sudo timeout 15 ip netns exec s50b tcpdump -ni s50vb -U -w /tmp/s50-b.pcap icmp。文件名应选用本次实验专属且不存在的路径。抓包启动后,在源端添加 sudo ip netns exec s50a tc qdisc add dev s50va root netem loss 25%,再运行同样的 20 次探测并保存为 loss.txt。若添加命令失败,不要把后续结果标为“已注入”。
这里的 25% 是源端该接口出方向的随机丢弃设置,不是每组 20 次必定丢 5 次,也不是整条链路所有方向的综合指标。目标端抓包可能看到部分序号缺失;源端输出则显示部分请求没有收到回应。为了把两项观测关联起来,还要保存 sudo ip netns exec s50a tc -s qdisc show dev s50va 的结果,证明注入配置存在,并观察其统计。不同观测位置可能看到不同数量,不能未经核对就把差值都解释成链路损失。
最后删除本次规则:sudo ip netns exec s50a tc qdisc del dev s50va root,再次执行相同探测并保存为 recovered.txt。让抓包进程结束后,用 sudo tcpdump -nn -r /tmp/s50-b.pcap 阅读报文,并将文件按本地权限规则归档。完成后删除 s50a、s50b 这 2 个实验命名空间;与它们关联的虚拟接口会随之清理。仅删除自己本次创建的资源,若中途失败,也应根据实际创建结果完成清理。
实验结论应写成:“在隔离环境的源端出口配置随机丢弃后,有限探测出现未响应,目标端观测与注入统计提供旁证,撤销后同样探测恢复。”它证明了这个实验中操作与现象的联系,却没有证明生产中的每次超时都是随机丢包。保留命令、时间、原始输出和抓包,才算固定了可复查的证据。
5 速度与完整性取舍
值班时不能无限等待,也不能为了快而把关键证据全部覆盖。较好的做法是先用少量、有时限的探测划定范围,再针对异常补充证据。最初 2 分钟可以用于确认影响对象、记录时间、观察解析与路由、尝试 1 次受限请求;如果已经有持续业务故障,就同步准备恢复动作。完整调查可以继续,但恢复与取证要共享同一条时间线。
采样次数直接影响结论的稳定程度。假设每次探测独立、丢失概率固定为 10%,连续 5 次全部成功的概率仍约为 59%。因此“5 次都通”不能排除这种间歇性问题。增加次数有助于观察,但需要更长时间,也可能增加负载。真实故障常成批发生,独立性假设不成立,所以这个计算只能解释采样风险,不能作为生产链路的保证。
超时也会改变观察结果。超时设得过短,正常但偏慢的响应会被归入失败;设得过长,排查节奏与故障恢复又会被拖慢。报告中必须带上超时、间隔、样本数和协议,否则不同人的“丢包率”可能根本不是同一个指标。ICMP 回应比例和 HTTPS 请求成功率应分开记录,不能因为前者正常就宣告后者没有问题。
抓包的完整性还受保存范围限制。较长时间、较宽过滤条件可以留下更多上下文,却消耗磁盘并收集更多业务信息;较窄过滤条件降低成本,也可能漏掉名称解析或另一条连接。开始前明确调查问题,选择足够的接口与过滤范围,限制持续时间或文件大小。保存目录应有足够空间与合适权限,分享前按规定处理地址、名称和载荷中的敏感信息。
恢复动作与证据采集可以形成短检查点:先保存必要状态和 1 段异常样本,再执行已知回退,随后重复同样的探测。如果系统持续受影响,不应为了追求完美样本无限延迟恢复。反过来,也不能把“恢复优先”理解为随意重启。能在几10秒内完成且不会扩大影响的证据,应尽量先保留下来,并记录还有哪些假设没有验证。
6 常见坑:先改配置再补证据
最常见的错误,是看到超时就依次修改解析、路由、防火墙和服务配置,最后再运行测试。即使恢复,也不知道哪个改动有效;如果更差,则不知道该回退哪项。每次操作前写出预期:“若出口选错,修改后 ip route get 应显示指定接口,连接应恢复。”修改后同时检查中间状态和最终结果,才有机会辨别改动是否按预期生效。
另一个坑是把 ping 当作统一的健康证明。有些目标不回应 ICMP,但 TCP 服务正常;也有目标能够回答 ICMP,业务进程却已经退出。应使用与故障尽量接近的目标、端口和协议,再用其他探测辅助划界。看到 HTTP 503,说明已经获得应用层回应,应继续查看服务及依赖;它与连接阶段完全超时的证据含义不同。
代理和执行环境也容易制造错觉。shell 中的 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY 或 NO_PROXY 会影响部分工具的访问路径,后台服务未必继承同样的值。检查时只记录必要信息,避免把包含凭据的变量直接粘贴到共享记录。还要确认实际调用的程序、配置文件与用户身份;同名命令、不同运行环境,可能测量的是不同路径。

不要看到接口累计丢弃就立即调整队列,也不要看到某次路径追踪星号就修改路由。先核对时间相关性、采样位置和业务对应关系。抓包时如果使用 any,输出可能涉及多个接口与方向;如果选用具体接口,则要确认返回确实会经过那里。多接口与非对称路径使“没有看到”尤其需要谨慎表达。工具自己的丢包提示也应一并保存。
最后,命令执行成功不代表目标状态已经正确。路由命令可能作用于错误的网络环境,配置文件可能没有被运行进程加载,服务重载也可能失败。每次改动都要有读取状态的检查和实际访问的检查。回退步骤应在修改前准备,包含原值、作用范围和验证方式。排障手册若只写“重启试试”,就把最有价值的定位信息留给了运气。
7 案例:单向路由导致假活
某台 Linux 文件服务主机新增了维护接口。业务客户端访问 TCP 8080 超时,但监控仍显示主机存活,值班人员在服务器上访问 127.0.0.1:8080 也成功。这里的“假活”是健康检查范围小于真实访问路径:本地服务能响应,只说明进程在本机可用;监控能触达某个接口,也不代表业务客户端的往返路径完整。
先固定故障对象:客户端地址为 192.0.2.10,服务器业务地址为 198.51.100.20,维护接口地址为 203.0.113.20。这些是用于说明的文档地址。客户端访问业务地址的 8080 端口,连接阶段超时。服务器的 ss -lnt 显示服务监听 0.0.0.0:8080,本地请求成功;这些证据缩小了监听配置问题的可能性,却仍不能证明远端连接能够建立。
客户端抓包看到连接请求重复发出。服务器业务接口抓包看到对应请求到达,说明去程至少到达了这个观测点;随后在维护接口观察到发向客户端的连接应答。客户端未收到这些应答。值班人员再执行面向该客户端的路由查询,发现返回路径选择维护接口,下一跳属于维护网络,而维护网络没有到业务客户端的可用路径。
根因并不是“去程通、网络就应该通”这一推断中的某种例外,而是连接本来就需要双向通信。服务器的回程选择与客户端去程可以不同;不同不必然有错,但每条路径都必须可达且符合策略。本例中,新增接口时加入的较具体路由覆盖了原先可用的选择,使服务器把应答送往错误下一跳。只有把路由状态和双端观测对齐,才能把怀疑收敛到这项配置。
恢复时先保存新增路由和相关配置,按既定回退移除错误条目,再查询同一客户端目的地址的选路。随后从原客户端重复同样的请求,确认连接建立并取得预期响应;服务器的返回报文也重新出现在业务接口。继续观察已有失败连接和新增连接的差别,避免把旧连接状态与新路径混为一谈。需要持久化的配置还应按系统管理方式修正,防止重启后故障复现。
复盘记录应同时写下误导因素:本地访问绕过了外部路径,原监控使用另一条路径,单端抓包只展示了部分过程。新增监控应覆盖代表性的客户端到业务端口,但仍要声明覆盖边界。至于复杂的多出口策略和路由协议,本课只保留“检查实际源地址、出口与回程”的方法,不继续展开其内部机制。
8 把排障手册写进值班方案
值班手册的入口应是可观察的现象,例如“域名解析失败”“连接建立超时”“连接成功但响应超时”。不要用尚未证明的根因作入口,例如“交换设备坏了”。每个入口配少量命令、预期输出、异常分支与停止条件,让接班者知道下一步为什么这样做。命令中的接口和地址必须来自当前环境,不能机械复制示例值。
手册先列明观测位置:客户端、服务主机、容器或其他隔离环境;再列明权限和工具要求。普通用户可以先运行受限请求、查看路由和公开状态;涉及抓包或配置变更时,使用组织规定的权限流程。若无法获得远端观测,就把证据缺口写清楚,并提交最小可复查材料,而不是用单端推测替代远端事实。
每条命令还要有资源边界。请求应设置连接与总超时,重复探测应限制次数,抓包应限制时间、大小或报文数量。记录保存在哪里、如何命名、保留多久、谁可以访问,也属于操作步骤。文件系统空间不足会让抓包中断,输出重定向失败会让记录缺失,因此执行后应确认命令退出状态和材料是否生成。
升级协作时,交付内容至少包括时间与时区、源和目标、协议与端口、影响范围、最近改动、复现命令、原始结果、已排除项以及待验证假设。向网络维护人员提出“请核对该时间段这 2 个观测点之间的去程和回程”,比“请查网络”更容易推进。若同时有人修改配置,应通过共享时间线协调,避免实验条件被无意改变。
最后为恢复动作设验证门槛:原始失败场景恢复、关键对照没有出现新故障、相关配置与持久化状态一致。保留回退和后续观察安排,并让手册记录这次新增的判断分支。手册的价值不在命令数量,而在于遇到同类症状时,能够用更少的试错得到更可靠的结论。
9 从网络排障走向一致性与共识(S51)
本课反复出现的边界是:没有收到响应,不等于对方没有执行。假设客户端向远端进程发送“写入文件”的请求后超时,可能是请求没有到达,也可能是远端已经写入,只是返回丢失。单看客户端超时无法区分这些状态。即使随后网络恢复,之前的操作是否完成仍然需要额外证据。
这会影响重试。重复读取通常比较容易理解,重复执行“追加 1 行”却可能产生 2 行。网络排障能够告诉我们连接在哪个阶段异常、哪些报文被观察到,却不能自动回答业务状态是否已经改变。应用需要提供可查询的操作标识、结果或其他确认方式,让通信失败后的状态能够继续核对。具体设计留待后续学习。
当多个进程分别保存状态时,观察角度还会继续增加。A 看到 B 没有回应,既可能是 B 停止运行,也可能只是 A 到 B 的路径受阻;B 可能仍在与 C 通信。把本地超时直接解释成“对方已经退出”,会让系统基于不充分证据作决定。本课的双向路径案例,正好说明局部观察与整体状态之间存在距离。
S51 将在这个基础上讨论一致性与共识:多个参与者如何对状态和决定形成可解释的约定,以及通信延迟、丢失和进程故障会带来哪些限制。进入下一课前,先记住排障结论的边界。证据链可以说明哪里观察到什么、哪些假设得到支持;对于尚未收到确认的远端结果,应保留“不确定”这个状态,而不是急着把它改写成成功或失败。
放进方案里
在值班方案中加入“网络异常证据与恢复”条目,明确负责人、协作对象和适用环境。以真实业务访问作为入口,记录源进程所在主机或容器、目标名称与实际地址、协议、端口、开始时间和时区。影响范围按客户端、地址族和目标分别描述,避免把局部超时写成全网故障。由当班人员维护共享时间线,其他操作人员在变更前登记动作。
预置 1 组低成本检查:系统名称解析、接口地址、目的路由、监听状态和带超时的业务请求。每项附预期结果及下一步分支。需要抓包时,明确两端接口、过滤条件、采集时限、保存路径和权限;记录采集丢弃与文件是否完整。计数器保存前后值,并将差值对应到具体测试窗口。禁止用累计值直接解释当前故障。
恢复动作采用检查点方式:先保留必要状态与异常样本,写出待验证假设,再执行范围明确、能够回退的操作。记录原值、执行时间、结果和回退命令。若业务持续受影响,按预案及时恢复,并注明尚未完成的取证。每次验证重复原来的失败场景,同时运行关键对照,确认没有扩大影响;临时配置还须核对持久化安排。
交接材料包含复现命令、原始输出、抓包位置、已排除项和证据缺口。恢复后以原场景成功、相关计数变化合理、观察期内未复发作为关闭依据,并说明观察时长。清理临时探测和实验资源,按保留规则归档材料。复盘把新发现写成可判断的分支,例如“服务器收到请求但应答走维护接口时,检查面向客户端的回程路由”,让下次值班能够直接复用。
10 小结:下一步一致性与共识(S51)
网络排障从准确描述现象开始,经由分层检查、受控对照和多点观测,形成带范围的结论。命令输出是证据材料,时间、接口、方向与执行环境决定了材料能够说明什么。变更前保留基线,变更后重复验证,才有可靠的恢复记录。
自测时可以回答 3 个问题:为什么 ping 成功不能证明 HTTPS 正常?为什么服务器看到请求仍可能无法建立连接?为什么请求超时后不能断言远端没有修改文件?前 2 个问题回到协议和往返路径,第 3 个问题把我们带向 S51 的一致性与共识。