keepalive未生效或配置错配导致连接堆积,需从连接状态、协议头、超时协同三方面排查:先用ss命令查真实活跃连接数,再核对upstream keepalive值与worker数量是否匹配,检查数据库连接来源;确认upstream中keepalive N、proxy_http_version 1.1、proxy_set_header Connection ""是否齐全,keepalive_timeout建议设为15–30s,并确保MySQL wait_timeout ≥ Nginx keepalive_timeout+缓冲;云数据库需关注其空闲连接kill策略;最后通过debug日志、$upstream_addr、$upstream_response_time及SHOW PROCESSLIST交叉验证泄漏点。

这不是 keepalive “导致”连接激增,而是 keepalive 没生效或配置错配,让连接卡在 ESTABLISHED 状态不释放,最终撑爆后端数据库的连接上限(如 MySQL 的 max_connections)。排查要从连接状态、协议头、超时协同三方面入手,不能只看配置。
确认是否真有连接堆积
别急着改配置,先用命令验证现象:
- 查当前到数据库的真实活跃连接数:
ss -tn state established '( dport = :3306 )' | wc -l(把 3306 换成你的数据库端口) - 对比理论值:如果 upstream 配了
keepalive 32、Nginx 有worker_processes 4,最多应有 128 个空闲长连接;若实际查出 500+,说明连接没回收 - 检查数据库侧连接来源:
SELECT host, count(*) FROM information_schema.processlist GROUP BY host;,确认大量连接是否来自 Nginx 服务器 IP
检查 Nginx 配置是否触发“假长连”
以下任一缺失都会让 keepalive 形同虚设:
- upstream 块里没写
keepalive N(默认完全不启用长连接) - location 中没加
proxy_http_version 1.1(HTTP/1.0 默认关闭连接) - 没写
proxy_set_header Connection ""(若客户端请求带Connection: close,Nginx 会原样透传,导致后端主动断连) -
keepalive_timeout设得过大(如 300s),空闲连接挂太久;建议设为 15–30s,略大于业务平均响应间隔
对齐数据库服务的空闲策略
Nginx 不会感知数据库是否准备关连,必须两端超时协同:
- MySQL 要确保
wait_timeout和interactive_timeout≥ Nginx 的keepalive_timeout+ 缓冲(例如后者是 20s,前者至少设为 30s) - 若用连接池(如 HikariCP),检查
connection-timeout、idle-timeout和max-lifetime,避免比 Nginx 更早主动断开 - 云数据库(如 RDS)注意其后台维护机制——某些版本会在空闲连接超过阈值时静默 kill,需查阅对应文档确认行为
用日志和指标交叉验证泄漏点
仅看配置不够,要抓运行时证据:
- 开启 debug 日志(需编译含
--with-debug),配置error_log /var/log/nginx/debug.log debug;,重点搜keepalive、reuse、close相关行 - 在
log_format中加入$upstream_addr和$upstream_response_time,分析哪些数据库实例被持续选中但响应慢 - 配合数据库监控:执行
SHOW PROCESSLIST;或查information_schema.PROCESSLIST,观察连接是否长期处于Sleep状态且Time值持续增长











