limit_conn_zone必须定义在http{}块顶层,否则nginx启动报错“unknown limit_conn_zone”并拒绝加载配置;它与limit_conn缺一不可,前者定义共享内存区存储ip连接状态,后者执行计数查询,单独使用limit_conn无效。

limit_conn_zone 必须定义在 http{} 块顶层
否则 Nginx 启动直接报错:unknown limit_conn_zone "perip",配置完全不加载。这不是语法警告,是硬性校验失败。
正确写法只能是:
http {
limit_conn_zone $binary_remote_addr zone=perip:10m;
# 其他配置...
}
-
$binary_remote_addr比$remote_addr更可靠:前者是固定 4 字节(IPv4)或 16 字节(IPv6)二进制格式,哈希稳定、内存占用小;后者是字符串,可能含空格或换行,导致键错乱 -
10m不是随便写的:1MB 约存 1.6 万个 IP 记录,10MB ≈ 支持 16 万独立 IP;若业务 DAU 超 50 万,建议设为20m或更高 - 不能套在
server或location里——哪怕只差一层缩进,Nginx 就认不出来
limit_conn 单独写在 location 里没用
limit_conn 只是“执行指令”,它本身不存状态、不计数,只负责查 limit_conn_zone 里某个 IP 当前连了多少个。缺了 zone,它就是个空操作,不报错也不生效。
常见失效场景:
- 只在
location /api里写了limit_conn perip 5,但忘了在http{}里定义limit_conn_zone - 把
limit_conn_zone错写在server{}块里,启动失败 - 用了 CDN(如 Cloudflare),
$binary_remote_addr拿到的是节点 IP,不是真实用户 IP,结果全站限流都作用在几个 CDN 节点上
补救方法:加 set_real_ip_from + real_ip_header X-Forwarded-For,再改用 $realip_remote_addr 或清洗后的 $http_x_forwarded_for。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
limit_conn perip 5 到底限制什么
它限制的是「已建立、尚未关闭的 TCP 连接数」,不是请求数,也不是每秒请求数。这点非常容易误解。
- HTTP/1.1 keepalive:一个浏览器标签页维持一个长连接,算 1 个
- WebSocket / SSE / 长轮询:只要底层 TCP 连接没断,就算 1 个
- HTTP/2:单个 TCP 连接可复用上百个 stream,
limit_conn perip 5只卡住 5 个连接,但实际请求压力可能翻几十倍——此时必须叠加limit_req从速率维度兜底 - 大文件下载、慢速读取响应体,会让连接长期处于“未关闭”状态,极易触发限制
超限时默认返回 503 Service Temporarily Unavailable,但错误日志不记录——得显式加 limit_conn_log_level warn 和 limit_conn_status 429 才能准确定位和前端友好处理。
和 allow/deny 白名单混用时的坑
allow/deny 是访问控制,limit_conn 是连接限流,两者触发阶段不同,不能互相跳过。
-
allow 192.168.1.100; deny all;写在location /admin里,只对那个路径生效;但limit_conn perip 3如果写在server{}顶层,就对全站生效——它们作用域可能不一致 - 如果同时启用了
auth_basic,allow/deny在认证之后才执行,而limit_conn在更早阶段就已拦截连接,所以被限流的用户根本不会走到鉴权环节 - 想让白名单 IP 绕过限流?不能靠
if ($remote_addr = ...),因为limit_conn在 rewrite 阶段前就已执行;正确做法是用map构造动态 key,比如对白名单 IP 使用不同 zone 名
真实部署中,最常被忽略的是代理链路下的 IP 识别逻辑和 HTTP/2 协议对连接复用的影响——这两点不处理,限流策略基本形同虚设。










