nginx的lingering_close是为实现优雅关闭而设计的机制,通过先shutdown(SHUT_WR)再限时监听FIN,避免RST导致客户端丢响应或中间设备误判;需配合lingering_time、lingering_timeout及reset_timedout_connection off协同配置。

nginx 的 lingering_close 是专为解决“响应已发出但连接被粗暴中断”这一问题设计的机制。它不追求立刻关掉连接,而是先关闭写端、保留读端一小段时间,让客户端有机会收完错误信息或响应体,同时消化掉自己尚未发完的残留请求数据——从而避免触发 RST,实现真正意义上的优雅关闭。
理解 lingering_close 的核心作用
当客户端提前断开(比如用户刷新页面、网络闪断),而 nginx 还有响应数据在内核发送缓冲区未发出,或客户端仍有少量请求数据正在途中时,直接调用 close() 很可能引发以下连锁反应:
- 内核检测到接收缓冲区还有未读数据,立即回 RST 包
- RST 导致客户端丢弃已收到但未 ACK 的响应内容(如 400/500 错误页)
- 中间设备(如某些企业防火墙、运营商代理)将 RST 视为异常,记录告警甚至拦截
lingering_close 就是绕过这个陷阱:它把“关连接”拆成两步——先 shutdown(SHUT_WR) 停止发数据,再用有限时间监听客户端是否继续发 FIN 或数据,期间只收不回,收完或超时后才彻底释放 socket。
正确配置 lingering_close 及配套参数
单独开启 lingering_close 效果有限,必须与 lingering_time 和 lingering_timeout 协同使用:
-
lingering_close:设为
on(默认行为,推荐)或always(强制所有请求 linger,包括 HEAD/空响应);off完全禁用,仅适合极低延迟、高并发且客户端完全可信的内部服务 - lingering_time:定义整个延迟关闭窗口总时长(单位秒),默认 30s;建议根据业务响应体大小和客户端网络质量调整,一般设为 5–15 秒已足够
- lingering_timeout:每次尝试读取客户端数据的超时(单位毫秒),默认 5000ms;设太小(如 100ms)会导致频繁轮询,设太大(如 10s)会拖慢连接回收;推荐 1000–3000ms
示例配置(放在 http 块中):
lingering_time 10;
lingering_timeout 2000;
配合 reset_timedout_connection 避免语义冲突
reset_timedout_connection 若开启,会在连接超时时主动发 RST 强制中断——这与 lingering_close “耐心等待”的初衷完全相悖。因此,只要启用了 lingering 机制,该指令必须显式设为 off:
否则,当 lingering_time 超时后,nginx 可能一边想“温和收尾”,一边又执行 RST,造成行为不可控。
什么情况下需要特别关注 lingering 行为
以下场景中,未启用或配置不当的 lingering_close 更易暴露问题:
- 返回大体积错误页(如自定义 500 HTML)时客户端快速关闭连接
- 使用 HTTP pipelining(虽已少见,但在某些旧设备或测试工具中仍存在)
- 上游服务响应慢,nginx 缓冲了部分响应后再转发,此时客户端中断
- 移动端弱网环境,TCP 重传延迟高,FIN 到达晚于 nginx 的默认 close 时机
这些情况都可能导致客户端收不到关键状态信息,而启用并合理调优 lingering_close 能显著提升错误可感知性与协议兼容性。

















