直接限制单个ip并发连接数是防御高频恶意爬虫最基础、见效最快的方式,nginx通过limit_conn在tcp握手后、响应前统计并控制活跃连接,配合limit_req实现连接数与请求速率双限流。

直接限制单个 IP 的并发连接数,是防御高频恶意爬虫最基础、见效最快的方式。它不等请求发完、不占后端线程,而是在连接建立初期就拦截——只要 TCP 已握手、HTTP 请求头已读完、响应还没发完,就算一个“活跃连接”,Nginx 就会统计并控制。
按 IP 限连:防连接耗尽的底线手段
爬虫常开大量短连接刷接口,迅速挤爆服务器连接池。用 limit_conn 可精准掐住这一环节:
- 在
http块中定义状态区:limit_conn_zone $binary_remote_addr zone=perip:10m;(用二进制 IP 更省内存,10MB 约支持 16 万个 IP) - 在目标
location(如/api/或/search)中启用:limit_conn perip 3;(表示每个 IP 最多维持 3 个活跃连接) - 搭配
limit_conn_status 429;返回标准状态码,方便前端或监控识别
按 User-Agent 限连:绕过 IP 伪装的补充策略
有些爬虫轮换 IP 但 UA 固定(如始终用 python-urllib 或 scrapy),这时单靠 IP 限连效果有限。可结合 map 归类 UA 后限连:
- 在
http块顶部加映射规则,把可疑 UA 统一标记为bot,正常浏览器映射为空(即放行) - 再定义区域:
limit_conn_zone $ua_type zone=ua_conn:10m; - 在 location 中写:
limit_conn ua_conn 2;(所有被标为bot的请求,总共最多 2 个活跃连接) - 注意:UA 可伪造,此策略必须和 IP 限连、请求速率限制配合使用
配合请求速率限制:堵死“少连多刷”绕过方式
仅限连接数,挡不住“只开 1 个连接却每秒发 100 次请求”的行为。必须叠加 limit_req:
- 复用同一 zone 名(如
perip),避免重复开内存:limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s; - 在相同 location 中启用:
limit_req zone=perip burst=5 nodelay;(允许瞬时 15 次请求,超了立刻返回 429) - 这样既控连接数,又控单位时间请求数,双保险防绕过
验证与调优要点
配置不是一劳永逸,需验证是否真生效:
- 用
ab -n 100 -c 10 http://site.com/api/test模拟并发,看是否大量返回 429 或超时 - 观察 Nginx 状态页中
Active connections下的Writing和Waiting数值是否明显堆积 - 日志里加
limit_conn_log_level warn;,快速定位触发限连的 IP 或 UA - 初始阈值建议保守:API 接口先设
limit_conn perip 2–3、rate=5–10r/s,再根据真实流量逐步放宽











