limit_conn限制单个IP并发连接数可有效防御恶意爬虫,需在http块定义limit_conn_zone区域(如$binary_remote_addr zone=perip:10m),再在location中用limit_conn perip 3启用,仅统计已读取请求头且未完成响应的活跃TCP连接,并建议搭配limit_conn_log_level、limit_conn_status和limit_req实现多层防护。

直接用 limit_conn 限制单个 IP 的并发连接数,是防恶意爬虫最基础也最有效的手段之一。爬虫常通过短连接高频发起请求,大量 TCP 连接会迅速耗尽服务器资源,而 limit_conn 在连接建立初期就拦截,不等它发请求、不占后端处理线程,防御成本低、见效快。
核心配置:定义区域 + 绑定 location
必须分两步写,缺一不可:
- 在
http块中定义连接状态存储区:limit_conn_zone $binary_remote_addr zone=perip:10m;
这里用$binary_remote_addr(4 字节二进制 IP)比$remote_addr更省内存;10m可记录约 16 万个 IP 的连接状态。 - 在具体
location(如/api或/search)中启用限制:limit_conn perip 3;
表示每个 IP 最多维持 3 个**同时活跃的连接**——注意不是请求数,而是“已建立、未关闭”的连接数。
关键细节:什么算“一个连接”?
Nginx 不统计所有 TCP 连接,只计算满足以下条件的连接:
- 已完成三次握手;
- 已完整读取 HTTP 请求头(即能解析出 method、path、host 等);
- 尚未返回响应或响应未完全发送完毕。
这意味着:静态文件下载、长轮询、HTTP/1.1 持久连接都会被计入;而快速失败的连接(如 SYN Flood)、未发完 header 就断开的连接,通常不被统计。
配合使用提升效果
单靠 limit_conn 不够全面,建议搭配:
-
limit_conn_log_level warn;—— 把触发限流的日志级别调高,方便快速发现异常 IP; -
limit_conn_status 429;—— 返回 429 Too Many Requests,比默认 503 更语义化,便于前端或监控识别; -
limit_req zone=perip_req burst=5 nodelay;—— 在同一区域上叠加请求速率限制,双保险防“少量连接+高频请求”的绕过行为。
验证是否生效
用 ab 或 wrk 模拟并发连接测试:
ab -n 100 -c 10 http://your-site.com/api/test
若配置 limit_conn perip 3,你会看到大量请求返回 429 或超时,且 nginx -s reload 后连接数重置,说明状态跟踪正常。也可查 Nginx 状态页:Active connections 下的 Writing 和 Waiting 数值变化趋势,辅助判断连接堆积情况。











