把代理与后端切开
反向代理(Nginx、HAProxy、云 SLB)夹在客户端与后端之间,故障时长出现两种完全相反的判断:「代理转发有问题」与「后端处理慢」。切开责任最有效的办法是对照测试:一次直连后端、一次经代理,比较耗时与状态码;再看 nginx 日志里的 $request_time 与 $upstream_response_time 差值——差值大是代理或网络段的问题,upstream 值大才是后端慢。
基本信息
| 适用平台 | Nginx / HAProxy / 云 SLB + 后端应用 |
|---|---|
| 关键字段 | $request_time、$upstream_response_time、$upstream_status、$upstream_addr |
| 对照手段 | curl 直连后端与经代理各测一次,注意带 Host 头 |
| 日志开关 | log_format 里显式加上 upstream 相关变量才可判读 |
| 权限要求 | 查看后端监听需后端主机权限;读日志需相应文件权限 |
典型使用场景
- 用户报「网站慢」:先确认慢在代理转发还是后端处理
- 出现 502/504:用 $upstream_status 判断是后端拒连、超时还是返回了错误码
- 多后端负载均衡:确认请求是否打到了预期的那台后端
- 代理自身 CPU 高导致的排队:用 request_time 与 upstream 差值识别
- 变更网关配置后回归验证:对照直连与经代理的结果差异
对照与取证
对照与取证
# 直连后端(绕开代理),拿到基准耗时
curl -sS -o /dev/null -w 'direct %{http_code} %{time_total}\n' http://127.0.0.1:8080/api/health
# 经代理访问,注意 Host 必须与站点配置一致,否则命中默认站点
curl -sS -o /dev/null -w 'proxy %{http_code} %{time_total}\n' -H 'Host: api.example.com' http://10.0.0.5/api/health
# 分段耗时:连接、首字节、总时间
tail -50 /var/log/nginx/error.log
grep 'upstream' /var/log/nginx/error.log | tail -20
# 建议在 access log 里显式记录:$request_time $upstream_response_time $upstream_status $upstream_addr日志字段判读
| 字段 | 含义 | 判读要点 |
|---|---|---|
| $request_time | 从收到请求到响应完成的总耗时 | 与 upstream 值差距大说明时间花在代理或客户端侧 |
| $upstream_response_time | 后端响应耗时,多个后端时用逗号分隔 | 该值大即后端慢,责任明确 |
| $upstream_status | 后端返回的状态码 | 502/504 指向后端不可用或超时 |
| $upstream_addr | 命中的后端地址 | 多后端场景确认请求打到哪台 |
| $upstream_connect_time | 与后端建连耗时 | 数值大说明建连慢,可能是后端 backlog 满 |
日志里没有 upstream 相关字段就先补进 log_format 再复现:有这组字段,代理自身慢与后端慢一眼可分,没有就只能靠猜。