记一次 Nginx 502 Bad Gateway 上游长连接超时与 keepalive 踩坑排查
【摘要】 线上偶发 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 配置后发现两个核心问题:
- HTTP 1.0 短连接:Nginx 反向代理默认使用 HTTP/1.0 协议连接上游,每个请求处理完即关闭 socket,没有复用长连接。
- 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)