1、故障排查全景:HTTP请求的生命周期、日志的价值、常见的故障类型
做运维这些年,我处理过成百上千的HTTP故障。说实话,每次接到告警,我脑子里都会快速过一遍那个请求从发起到返回的全过程。你想想看,一个请求从用户浏览器出发,经过DNS、负载均衡、网关、应用服务、缓存、数据库……中间任何一个环节出问题,用户感知到的就是“打不开”或“好慢”。
所以这一章,我们先搭个全景框架。后面29章的所有技巧,都建立在这个框架之上。
1.1 HTTP请求的生命周期
一个典型的HTTP请求,从客户端到服务端再返回响应,大致经历这么几个阶段。我习惯把它分成“前端链路”和“后端链路”来看。
核心链路速览:
- DNS解析 — 域名变IP,这一步挂了就是“无法解析主机”。
- TCP连接 — 三次握手,建立可靠通道。
- TLS握手 — HTTPS场景下协商加密套件、交换证书。
- 发送请求 — 客户端发出HTTP报文(方法、路径、头、体)。
- 负载均衡 — 转发到后端某台真实服务器。
- 应用处理 — 业务逻辑、数据库查询、调用外部服务。
- 返回响应 — 状态码、响应头、响应体回传客户端。
- 连接关闭/复用 — keep-alive或四次挥手。
每个阶段都有对应的日志可以追踪。我个人习惯把日志按“入口、中间、出口”三个位置来组织,这样排查时思路特别清晰。
1.2 日志的价值
日志是什么?说白了,就是系统在关键时刻留下的“黑匣子”。没有日志,你排查故障就像蒙着眼睛找东西。
我记得有一次线上告警,用户反馈下单接口超时。我第一反应是看Nginx的access.log,发现upstream_status全是504。再翻应用日志,看到一条SQL执行了30秒。最后定位到是数据库连接池被慢查询打满了。整个过程不到10分钟,全靠日志串联。
日志的三大核心价值:
- 还原现场 — 请求从哪里来、经过了哪些服务、花了多长时间。
- 定位根因 — 错误栈、异常信息、参数快照,直接告诉你哪里崩了。
- 量化分析 — 平均响应时间、错误率、P99延迟,帮你判断系统健康度。
但这里有个坑——日志不是越多越好。我曾经见过一个团队,每个接口都打印完整的请求体和响应体,一天产生几百GB日志。结果排查问题时,光翻文件就花了半小时。嗯,这里要注意:日志要有结构、有分级、有关联ID。
| 日志类型 | 典型来源 | 排查价值 |
|---|---|---|
| 访问日志 | Nginx、网关、负载均衡 | 请求来源、状态码、响应时间、上游地址 |
| 应用日志 | 业务代码、框架(Spring Boot、Gin等) | 业务逻辑、异常栈、调用链、参数快照 |
| 慢日志 | MySQL、Redis、MongoDB | 慢查询、慢操作、索引缺失 |
| 错误日志 | 系统组件、中间件 | OOM、连接超时、配置错误 |
| 审计日志 | 安全组件、操作记录 | 谁在什么时间做了什么操作 |
1.3 常见的故障类型
故障千奇百怪,但归纳起来就那么几类。我按“现象”来分,这样排查时更容易对号入座。
1.3.1 连接类故障
客户端连不上服务端,或者连接被重置。典型表现:Connection refused、Connection timeout、Connection reset by peer。
- 原因:端口没开、防火墙拦截、后端服务挂了、连接池耗尽。
- 日志看哪里:Nginx的upstream状态、应用层的网络异常栈。
1.3.2 超时类故障
请求发出去,等了很久才返回,或者直接超时。典型表现:504 Gateway Timeout、upstream timed out。
- 原因:后端处理慢、数据库慢查询、外部API响应慢、线程池阻塞。
- 日志看哪里:应用日志的执行耗时、慢日志、调用链追踪。
避坑指南:我曾经遇到一个案例,Nginx的proxy_read_timeout设了60秒,但应用层的接口超时设了30秒。结果Nginx还在等,应用已经断了,返回给客户端的是502。排查时两边日志对不上,浪费了半天。所以超时配置一定要上下游对齐。
1.3.3 状态码异常类故障
请求正常返回了,但状态码不对。比如该200的返回了500,或者该302的返回了404。
- 原因:代码bug、路由配置错误、权限校验失败、资源不存在。
- 日志看哪里:应用日志的异常信息、业务日志的参数快照。
1.3.4 数据类故障
接口返回了,状态码也是200,但数据不对。比如字段为空、数值错误、乱码。
- 原因:缓存与数据库不一致、序列化/反序列化问题、字符集不匹配。
- 日志看哪里:业务日志的入参和出参、数据库查询结果。
1.3.5 性能类故障
接口能正常返回,但响应时间远超预期。比如平时10ms的接口突然变成2秒。
- 原因:慢查询、锁竞争、GC停顿、网络带宽瓶颈、CPU飙高。
- 日志看哪里:慢日志、GC日志、系统监控指标、调用链耗时。
| 故障类型 | 典型现象 | 排查切入点 |
|---|---|---|
| 连接类 | Connection refused / timeout | 端口、防火墙、服务状态、连接池 |
| 超时类 | 504 / upstream timed out | 应用耗时、慢查询、线程池 |
| 状态码异常 | 500 / 404 / 403 | 代码异常、路由、权限 |
| 数据类 | 数据为空 / 乱码 / 不一致 | 缓存、序列化、字符集 |
| 性能类 | 响应慢 / 延迟高 | 慢日志、GC、监控指标 |
1.4 小结
这一章我们搭好了全景框架。你记住三件事就行:
- HTTP请求有8个关键阶段,每个阶段都可能出问题。
- 日志是排查故障的“第一手证据”,要有结构、有关联ID。
- 故障分5大类,先看现象再找日志,别瞎猜。
后面每一章,我都会带着你深入一个具体的故障场景,手把手教你怎么看日志、怎么定位、怎么修复。准备好了吗?