问题出现得很突然,日志倒是留得挺全。阿里云 ALB 挂三台 nginx 后端,业务方反馈下单接口偶发 504,可 nginx 的 access log 里同一时刻的请求记录是 200,upstream_response_time 只有 0.3 秒,两边对不上。

刚开始盯着「健康检查把一台慢节点留在组里,部分请求被转发过去后卡住」,折腾了半个多小时,排掉了。

排查方向其实有限,先把可能性排一排。ALB 到后端之间的连接复用有问题,握手和排队时间没算进后端耗时。少数情况下是后端返回的响应体较大,ALB 等首字节之后就超时了,日志里看不出传输阶段。

还有一种情况,ALB 的 idle timeout 比 nginx 的 keepalive_timeout 短,连接被中途断开。

第一件事是按 request_id 把两边日志对上

grep 8f3c2a1b /var/log/nginx/access.log

然后统计后端响应时间的分布,看长尾

awk '{print $NF}' /var/log/nginx/access.log | sort -n | tail -20

调低 nginx 的 keepalive 超时,短于 ALB 的空闲超时

grep -n keepalive_timeout /etc/nginx/nginx.conf

摘掉慢节点后观察 504 是否消失

curl -s -o /dev/null -w '%{time_total}\n' http://10.0.0.12/health

别只看报错消失,验证要多做一步。ALB 监控里 504 比例降到零,后端 access log 与 ALB 访问日志的 request_id 一一对应,长尾请求耗时回到 1 秒以内。

容易忽略的是,四层和七层负载均衡的超时是两套参数,先确认是哪一层先断;对不上日志时优先查连接复用和空闲超时,而不是加后端超时时间。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189