send_timeout防客户端接收慢导致的连接占用,专管响应发送阶段超时断连;默认60秒过长,建议Web服务设15–30秒,大文件可提至120秒,并需配合tcp_nodelay on、reset_timedout_connection on等配置生效。

send_timeout 是 Nginx 在向客户端发送响应数据过程中,控制两次写操作之间最大等待时间的关键参数。它不负责建立连接或接收请求,而是专管“发得慢”这个环节——当后端已返回完整响应、Nginx 开始往客户端吐数据时,若两次 write() 调用间隔超过 send_timeout,Nginx 就会主动断开连接。
这个机制对释放被慢速客户端(如网络极差的移动设备、故意限速的攻击者)长期占用的 worker 连接非常有效,尤其在响应体较大(如文件下载、大 JSON)时。
send_timeout 防的是什么场景
- 客户端接收能力极弱:比如 2G 网络下 TCP 窗口几乎为零,Nginx 发几个包就卡住,等几秒才收到 ACK
- 攻击者建连接后只收开头几百字节,然后停滞,让连接长期挂在
ESTABLISHED状态 - 中间代理(如某些企业防火墙)缓冲行为异常,导致响应流被截断或延迟
它不会干预请求阶段(那是 client_header_timeout 和 client_body_timeout 的事),也不影响后端处理时间。
合理设置 send_timeout 的要点
-
默认 60 秒太长:一个卡住的连接可能持续占着 worker 进程和 socket 资源,万级并发下极易耗尽
worker_connections - 常规 Web/API 服务建议设为 15–30 秒:足够覆盖真实弱网用户(如地铁进隧道瞬间),又大幅压缩攻击窗口
-
大文件下载或流式接口可单独提升:用
location ~ \.(zip|pdf|mp4)$ { send_timeout 120; }避免误杀合法长传 -
必须配合
tcp_nodelay on;:禁用 Nagle 算法,防止小包攒批发送导致“看似卡顿”,让超时判断更准确
让超时真正生效的配套配置
-
reset_timedout_connection on;:超时后发 RST 包,而不是优雅 FIN,快速回收 socket 和文件句柄,避免堆积在TIME_WAIT -
keepalive_timeout 15s;:缩短空闲长连接存活时间,减少被复用为慢速通道的可能性 -
sendfile off;或aio on;(视内核和磁盘类型而定):sendfile在某些低速客户端场景下会阻塞 worker,关闭后改用用户态 buffer + 异步 IO 更可控
如何验证是否起作用
- 错误日志中出现
[error] ... client timed out (110: Connection timed out) while sending response to client - 对应请求返回
HTTP 499(注意:这是 Nginx 自定义状态码,表示服务端主动关闭连接,不是客户端断开) - 用
ss -tn state established | wc -l对比调参前后 ESTABLISHED 连接数变化趋势,尤其在模拟慢速接收(如tc netem delay 3000ms loss 10%)时观察回落速度
不复杂但容易忽略。

















