limit_conn单独无效,因必须先在http块中用limit_conn_zone声明共享内存区(如$binary_remote_addr zone=perip:10m)以存储连接状态,否则无计数载体,配置静默失效。

直接限制单个 IP 的并发连接数,用 limit_conn 就行,但必须配合 limit_conn_zone 定义共享内存区域,否则配置无效。
为什么 limit_conn 单独写没用
Nginx 的连接限制不是靠“开关”控制的,它依赖一个运行时状态存储区。这个区域得提前在 http 块里用 limit_conn_zone 声明,否则 limit_conn 找不到状态载体,会静默忽略——你 reload 配置不报错,但压根不生效。
-
limit_conn_zone $binary_remote_addr zone=perip:10m;是必需前置项,$binary_remote_addr比$remote_addr更省内存,推荐始终用它 -
zone=perip:10m中的10m不是随便写的:每条连接记录约 32 字节,10MB 约支持 30 万 IP 的并发状态;小流量站点 5m 够用,高防场景建议 20m - 该指令只能出现在
http上下文,不能塞进server或location里
limit_conn 放在哪一级才真正起作用
位置决定作用域。放在 http 块,全局生效;放在 server 块,只限该虚拟主机;放在 location 块(如 /api),仅对该路径生效。但要注意:limit_conn 对 HTTP 连接计数,不是对请求计数——长连接(Keep-Alive)期间多个请求只算 1 个连接。
- 防恶意刷流量,重点保护后端 API 或登录入口,建议放在
location /api或location /login下 - 若放在
server块,静态资源(CSS/JS/图片)也会被计入,可能误伤正常用户,不推荐 - 值设多少合理?参考真实业务:普通 Web 页面一般
limit_conn perip 10足够;API 服务可设为5–20;后台管理接口建议3–5
怎么让被拒绝的连接返回 429 而不是默认 503
默认情况下,超限连接直接返回 503 Service Temporarily Unavailable,但 429 更语义明确,也方便前端做重试判断。改状态码只需一行:limit_conn_status 429;,但它有作用域限制。
立即学习“PHP免费学习笔记(深入)”;
- 该指令在
http、server、location三级都有效,优先级从低到高:http - 如果只想对某个 API 接口返回 429,就把它和
limit_conn写在同一location块里 - 注意:Nginx 1.13.6+ 才完全支持
429,旧版本(如某些 phpEnv 自带的 1.12.x)可能 fallback 到 503
phpEnv 环境下容易漏掉的关键点
phpEnv 是集成包,Nginx 配置常被拆成多个 include 文件(如 vhost/xxx.conf、conf/nginx.conf)。直接在 vhost 文件里加 limit_conn_zone 会报错,因为它不在 http 块里。
- 必须找到主配置文件中
http { ... }区域,在include mime.types;后面或include vhost/*.conf;前插入limit_conn_zone行 - phpEnv 默认可能启用了
gzip和keepalive_timeout,长连接保持时间过长(如 65s)会让单个 IP 的连接数“滞留”更久,建议调低到keepalive_timeout 15; - 测试是否生效:用
ab -n 100 -c 50 http://yoursite/api/test压测,再查 Nginx 错误日志里有没有limiting connections by zone记录
真正难的不是写这三行指令,而是确认 limit_conn_zone 在正确的作用域声明、limit_conn 落在精确的路径上、且整个链路没有被其他模块(比如 Lua 脚本或第三方限流模块)覆盖或绕过。



















