send_timeout仅控制发送响应体时两次写操作间的超时,不检测空闲僵尸连接;真正有效的是keepalive_timeout(控制HTTP keep-alive空闲时长)和TCP keepalive机制。

通过 send_timeout 自动断开长时间无响应的僵尸连接,关键在于理解它的真实作用范围——它**只控制发送响应数据过程中的超时**,而非检测或清理空闲连接。真正用于应对僵尸连接(如客户端断开但服务端未感知、TCP 连接长期空闲)的是 keepalive_timeout 和 TCP 层的保活机制。
send_timeout 并不适用于“检测僵尸连接”
send_timeout(Nginx 中)定义的是:向客户端发送响应体(response body)时,两次成功写操作之间的最大等待时间。如果在这段时间内无法把数据发出去(比如客户端接收缓冲区满、网络卡顿、客户端已崩溃但 FIN 未到达),Nginx 就会关闭该连接。
但它不会在客户端完全不发请求、服务端也无响应要发的情况下触发;也就是说,对纯空闲连接(没有请求、也没有响应要发),send_timeout 完全不生效。
常见误用场景:
- 客户端建立连接后不发任何请求(SYN 已完成,但 HTTP 请求没来)→ send_timeout 不起作用
- 客户端收到响应后挂起,不再交互 → 若后续无新请求,send_timeout 也不介入
真正该配置的参数:keepalive_timeout
这是 Nginx 控制 HTTP keep-alive 连接空闲时长的核心指令。它决定了:一个 keep-alive 连接在处理完一次请求后,若无新请求到达,最多保持打开多久。
建议配置示例:
-
keepalive_timeout 15s;—— 连接空闲 15 秒后自动关闭 -
keepalive_requests 100;—— 单个连接最多处理 100 个请求(防止单连接长期占用)
该机制能有效回收那些“建连后不请求”或“请求后不继续”的半死连接,比依赖 send_timeout 更直接、更可靠。
补充:启用 TCP keepalive 提升底层健壮性
HTTP 层的 keepalive_timeout 依赖于上层活动,而操作系统 TCP keepalive 可在更底层探测死链(如中间网络中断、客户端硬断电)。需在 Nginx 配置中显式开启:
-
tcp_keepalive on;(Nginx 1.19.6+ 默认开启,旧版本需手动设) - 系统级调优(Linux):
net.ipv4.tcp_keepalive_time = 600(首次探测前空闲秒数)net.ipv4.tcp_keepalive_intvl = 60(重试间隔)net.ipv4.tcp_keepalive_probes = 3(失败后重试次数)
注意:TCP keepalive 探测周期较长(默认 2 小时),适合防“长周期静默断连”,不适合替代 HTTP 层的快速超时策略。
辅助手段:限制连接生命周期与资源占用
除了超时,还可从连接来源和行为维度抑制僵尸连接影响:
- 用
limit_conn限制单 IP 并发连接数,防止慢速攻击耗尽连接槽位 - 搭配
limit_req限制请求频率,避免恶意空连接反复建立 - 日志中关注
$connection_requests和$request_time,识别异常长连接或零请求连接
这些不直接“断开”连接,但能降低僵尸连接对服务整体可用性的影响。

















