综合分诊:支付 API 故障
目标
把三个缺陷叠加在一起的故障按层缩小范围,锁定原因、进行修复,并留下规定格式的事后报告。一次性用上本课程学到的所有工具。
为什么重要
实际故障往往不止一个原因。修好一个后说“没好啊”就转换方向,连已经修好的也会开始怀疑。所以把每一层都检查到底、把发现的全部记下来,最终反而更快。另外,修复之后要用当初复现失败的那条命令确认成功,处理才算结束。
步骤
- 用
bash /opt/fixtures/nt-triage/start-incident.sh复现故障情形,并阅读/opt/fixtures/nt-triage/incident.md。创建/root/triage目录。 - 把向自己的接口 IP ping 3 次的结果保存到
/root/triage/l3.txt。丢包率必须为 0%。 - 分别敲一下自己接口 IP 的 9101 和 9102 端口,把结果以两行写入
/root/triage/l4.txt。9101=<open|refused|timeout>/9102=<open|refused|timeout> - 确认
pay-api.labhub.local的名称解析结果,以两行写入/root/triage/name.txt。RESOLVED=<IP returned by getent>/SOURCE=<absolute path of the file that holds that value> - 确认 9101 服务的监听地址,以一行写入
/root/triage/bind.txt。格式为BIND=<listen address:port>。(例:BIND=127.0.0.1:9101) - 向可以访问的一方(9102)请求
/ok,把状态码以code=<code>一行写入/root/triage/http.txt。 - 修复两处。
- 把
/etc/hosts中pay-api.labhub.local的条目改正为这台服务器的实际接口 IP。 - 重新启动 9101 服务,让它在
0.0.0.0上监听。(结束原有进程) 然后确认curl -s http://pay-api.labhub.local:9101/ok成功,并把输出保存到/root/triage/fixed.txt。
- 把
- 把
/root/triage/report.txt写成以下 6 行。SYMPTOM=remote-timeout/LAYER1=name/LAYER2=bind/CAUSE_NAME=<wrong IP originally in hosts>/CAUSE_BIND=127.0.0.1/FIXED=yes
参考
- 重新启动服务时,先用
pkill -f 'server.py 9101'清理,再用nohup python3 /opt/fixtures/nt-http/server.py 9101 0.0.0.0 &启动。 - 名称解析结果用
getent hosts确认,实际监听地址用ss -ltnp确认。 - 常见错误 1:在第 3 步用回环地址测试,两个端口看起来都是 open。一定要用接口 IP。
- 常见错误 2:在第 7 步只改 hosts、不改绑定,仍然会失败。原因有两个。
复现故障情形
用 bash /opt/fixtures/nt-triage/start-incident.sh 复现故障情形,并阅读 /opt/fixtures/nt-triage/incident.md。创建 /root/triage 目录。
运行夹具的启动脚本就会制造出故障情形。也请一并阅读报告单。
确认 L3 可达性
把向自己的接口 IP ping 3 次的结果保存到 /root/triage/l3.txt。丢包率必须为 0%。
要用 IP 而不是名称来确认,才不会和名称问题混在一起。使用自己的接口地址。
按端口判定结果
分别敲一下自己接口 IP 的 9101 和 9102 端口,把结果以两行写入 /root/triage/l4.txt。
9101=<open|refused|timeout> / 9102=<open|refused|timeout>
两个端口的结果不同。准确区分 refused、timeout 和 open 后再写。
锁定名称解析问题
确认 pay-api.labhub.local 的名称解析结果,以两行写入 /root/triage/name.txt。
RESOLVED=<IP returned by getent> / SOURCE=<absolute path of the file that holds that value>
把 getent 返回的 IP 与这台服务器的实际 IP 进行比较。还要找出这个值写在哪里。
锁定绑定问题
确认 9101 服务的监听地址,以一行写入 /root/triage/bind.txt。格式为 BIND=<listen address:port>。(例:BIND=127.0.0.1:9101)
ss 输出的 Local Address 列就是答案。分辨出两个服务中哪一个有问题。
确认应用层
向可以访问的一方(9102)请求 /ok,把状态码以 code=<code> 一行写入 /root/triage/http.txt。
先通过可访问的一方确认,证明服务本身是正常的。
修复并验证
修复两处。
- 把
/etc/hosts中pay-api.labhub.local的条目改正为这台服务器的实际接口 IP。 - 重新启动 9101 服务,让它在
0.0.0.0上监听。(结束原有进程) 然后确认curl -s http://pay-api.labhub.local:9101/ok成功,并把输出保存到/root/triage/fixed.txt。
两处都要修好。修复后一定要用外部地址再确认一次。
事后报告
把 /root/triage/report.txt 写成以下 6 行。
SYMPTOM=remote-timeout / LAYER1=name / LAYER2=bind / CAUSE_NAME=<wrong IP originally in hosts> / CAUSE_BIND=127.0.0.1 / FIXED=yes
格式是固定的。每个值都必须是在前面步骤中实际确认过的。