map指令不能直接启停upstream节点,仅能根据变量选择预定义的upstream块;需提前配置full_cluster、degraded_cluster、maintenance_cluster等不同可用性集群,再通过map动态路由。

map 指令本身不能直接开启或关闭 upstream 中的某个节点,它不参与健康检查、权重调整或节点启停逻辑。它的作用是“选集群”,而不是“调节点”。所谓“动态开启或关闭轮询节点”,实际应理解为:根据运行时条件(如请求头、参数、IP 等),将请求路由到**预定义的不同 upstream 块**——其中某些 upstream 块可能只包含活跃节点,另一些则刻意剔除或仅保留备用节点。
用 map 切换不同可用性的 upstream 块
本质是把“节点开关”提前配置成多个 upstream 定义,再用 map 选中对应块:
- 定义一个 full_cluster,含全部后端节点(正常轮询)
- 定义一个 degraded_cluster,只保留 1–2 个稳定节点(降级模式)
- 定义一个 maintenance_cluster,仅含维护页服务或返回 503(全关闭等效)
- 用 map 根据 $arg_mode、$http_x_maintenance 或 $time_iso8601 等变量决定使用哪个 upstream 名称
按维护状态动态路由示例
以下配置实现:带 mode=maint 参数时走维护集群,否则走完整集群:
http {
map $arg_mode $upstream_backend {
default full_cluster;
maint maintenance_cluster;
}
<p>upstream full_cluster {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080;
}</p><p>upstream maintenance_cluster {
server 127.0.0.1:8081; # 返回维护页的本地服务
}</p><p>server {
location / {
proxy_pass <a href="https://www.php.cn/link/417dedd041fefe5dbdea9cd22d424d86">https://www.php.cn/link/417dedd041fefe5dbdea9cd22d424d86</a>;
}
}
}</p>
结合时间或 Header 实现灰度开关
例如在凌晨自动切降级集群,或通过自定义 Header 临时关闭某节点组:
- 用 $time_hour 匹配时段:
~^(0[0-6]|2[2-3])$→ 选 degraded_cluster - 用 $http_x_feature_flag 控制:
"off" maintenance_cluster,其他值走 full_cluster - 注意:所有 upstream 名称必须与 map 输出值完全一致,大小写敏感
为什么不建议在 map 里控制单个节点启停
upstream 节点的启用/禁用需靠 down、backup、max_fails 等指令,在 upstream 块内静态声明。map 是请求级变量映射,无法修改 upstream 运行时结构。强行用 map 拼接 IP+端口(如 http://$backend_ip:$backend_port)虽可行,但失去健康检查、连接复用和负载均衡能力,仅适合极简透传场景。











