nginx 不产生标准“僵尸连接”,实际指失效未关闭的 tcp 连接(如 close_wait、空闲超时、websocket 状态不一致),需通过 proxy_read_timeout、keepalive、内核 keepalive 参数协同控制生命周期,配合 down 参数隔离假在线后端节点。

Nginx 本身不产生“Zombie Connection”(僵尸连接)这个术语在 TCP 层面并不存在标准定义,但实际运维中常用来指代已失效却未被及时关闭的 TCP 连接——比如卡在 CLOSE_WAIT、长时间空闲未断开、或 WebSocket 中业务层认为活跃而代理层已静默中断的连接。这类连接会占用端口、文件描述符和连接跟踪资源,严重时导致新建连接失败。
Nginx 的处理逻辑不是“主动杀掉僵尸”,而是通过超时控制、keepalive 协同、内核联动和被动探测,让僵死连接自然退出生命周期。关键不在“清理”,而在“预防+及时释放”。
启用并约束连接空闲生命周期
Nginx 不维护连接健康状态,只靠时间窗口做被动裁决:
-
proxy_timeout 30s;(stream 模块)或proxy_read_timeout 60s;(http 模块):限制后端响应等待时间,超时即断开,避免卡在 CLOSE_WAIT -
keepalive_timeout 60s;(http)或so_keepalive=on;(stream):启用系统级 TCP keepalive,触发内核探测机制 -
keepalive_requests 1000;和keepalive 32;(upstream 内):限制单个长连接复用次数与最大空闲连接数,防连接池滞留
示例(stream):
stream { upstream backend { server 192.168.1.10:8080; server 192.168.1.11:8080; } server { listen 8001 so_keepalive=on; proxy_timeout 45s; proxy_pass backend; } }
依赖内核 TCP keepalive 探活
Nginx 的 so_keepalive=on 仅开启系统机制,真正探测由内核执行:
-
net.ipv4.tcp_keepalive_time = 600:空闲 10 分钟后开始发探测包 -
net.ipv4.tcp_keepalive_intvl = 60:每 60 秒发一次 -
net.ipv4.tcp_keepalive_probes = 3:连续 3 次无响应则关闭连接
这些参数需写入/etc/sysctl.conf并sysctl -p生效;也可在 listen 行中覆盖:listen 8001 so_keepalive=on:300:30:2;
区分 CLOSE_WAIT 与 TIME_WAIT,对症下药
-
CLOSE_WAIT 堆积 → 是 Nginx 或后端没调用 close(),属应用层问题:
- 检查
proxy_ignore_client_abort off;(默认)是否被误设为 on - 确认后端服务是否 hang 住、GC STW 导致响应延迟超
proxy_read_timeout
- 检查
-
TIME_WAIT 过多 → 是 Nginx 主动关闭连接后残留,不影响功能但占端口:
- 启用
net.ipv4.tcp_tw_reuse = 1(配合tcp_timestamps = 1)允许端口复用 - 可将
net.ipv4.tcp_fin_timeout调至 30,加快 TIME_WAIT 回收(仅当tw_reuse开启时生效)
- 启用
主动识别 + 手动干预“假在线”后端节点
所谓“僵尸节点”,是指 upstream 中仍被调度但实际无响应的服务器:
- 查 error.log:搜索
connect() failed、upstream timed out、no live upstreams - 看 nginx_status:
Writing持续增长 +Requests停滞,提示转发卡住 - 立即隔离:在对应
server行加down;,再nginx -s reload,无需重启
不复杂但容易忽略











