Nginx连接限流需三步:一是在http块用$binary_remote_addr定义共享内存区(如zone=perip:10m);二在server或location中用limit_conn perip N启用,以较小值为准;三在代理环境下改用$realip_remote_addr并配置real_ip_module。

直接在 Nginx 的 http 块中定义共享内存区域,再在 server 或 location 中启用限制,就能生效。它统计的是当前活跃的 TCP 连接数(含 keepalive、HTTP/2 多路复用),不是请求数。
第一步:在 http 块中定义共享内存区域
必须写在 http{...} 里,不能放在 server 或 location 内:
- 使用
$binary_remote_addr作为 key,比$remote_addr更省内存(IPv4 固定 4 字节,IPv6 固定 16 字节) -
zone=perip:10m表示创建名为perip的共享内存区,大小 10MB;约可存储 16 万~32 万个独立 IP 的连接状态 - 如果日志中出现
limit_conn: cannot add connection,说明内存不足,需调大 size(如20m)
第二步:在 server 或 location 中启用限制
引用上面定义的 zone 名,并设定每个 IP 最大并发连接数:
- 整个站点限制:在
server块中加limit_conn perip 10; - 仅限某路径:比如只对 API 接口限流,写在
location /api/ { limit_conn perip 5; } - 若
server和location都配置了limit_conn,以数值更小的那个为准
第三步:代理环境要识别真实 IP
如果 Nginx 前有 CDN、SLB 或 WAF,$binary_remote_addr 默认是代理节点 IP,需配合 real_ip_module:
- 确保已加载
http_realip_module - 配置
set_real_ip_from指定可信上游地址段 - 改用
$realip_remote_addr作为 key(推荐),或从$http_x_forwarded_for提取第一个非空 IP 并去空格
增强实用性与可观测性(推荐补充)
让限流更可控、更容易排查问题:
-
limit_conn_log_level error;:把超限日志设为 error 级,避免刷屏 -
limit_conn_status 429;:返回 429 Too Many Requests,语义比默认 503 更明确 -
limit_rate 200k;:对已放行的连接限速,防止单连接持续占带宽 -
keepalive_timeout 15;:及时释放空闲长连接,避免无效占用配额


















