keepalive_timeout过长会间接导致内存长期占用,因其延长空闲连接驻留时间,使ngx_connection_t结构体、缓冲区及SSL上下文等per-connection资源无法及时释放,引发RSS线性增长、fd耗尽及Waiting状态持续偏高。

Keepalive timeout 过长本身不会直接导致内存长期占用,但会间接引发连接堆积、空闲连接滞留、worker 进程中连接结构体(ngx_connection_t)长期不释放等问题,尤其在高并发、短连接业务中,可能表现为 worker 进程 RSS 持续偏高、连接数居高不下、甚至触发 worker_connections 耗尽。排查需从连接状态、内存分布和配置联动三方面入手。
确认活跃连接是否异常堆积
使用 Nginx 内置状态模块(需编译时启用 --with-http_stub_status_module)观察实时连接行为:
- 访问
/status(如curl http://127.0.0.1/status),重点关注Active connections和Reading/Writing/Waiting三态分布; - 若
Waiting长期占 Active connections 80% 以上,且持续数分钟不下降,说明大量连接处于 keepalive 空闲等待状态; - 配合
netstat -ant | grep :$port | awk '{print $6}' | sort | uniq -c查看 ESTABLISHED 连接中处于ESTABLISHED但无数据收发的连接数量与存活时长。
检查 worker 进程内存与连接数关系
内存增长是否与连接数线性相关,是判断 keepalive 影响的关键线索:
- 用
ps aux --sort=-rss | grep nginx查看 worker 进程 RSS 大小,记录基线值; - 用
ss -o state established '( dport = :$port )' | wc -l统计当前 ESTABLISHED 连接数; - 压测后观察:若连接数回落但 RSS 未同步下降(例如 5 分钟后仍维持高位),说明连接结构体或其关联缓冲区未及时释放,keepalive timeout 过长可能是诱因;
- 注意:Nginx 默认为每个连接分配约 2–4 KB 内存(含读写缓冲区、SSL 结构等),千级空闲连接即可增加数 MB RSS。
验证 keepalive_timeout 与实际连接生命周期是否匹配
不要只看配置值,要结合客户端行为和上游依赖判断合理性:
- 检查客户端(尤其是移动端、CDN、爬虫)是否真正复用连接:用
tcpdump -i any port $port -w keepalive.pcap抓包,过滤 FIN/RST,观察两次请求间隔是否落在keepalive_timeout内; - 若大部分客户端在 5–10 秒内就发起下一次请求,却将
keepalive_timeout设为 65s,属于过度保留; - 反向代理场景下,还需检查
proxy_http_version 1.1和proxy_set_header Connection ''是否开启,否则 upstream 可能提前关闭连接,导致 Nginx 端连接空转超时; - 建议值参考:公网服务通常设为
15–30s;内网服务可适当延长至60s;纯 API 网关或 gRPC 代理建议 ≤20s。
辅助定位:日志与调试信号
启用临时调试手段,避免误判其他内存泄漏:
- 临时开启
error_log /var/log/nginx/debug.log debug;(需重新编译含--with-debug),关注"close connection" / "keepalive timeout"日志频率与时序; - 发送
kill -USR1 $nginx_pid生成连接 dump(需配置debug_points abort或使用nginx -t -v确认 debug 支持),分析哪些连接长时间处于NGX_HTTP_KEEPALIVE状态; - 排除干扰项:确认未开启
open_file_cache过大、ssl_session_cache未清理、或第三方模块(如 lua-resty-redis 连接池)持有长连接。











