nginx 通过 include 指令将灰度白名单 ip 抽离为独立文件,结合 geo 模块高效映射 $is_gray 变量,并在 location 中按该变量分流至不同 upstream 或静态资源,修改白名单后仅需 nginx -t && nginx -s reload 即可生效。

Nginx 使用 include 指令可以将灰度白名单 IP 规则从主配置中剥离,实现配置解耦和动态维护。核心是把 IP 列表抽成独立文件,用 allow/deny 配合 if 或 geo 模块控制流量路由,避免每次改 IP 都 reload 全局配置。
白名单 IP 单独存为外部文件
在 Nginx 配置目录(如 /etc/nginx/conf.d/)下新建文件,例如 gray-whitelist.conf:
# /etc/nginx/conf.d/gray-whitelist.conf 192.168.1.100; 10.0.5.22; 2001:db8::1;
注意:每行一个 IP 或 CIDR,末尾带分号;支持 IPv4 和 IPv6;该文件仅用于被 include,本身不执行逻辑。
用 geo 模块高效映射白名单状态
直接在 server 或 http 块中 include 并定义灰度标识变量:
geo $is_gray {
default 0;
include /etc/nginx/conf.d/gray-whitelist.conf;
}
geo 比反复写 if ($remote_addr = ...) 更高效,Nginx 启动时加载为哈希表,匹配 O(1);default 0 表示非白名单用户默认不灰度;include 的文件内容会自动转为 192.168.1.100 1; 这类格式。
在 location 中按灰度变量分流
结合 proxy_pass 或 try_files 实现差异化响应:
- 指向不同 upstream(推荐):
location /api/ { if ($is_gray) { proxy_pass http://backend-gray; } proxy_pass http://backend-prod; } - 返回不同静态资源:
location / { if ($is_gray) { root /usr/share/nginx/html-gray; } root /usr/share/nginx/html-prod; }
注意:if 在 location 内可用,但避免在 server 级别滥用;更健壮的方式是用 map 替代 if 做变量映射。
热更新白名单无需 reload Nginx
修改 gray-whitelist.conf 后,只需执行:nginx -t && nginx -s reload
Nginx 会重新读取 include 文件并重建 geo 表。若希望完全免 reload(比如高频变更),可考虑用 lua-resty-iputils + Redis 动态查表,但普通灰度场景没必要。











