send_timeout仅控制nginx向客户端发送响应时两次写操作间的等待时长,适用于慢速接收场景;需配合reset_timedout_connection on才能强制rst断连,空闲连接应由keepalive_timeout等机制处理。

send_timeout 不是用来释放“客户端无响应”的空闲连接,它只管一件事:Nginx 向客户端发送响应数据时,两次写操作之间能等多久。如果客户端接收太慢、卡住或已断开但 FIN 没到,Nginx 就会在这个超时后主动断连——但这不是针对僵尸连接,而是防慢速读拖垮 worker。
它真正控制的场景
适用于静态资源(如图片、JS、CSS)下发过程中,客户端接收异常缓慢的情况:
- 浏览器窗口最小化、网络丢包严重、TCP 接收窗口长期满
- 恶意低速读攻击(Slow Read),故意拉长响应传输时间
- CDN 回源或中间代理转发延迟大,导致 Nginx 等不到下一次可写事件
合理取值建议
静态服务不宜设长,否则一个慢连接会长期占用 worker:
- 普通网页/静态资源站:10–20 秒足够(99% 客户端毫秒级收完)
- 面向弱网移动设备:可放宽至 30 秒,但需配合 access_log 中 $request_time 和 $upstream_response_time 观察真实 P95 发送耗时
- 绝对避免设为 0 或 300 秒以上——这等于给 Slow Read 攻击留出完整通道
必须搭配 reset_timedout_connection 才有效果
仅设 send_timeout,Nginx 默认发 FIN 关闭连接;若客户端不响应,连接会卡在 TIME_WAIT,socket 资源未释放:
- 加上 reset_timedout_connection on;,Nginx 直接发 RST 强制中断
- worker 可立即复用该连接槽位,避免连接表被半关闭连接挤满
- 该指令需放在 http/server/location 块中,与 send_timeout 同级生效
别指望它处理真正的僵尸连接
客户端建连后一直不发请求、或响应完就挂起不再交互——这些空闲连接,send_timeout 完全不触发:
- 这类情况靠 keepalive_timeout(建议 15–60 秒)和 keepalive_requests(建议 100–500)回收
- 底层探测死链靠 TCP keepalive(tcp_keepalive on;),但默认探测周期长(约 2 小时),适合防硬断电,不能替代 HTTP 层快速超时
- 验证是否生效:用
curl -v --limit-rate 10 http://x/logo.png模拟慢速下载,看是否在设定时间内断开并返回 408 或 RST











