least_conn防御慢连接攻击的核心在于真实反映后端负载,需通过max_conns限流、主动健康检查、合理keepalive及proxy_http_version 1.1等配置协同实现自动绕行与容量拦截。

测试 least_conn 在防御慢连接攻击时的削峰缓冲效果,核心不是看它“能不能分发”,而是验证它能否在连接被恶意拖长、后端连接池被虚假占满的情况下,仍把新请求导向真正可用的节点,并避免调度逻辑被失真的连接数误导。
构造可控的慢连接攻击场景
真实慢连接攻击(如 Slowloris)会让连接长期处于半开状态,但 Nginx 默认不感知这类连接是否“有效”。必须主动模拟并隔离变量:
- 用 mock 服务 模拟两类后端:一台正常响应(sleep 50ms),另一台故意延迟响应头(如 hold connection 15s 后才发 HTTP 200)——这比直接断连更能触发 least_conn 的“连接数堆积”问题
- 关闭后端所有缓存与异步逻辑,确保延迟完全由连接维持行为导致,而非业务耗时
- Nginx 侧禁用
proxy_buffering off和proxy_cache,防止缓冲掩盖连接阻塞;开启stub_status实时查Active connections
压测中重点观测三类指标变化
单纯看 QPS 或错误率会掩盖调度失效。需交叉比对:
- 各后端活跃连接数分布趋势:攻击发起后,慢节点连接数是否快速升至高位(如从 5 → 180),而健康节点是否维持在低位(如 3–8)。若两者趋近(比如都卡在 40–60),说明 least_conn 已被“假连接”污染,失去削峰能力
-
新建连接速率 vs 复用连接数:通过
ss -s | grep 'estab'对比 Nginx 统计的Active connections。若 Nginx 显示连接数低但系统级 ESTAB 连接暴增,说明 keepalive 失效,短连接泛滥,least_conn 退化 -
请求重试行为是否生效:配置
proxy_next_upstream error timeout http_504+proxy_read_timeout 8s,观察 slow 节点上的超时请求数是否上升、重试是否成功落到健康节点(查 access.log 中$upstream_addr字段)
验证削峰缓冲是否真正起效
关键看 least_conn 是否在连接层实现了“自动绕行+容量拦截”双重保护:
- 为慢节点显式设置
max_conns=50,健康节点设max_conns=500。攻击流量达到 300 RPS 时,检查慢节点是否被稳定跳过(Nginx 日志中该地址出现频次骤降),且健康节点连接数未突破其max_conns - 启用主动健康检查:
health_check interval=3 fails=2 passes=2 match=status_ok;,并让 mock 服务在慢响应时返回非 2xx 状态码或缺失X-Status: ok头。观察节点被标记为 down 的时间是否 ≤ 6 秒(2×3s),是否明显快于仅靠proxy_next_upstream的被动摘除 - 对比 baseline:相同攻击下,换用
round-robin,看慢节点错误率是否飙升、整体 P95 延迟是否突增 3 倍以上。least_conn 的削峰价值就体现在这个差距里
配置必须同步加固,否则测试无意义
以下四项是 least_conn 抵御慢连接攻击的前提,缺一不可:
-
upstream 内必须有
keepalive 32:防止每个慢请求都建新连接,放大连接数失真 -
location 中必须设
proxy_http_version 1.1和proxy_set_header Connection '':强制复用,避免后端误关连接 -
每个 server 行必须带
max_fails=2 fail_timeout=10s:配合proxy_next_upstream timeout快速剔除已卡死节点 -
禁用
ip_hash、hash等互斥策略:least_conn 必须独占 upstream 块,否则调度逻辑混乱











