记一次 Nginx 502 Bad Gateway 上游长连接超时与 keepalive 踩坑排查

举报
yd_218612773 发表于 2026/10/31 09:36:11 2026/10/31
【摘要】 线上偶发 Nginx 502 报错,查看 error.log 提示 connection reset by peer。本文复盘从抓包排查到 upstream keepalive 与超时时间对齐的完整解决过程。

最近生产环境一个对外的 API 网关偶发返回 502 Bad Gateway,查看 Nginx 的 error.log 发现了如下报错信息:

2026/10/28 15:20:11 [error] 14201#0: *891241 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: 10.0.12.8, server: api.example.com, request: "GET /api/v1/user/info HTTP/1.1", upstream: "http://192.168.1.102:8080/api/v1/user/info"

一、排查思路与现场复现

起初怀疑是后端应用负载过高被 OOM 杀死,但检查后端 Tomcat/Go 服务的日志发现没有任何崩溃记录,同时 CPU 和内存指标正常。

使用 netstat -ant | grep 8080 统计连接状态,发现存在大量 TIME_WAIT 连接:

netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key, state[key]}'
TIME_WAIT 4320
ESTABLISHED 210

二、根本原因分析

排查 upstream 配置后发现两个核心问题:

  1. HTTP 1.0 短连接:Nginx 反向代理默认使用 HTTP/1.0 协议连接上游,每个请求处理完即关闭 socket,没有复用长连接。
  2. Keepalive 超时时间未对齐:Nginx 侧虽然在 upstream 块中配置了 keepalive 32,但后端服务的 keepalive 超时设置为 5 秒,而 Nginx 侧的超时为 60 秒。当 Nginx 尝试复用一个在后端刚好超时的连接时,后端直接返回了 RST 报文,触发 104 Connection reset。

三、配置调优与验证

在 Nginx 的 location 中显式指定 HTTP/1.1 并清空 Connection 请求头:

upstream backend_cluster {
    server 192.168.1.102:8080 max_fails=3 fail_timeout=10s;
    server 192.168.1.103:8080 max_fails=3 fail_timeout=10s;
    keepalive 64; # 保持长连接池
}

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://backend_cluster;
        proxy_http_version 1.1;
        proxy_set_header Connection ""; # 关键:去除默认的 close 头
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_connect_timeout 5s;
        proxy_read_timeout 60s;
    }
}

重新加载配置 nginx -s reload 后,持续压测验证,502 错误彻底消失,上游并发连接数下降 70%,性能明显改善。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。