使用 $server_name 是为按域名维度限流,$binary_remote_addr 则用于单IP限流;前者实现每域名最多N并发,适合多租户场景,需在http块定义zone,配合limit_conn指令生效。

可以使用 limit_conn_zone 指令配合 $server_name 变量,为每个虚拟主机(即每个 server 块对应的域名)单独设置连接数限制,实现按域名维度的全局连接限流。
为什么用 $server_name 而不是 $binary_remote_addr
$binary_remote_addr 用于限制单个客户端 IP 的并发连接数,而 $server_name 是当前请求匹配的虚拟主机名(如 api.example.com 或 www.example.com),它代表服务维度。两者结合可实现“每域名最多 N 个并发连接”的策略,适合多租户、多站点共用同一 Nginx 实例的场景。
注意:$server_name 的值来源于请求中的 Host 头或 server 块的 server_name 指令,前提是该请求能成功路由到对应 server 块。若 Host 不匹配或未定义 server_name,可能取空值或默认服务器名,需确保配置严谨。
基本配置写法
在 http 块中定义共享内存区域:
limit_conn_zone $server_name zone=per_server:10m;
该配置表示:以 $server_name 为 key,创建名为 per_server 的共享内存区,大小为 10MB,足够存储数万个不同域名的计数器。
然后在需要限流的 server 或 location 块中启用:
limit_conn per_server 100;
表示:每个唯一 $server_name 最多允许 100 个并发连接(包括 keepalive 连接)。
实际使用注意事项
- 必须放在 http 块顶层定义 zone,不能在 server 或 location 内定义;limit_conn 指令则可放在 http / server / location 中,作用域决定生效范围。
-
多个 server 共享同一个 zone,Nginx 会自动按
$server_name值做哈希分桶统计,互不影响。 -
不区分 HTTP/HTTPS 或端口,只要
Host头一致(且被正确路由),就计入同一计数器。例如example.com:80和example.com:443若共用同一server_name,则共享连接限额。 -
配合 log_format 可记录触发限流的域名,便于排查:在日志格式中加入
$server_name,并留意错误日志中limiting connections by zone提示。
进阶:与 IP 限流叠加使用
常见做法是分层控制:先限制单 IP 并发(防爬),再限制整站并发(保稳定性)。例如:
limit_conn_zone $binary_remote_addr zone=per_ip:10m;
limit_conn_zone $server_name zone=per_server:10m;
<p>server {
server_name api.example.com;
limit_conn per_ip 10; # 单 IP 最多 10 连接
limit_conn per_server 500; # 整个 api.example.com 最多 500 连接
}此时两个 limit_conn 规则同时生效,任一触发都会拒绝新连接(返回 503),Nginx 按配置顺序检查,但最终效果是“与”关系。


















