在 nginx 中设置过长的 proxy_read_timeout 会显著增加服务器被慢速连接攻击(slowloris)或资源耗尽的风险,导致正常请求因无法获取空闲连接而排队甚至失败。要规避这一隐患,必须将超时时间限制在合理的业务范围内,并配合 client_body_timeout 和 keepalive_timeout 共同收紧连接生命周期,确保异常客户端无法长期占用后端资源。

为什么长超时会导致连接池耗尽
当 proxy_read_timeout 设置过长时,如果上游应用响应缓慢或恶意客户端故意发送极慢的数据流,Nginx 会维持与该客户端的 TCP 连接以及到后端的连接长达数分钟甚至更久。这直接占用了 Nginx 的文件描述符和内存资源,导致新的合法请求无法建立连接,引发服务拒绝。

server {
listen 80;
server_name example.com;
# 关键配置:缩短读取超时,防止慢速攻击
proxy_read_timeout 30s;
client_body_timeout 10s;
keepalive_timeout 15s;
location / {
proxy_pass http://backend_app;
proxy_connect_timeout 5s;
}
}
上述配置将读取超时限制为 30 秒,客户端主体超时为 10 秒。若客户端在 10 秒内未发送完整请求体,连接立即断开;若后端在 30 秒内未返回数据,Nginx 也会切断连接。这种组合策略能有效抵御大多数慢速连接攻击,同时保证正常业务在合理时间内获得响应。
如何验证超时生效与资源释放
通过模拟慢速请求并观察 Nginx 错误日志及连接状态,可以验证超时机制是否按预期工作。使用 curl 发送部分请求头后挂起,若 Nginx 在设定时间内主动关闭连接,则说明配置生效。

# 测试脚本:模拟慢速客户端
while true; do
curl -s -o /dev/null -H "X-Slow: test" http://example.com/ &
sleep 5
done
# 监控命令:查看当前活跃连接数
watch -n 1 'ss -tan | grep ESTAB | wc -l'
运行测试脚本后,若发现活跃连接数未持续攀升且在 10-30 秒后回落,表明超时机制正在清理僵尸连接。同时检查
proxy_read_timeout
设置为 300 秒(5 分钟),在并发量中等的环境中,恶意客户端只需发起几十个慢速请求即可耗尽服务器的连接池。例如,每个连接占用约 4KB 内存,100 个慢速连接即消耗 400KB,看似不多,但结合文件描述符限制和上下文切换开销,实际影响呈指数级放大。此时,正常用户访问网站会出现间歇性 502 或 504 错误,因为 Nginx 无法为新请求分配后端连接。











