用了几个月甚至几年的服务,突然某天早上怎么点都打不开,这种经历我相信搞技术的人都遇到过。不是密钥失效,不是配置被改,也不是服务商跑路,但就是莫名其妙连不上。很多时候,真正的坑往往藏在最不起眼的地方,比如本地缓存、系统时钟,或者某个早就过期却没人在意的域名解析记录。
这篇文章就从一个典型的“长期稳定运行的服务突然不可用”故障场景出发,记录我完整的一次排查过程。不看任何厂商日志,不用任何花哨工具,就用本机自带命令一步步缩小范围。整个过程适合刚接触网络排查的新手,也适合想梳理一下排障思路的运维朋友。我尽量把每一步为什么这么做、每一条命令怎么看结果,都写得清清楚楚。
1. 故障现场与第一步判断
先说现象。当天早上打开公司内部文档系统,浏览器转圈转了很久,最后直接提示“无法访问此网站”。试了两次都一样。当时我的第一反应不是慌,而是先问自己一个问题:这个服务到底是彻底挂了,还是只有我这边访问不了?这个问题决定了后面完全不同的排查方向。
我顺手做了三个快速验证:
- 用手机开移动数据访问同一个服务域名,结果正常打开。
- 用公司另一台电脑访问,结果也正常。
- 只有我这台电脑不行。
这就很有意思了。服务端大概率没挂,问题出在我这台电脑和这个服务之间的某个环节上。很多人这时候喜欢直接重装软件、重启电脑、或者干脆卸载重装,我建议先别急。重装是最后手段,因为它会把问题吃掉,但不会告诉你问题在哪。下次再出问题,你还是两眼一抹黑。
接下来我做的事情,是把“访问不了”这个模糊的描述,细化成一个可定位的技术现象。我打开浏览器,手动输入服务的完整地址,观察返回内容:
- 是浏览器报错?还是页面返回了503/504?
- 是连接超时?还是被重置?
- 是解析不到域名?还是跳到某个奇怪的错误页?
这些细节看起来琐碎,实际排查时却是最有力的线索。比如“连接被重置”和“连接超时”的成因完全不同:前者通常是中间设备干预,后者通常是路由不可达或服务端无响应。如果连这些信息都不记录,后面很容易在原地打转。
我在纸上写下了几个关键词:解析结果、连通性、路由路径。然后开始按从下往上的顺序逐层排查。
2. 从终端开始逐层排查
2.1 先确认本机网络出口是好的
排障最忌讳上来就盯着目标服务看。第一步应该是确认你本机到互联网的链路是不是通的。如果连外网都没通,后面查什么都白搭。
我在终端里执行了两个命令:
ping 127.0.0.1这个命令检查本机协议栈基本没问题。通的话,说明网卡和TCP/IP协议栈至少还在正常工作。然后我再ping网关:
ping 192.168.1.1这是局域网内最基础的一条链路。如果网关都不通,问题基本锁定在网卡、网线、Wi-Fi信号或者路由器本身。但这次我本机到网关是通的,延迟1ms,很稳定。
然后ping一个公共地址,比如:
ping 223.5.5.5注意这里我刻意选了一个IP地址而不是域名。原因后面会讲。如果IP能通而域名不通,说明问题出在DNS解析;如果IP也不通,那就是路由出口的问题。这次ping 223.5.5.5是通的,说明我本机到公网出口完全正常。
到这里,可以把范围从“我的电脑坏了”缩小到“我的电脑与目标服务之间的某个环节有问题”。别小看这个判断,它帮你排除掉了网线、网卡、路由器、运营商接入这五层问题,下面只需要盯着和目标服务相关的东西看。
2.2 域名解析:最容易暴雷的环节
既然外网通了,接下来要确认的就是域名解析。很多服务用了好几年突然“不行”,大概率是DNS换了IP、本地DNS缓存陈旧、或者你偶尔手动配过hosts。
我用nslookup查看解析结果:
nslookup docs.example.com返回了一个A记录,但我发现一个问题:解析出来的IP地址,和我记忆中这个服务该有的IP完全不一样。我印象中它一直是10.20.30.40这种内网地址(很多公司内部服务虽然通过公网域名暴露,但解析给的是内网IP),现在解析结果却变成了一个公网IP 183.x.x.x。
这里要补一个常识:DNS解析结果不是一成不变的。公司做网络改造、把服务从机房租到云端、或者换了CDN厂商,都会导致域名解析的IP发生变化。如果本地DNS缓存更新不及时,就会出现“别人家都能访问,就我这不行”的诡异现象。
我在Mac上清一下DNS缓存:
sudo dscacheutil -flushcache sudo killall -HUP mDNSResponderWindows对应的是:
ipconfig /flushdns清完缓存重新nslookup,结果还是那个公网IP。那就说明不是缓存问题,而是域名本来就已经指向新的IP了。这时候我尝试直接ping这个新IP,结果不通。而服务域名在别的电脑上却能正常打开,说明这个新IP对我这边的网络路径是异常的。
到这一步,方向已经完全清晰了:不是DNS出错,而是“我的网络到新IP”这一段路径有问题。
2.3 路由路径:找准断点在哪一跳
接下来用traceroute看路由走向。Mac或Linux用:
traceroute -T -p 443 183.x.x.xWindows用:
tracert 183.x.x.x加-T -p 443是为了直接探测TCP 443端口的连通性,比默认的ICMP更贴近真实访问场景,因为很多节点禁ping。
输出的内容大概是这样:前三跳是本地网关和运营商接入设备,延迟正常;第四跳到某个节点之后,请求全部超时,出现星号。这种情况有两种可能:一是那个节点禁用了探测包,不值得恐慌;二是那一段路由确实断了,需要再确认。
怎么确认?我换了一个端口再探测一次,同时用别的DNS做对比解析,确认我本地的路由表中没有奇怪的静态路由。比如:
route -n get 183.x.x.x这条命令能看到去往那个IP实际的下一跳是什么。结果显示下一跳就是默认网关,没有异常。那就说明不是本机路由表被改过,问题出在本地出口之外的网络路径上。
这个时候我基本可以断定:域名解析出来的新IP,在我当前所处网络的运营商路由里存在异常,或者目标服务做了区域访问限制。我在第1章已经验证过“手机用移动数据能访问”,也就是说换个网络出口就能通,进一步坐实了“本地出口与目标IP之间存在路径问题”这一判断。
3. 服务端状态也不能放过
3.1 先看端口监听与访问策略
虽然基本锁定是网络路径问题,但作为负责任的排查,服务端状态我还是看了一眼。有时候问题不是一个,而是叠加的。
我先检查目标服务在内网测试环境里的监听状态。常用的方式有:
netstat -tlnp | grep 443如果是Windows服务器:
netstat -ano | findstr :443LISTENING状态的监听就是正常的,如果看不到443端口,说明Web服务进程根本没起来,或者被防火墙拦了。但这次服务端没问题,端口正常监听,防火墙也放行了我的来源IP。
3.2 证书过期:最容易忽略的定时炸弹
第二个容易忽略的检查项是TLS证书有效期。很多服务跑着跑着突然浏览器报警,但后台看起来一切正常。我习惯用openssl直接看证书到期时间,根本不用打开浏览器:
openssl s_client -connect docs.example.com:443 -servername docs.example.com </dev/null | openssl x509 -noout -dates这条命令会把服务器返回的证书起始日期和结束日期打出来。如果结束日期已经过去了,那就说明服务端没做证书自动续期,坑了所有访问者。这次我看了,证书还有两百多天,没问题。
不过这里有个细节提醒一下:如果服务端证书是新的,但你本机系统时间不对——比如主板电池没电导致系统时间退回了几年前——那么就算证书本身没过期,浏览器也会当作过期处理。因为TLS证书校验依赖两端时间同步,客户端时间不在证书有效期内,握手就会失败。这个坑我踩过一次,排查了半小时才发现是本地时间错了。
3.3 服务日志里的线索
服务端日志这时反而没有太多参考价值,因为从日志上看,我这边的请求根本没有到达服务端。这就是“路径异常”和“服务故障”最明显的区别:路径异常时,服务端日志里干干净净,什么都没收到。而服务故障时,日志里会有大把的连接尝试、错误堆栈、超时记录。
我翻了翻最近几天的访问日志,发现从我这根运营商线路来的请求全都断在了中间环节,一次都没有进到后端。这也正常,毕竟我已经通过traceroute确认断点在中间链路。
4. 中间链路、本地环境与终端小问题
4.1 路由器与运营商的“隐形故障”
既然问题不在我本机,也不在服务端,那中间链路还有什么值得看的?首先是家里或者办公网络的路由器。老路由长时间通电后,NAT表项可能会变得乱七八糟。我做的第一个操作是把路由器断电重启,等两分钟再通电。这一招能解决六成“昨天好好的今天突然不行”的奇怪问题,因为很多情况下是连接表被占满或者固件内部状态卡死了。
但这次重启路由器后,问题依旧。于是我又试着把路由器WAN侧的MTU从1500改成1400。为什么要看MTU?因为如果链路中某一段的MTU变小,而流量又超过了这个值,就可能导致大包被丢弃,小包却正常。现象就是网页、视频这类大流量请求卡死,而ping这类小包完全正常。虽然最终问题不是出在MTU上,但这种排查细节往往是很多人没试过的方向。
4.2 浏览器插件和系统代理的暗坑
再往上看,本地环境里还有一个经常被忽略的环节:浏览器扩展和系统代理设置。我打开浏览器设置,确认有没有开“自动配置代理”或安装了那种全局接管流量的插件。很多插件会在后台把流量绕路到海外节点或者其他中间服务器,一旦那个中间服务出问题,你会感觉是目标网站挂了,其实是“绕路的车”翻在路上了。
这种干扰特别隐蔽,因为页面加载失败时,浏览器报的错误和真正的网络不通几乎一模一样。我习惯在排查早期就直接关闭所有扩展,用无痕模式打开同一个地址。如果无痕模式下能访问,那基本可以断定是某个扩展干的“好事”。这次测下来,无痕模式同样访问不了,说明也不是扩展的问题。
4.3 公共DNS与本地hosts的排查
还有一个高频雷区是hosts文件和DNS配置。我之前遇到过用户把一条过去的解析记录写死在hosts里,服务端都换过好几轮IP了,他那边每次访问都是找老IP,当然永远失败。我在Mac上查看了本地hosts文件:
cat /etc/hostsWindows就是:
type C:\Windows\System32\drivers\etc\hosts确认没有写死记录。同时我把本机DNS临时切换到公共DNS(比如223.5.5.5和119.29.29.29),再尝试访问。这一步是为了排除“本地DNS服务器返回了过期的解析结果”这个可能。切换后依然访问不了,但解析IP没变,说明目标IP确实就是要访问的那个IP,不是DNS故意使坏。
5. 问题排查速查表
这次排查从开始到定位问题,用了将近四十分钟。整个过程踩了不少容易忽略的细节,我整理成了一张速查表,以后遇到类似场景可以照着过一遍:
| 排查项 | 命令或操作 | 正常表现 | 异常时该怎么办 |
|---|---|---|---|
| 本机协议栈 | ping 127.0.0.1 | 通 | 重启网卡驱动或检查系统网络组件 |
| 局域网链路 | ping 网关IP | 通且延迟低 | 查网线、Wi-Fi信号、路由器 |
| 公网出口 | ping 223.5.5.5 | 通 | 路由器重拨号或联系运营商 |
| DNS解析 | nslookup 域名 | 返回正确IP | 刷新DNS缓存、换公共DNS |
| 路由路径 | traceroute -T -p 443 IP | 最后一跳可达 | 对比不同网络出口定位断点 |
| 端口监听 | netstat -tlnp | grep 443 | LISTENING | 启动服务或改防火墙规则 |
| 证书有效期 | openssl s_client看dates | 未过期 | 续期证书 |
| 本地hosts | cat /etc/hosts | 无异常记录 | 删掉或注释异常行 |
| 浏览器扩展 | 无痕模式访问 | 可访问 | 逐个禁用扩展找问题 |
这张表适合按顺序从第一项执行到最后一项,也可以根据已有信息直接跳转到疑点项。我个人经验是:不要跳过前两步,因为看起来不起眼反而最容易在水落石出前浪费你最多时间。
6. 排障经验与心得
这次故障排查下来,我最大的体会是:排障的思路比工具重要。不急着下结论,不跳过步骤,一层层缩小范围,最后一定能把问题定位到具体的链路上。很多时候我们凭直觉直接猜某个环节出问题,但如果后续验证不足,很容易被表象带偏。
我整理几条实用的心得体会:
- 排查顺序从“自己能控制的范围”开始,再到“自己控制不了的范围”。本机、局域网、出口、DNS、路由、服务端,这个顺序每次都不会错。
- 所有的现象都要记录。几点几分出现、报错内容是什么、当时你对系统做了什么变更——这些记录在排障时都是最珍贵的线索。
- 遇到解析IP变了的情况,先别急着说“DNS出问题了”。解析结果本身没错,错的是缓存、路由或其他环节。多对比几个网络环境就能迅速判断到底是谁的问题。
- 服务端日志没有请求记录,不一定代表没有用户访问失败。很多人只盯服务端日志,却忽略了“请求根本没到服务端”这种情况。
- 长期不重启的路由器确实可能积累问题,但一上来就重启之前,至少先看一眼它的状态页。如果状态页也打不开,再重启不迟。
最后再分享一个小技巧:我习惯在桌面备忘录里维护一份“长期服务清单”,记录每个服务对应的域名、IP归属、端口、证书到期时间、以及上次维护的日期。真出故障时,打开这份清单先对照一遍,经常五分钟内就能排除掉一半以上的干扰项。这次我虽然没有第一时间用上,但事后把新的IP信息和断点情况补录了进去,下次再遇到类似问题,比这次会快很多。