502错误主因是upstream keepalive连接复用失控:nginx复用已被后端关闭的空闲连接,收到rst触发502;典型日志为“connection reset by peer”,需严格错开nginx与后端keepalive_timeout(如后端20s则nginx设12–16s),并验证estab连接数与rst计数。

排查 upstream keepalive 连接池溢出导致的 502,关键不是“连接池满了”,而是连接复用失控引发的连接失效——Nginx 拿着一个已被后端关闭的空闲连接去发请求,结果收到 RST,触发 502。它不报“pool full”,但日志和现象非常典型。
看错误日志里的“Connection reset by peer”
这是最直接的信号。当 Nginx 错误日志中反复出现:
- recv() failed (104: Connection reset by peer) while reading response header from upstream
- 或伴随 upstream prematurely closed connection(但后端无崩溃日志)
说明 Nginx 正在复用一条“过期”的连接:后端已按自己的超时策略关闭了该连接,而 Nginx 的连接池还没来得及感知或清理,下次请求就撞上了 RST 包。
核对两端 keepalive 超时是否错位
这不是配置“开启 keepalive”就行,而是必须检查超时值是否严格错开:
- 查后端实际生效的 keepalive 超时:Tomcat 默认 20 秒;Spring Boot
server.tomcat.connection-timeout=20000;Node.jskeepAliveTimeout=5000 - 查 Nginx upstream 中是否显式配置了
keepalive_timeout(仅写keepalive 32不够!) - 确认 Nginx 的
keepalive_timeout比后端小至少 2–4 秒,例如后端 20s → Nginx 设 16s 或 12s
验证连接池是否真在“僵死”而非“溢出”
连接池溢出本身不会直接报 502,但会导致新建连接压力陡增,间接暴露底层问题。可观察:
- 用
ss -tn state established | grep :8080 | wc -l查 Nginx 到后端的 ESTAB 连接数,是否长期卡在keepalive N设置值附近且不回落 - 配合
netstat -s | grep -i "reset"看是否有异常 RST 计数上升 - 对比高峰期前后 dmesg 是否有 OOM 杀进程记录——排除混淆项:如果是 OOM 导致后端崩,日志会是
upstream prematurely closed connection+ dmesg 显示 killed process
快速验证与修复配置
临时加一组最小化有效配置,重启后观察 502 是否收敛:
- upstream 块内:
keepalive 64; keepalive_timeout 12s;(假设后端为 20s) - location 块内:
proxy_http_version 1.1; proxy_set_header Connection ''; - 禁用干扰项:不要手动设
proxy_set_header Keep-Alive ""或Connection: keep-alive











