使用$server_name作为key定义limit_conn_zone可实现按域名站点的全局并发连接限制,安全可靠且天然适配多租户场景;需在http块中定义共享内存区,server块中启用limit_conn,并可叠加per-ip限流与语义化状态码提升防护与可观测性。

用 $server_name 作为 key 定义 limit_conn_zone,再在对应 server 块中调用 limit_conn,就能实现对单个虚拟主机(即某个域名站点)的全局总并发连接数限制。这不是按 IP、不是按路径,而是把整个站点当作一个整体来统一分配连接资源,天然适配多租户、多业务共存的场景。
在 http 块中定义基于域名的共享内存区
这一步必须放在 http{} 最外层,不能嵌套在 server 或 location 内:
-
limit_conn_zone $server_name zone=per_server:10m;—— 使用 Nginx 内置变量$server_name为键,确保 key 来自配置而非客户端输入,安全可靠 -
$server_name的值取自当前匹配的server_name example.com;指令中的第一个域名,不依赖 Host 头,不会被篡改 -
zone=per_server:10m表示开辟 10MB 共享内存,足够记录数万个不同域名的状态,单站点部署下绰绰有余
在 server 块中启用硬性连接上限
把限制加在具体站点的 server{} 块一级,对所有进该站点的流量生效:
-
limit_conn per_server 300;—— 表示该域名下所有客户端连接加总,最多维持 300 个活跃 TCP 连接 - HTTP/2 单连接复用多个请求,仍只计为 1;keepalive 空闲连接也持续占用配额,建议同步设置
keepalive_timeout 15; - 超出立即返回
503 Service Temporarily Unavailable,不排队、不延迟,资源释放及时
搭配 per-IP 限流形成双层防护
仅靠站点级总量控制不够精细,容易被单个恶意 IP 耗尽全部额度:
- 在
http{}中补充:limit_conn_zone $binary_remote_addr zone=per_ip:10m; - 在同一
server{}块中追加:limit_conn per_ip 15;—— 单 IP 最多占 15 个连接 - 两者并存时,Nginx 会同时检查两个限制,任一触发即拒绝,兼顾公平性与防攻击能力
提升行为可观察性与语义准确性
让限流不只是“静默拦截”,而是便于监控、告警和前端识别:
-
limit_conn_log_level error;—— 把限流日志提至 error 级,避免 warn 日志刷屏,方便快速定位异常流量 -
limit_conn_status 429;—— 返回429 Too Many Requests,比默认 503 更符合限流语义,前端可针对性重试或降级 - 验证是否生效:用
hey -c 400 -n 1000 http://example.com/压测,直接查error.log是否出现limiting connections by zone "per_server"










