502异常若集中于特定节点、时段或路径,极可能是硬件故障;需通过access日志统计$upstream_addr与$upstream_status,结合softirq、iostat、ethtool、dmidecode等工具验证CPU降频、磁盘I/O卡死、网卡丢包或内存ECC错误,并辅以本地curl压测和dmesg日志交叉定位。
502
状态码
在集群中不是均匀出现的,如果集中在特定节点、特定时段或特定请求路径,就极可能是硬件层面出了问题——比如某台机器内存虚高、磁盘 I/O 卡死、网卡丢包或 CPU 频率异常降频。关键不是看“有没有 502”,而是看“谁在报、什么时候报、报给谁、报什么路径”。
定位异常节点:从 access 日志和 upstream 指标切入
nginx access 日志里每条记录都带
$upstream_addr
和
$upstream_status
。用以下命令快速统计各后端地址返回 502 的次数:
($11 是 $upstream_addr)
若发现某个 IP:PORT 出现远高于其他节点的 502 计数(例如 80% 都指向 10.20.30.41:8080),先标记该节点为高嫌疑对象
同步查该节点上 nginx error.log 中是否高频出现
"upstream prematurely closed connection"
或
"Connection refused"
—— 这类错误往往对应进程僵死、端口监听异常或内核连接队列溢出
交叉验证硬件指标:避开“看起来正常”的假象
CPU 使用率低 ≠ 硬件健康。很多硬件故障表现为间歇性响应延迟,监控面板平均值会掩盖瞬时毛刺:
检查该节点的
softirq 时间占比
(
),持续 >30% 可能是网卡中断处理瓶颈
运行
,关注
%util 接近 100 且 await > 50ms
,说明磁盘已饱和,Java 应用 GC 日志写入或日志轮转可能被阻塞
执行
查看网卡协商速率与实际 link 状态;再用
看是否有 TCP 重传或接收丢包
用
和
检查是否存在内存 ECC 错误计数上升(尤其在 502 集中时段)
复现与隔离:用最小流量触发故障特征
不依赖用户真实请求,主动构造可复现压力:
在疑似节点上直接
,反复执行 100 次,统计失败率。若本地直连也偶发失败,基本排除网络层,指向本机内核、JVM 或容器 runtime
临时将该节点从 upstream group 中摘除(
后观察集群 502 是否骤降;再单独对其压测,如
),对比成功率与响应时间分布
若压测中出现大量
"Connection reset by peer"
,配合
查看是否触发了 OOM killer 或 TCP 连接数超限(
设置过小)
关联应用层日志:确认硬件问题引发的连锁反应
硬件异常很少直接返回 502,而是通过影响应用行为间接暴露:
检查该节点 JVM GC 日志:若 Full GC 频繁且耗时 >5s,会导致 HTTP 请求线程长时间挂起,nginx 因
proxy_read_timeout
到期而返回 502
查看应用日志中是否有
"java.io.IOException: Broken pipe"
或
"AsyncRequestTimeoutException"
,这类异常常由底层 socket 写失败触发,根源可能是网卡驱动 bug 或内存不足导致 send buffer 清空失败
对比同一业务在其他节点的日志,若仅该节点出现大量
"Failed to write response"
或
"Response already committed"
,大概率是内核协议栈或 JVM native 层异常
awk '$9 == "502" {print $11}' access.log | sort | uniq -c | sort -nrcat /proc/stat | grep softirqiostat -x 1 5ethtool eth0netstat -s | grep -i "retransmit\|drop"dmidecode -t memoryedac-util --statuscurl -I http://localhost:8080/healthnginx -s reloadab -n 1000 -c 50 http://node-ip:8080/api/testdmesg -T | tail -30net.core.somaxconn