现场是这样的。一台 nginx 1.22 上跑二十多个站点,用 map 根据 Host 把请求分发到不同的 upstream,加了新域名后所有访问都进了第一个站,日志里 $backend 变量一直是 default。

中间走过弯路,把「default 项写在了 map 的第一行,后面的匹配被短路」当成主因,改完现象没变。

真正麻烦的地方在于,几个原因的现象几乎一样。map 块写在 http 之外,变量根本没被解析;map 的 key 用了 $host 但请求里带端口,匹配不到;include 的顺序让后面的 conf 覆盖了同名变量。

上来先确认变量有没有被赋值

grep -rn -B2 -A6 'map ' /etc/nginx/

随后把变量打进日志看实际匹配到的值

tail -5 /var/log/nginx/access.log

然后把 map 移进 http 块并调整默认项位置

nginx -T | grep -n -A8 'map '

剩下的就是配置检查通过后重载

nginx -t && nginx -s reload

别只看报错消失,验证要多做一步。访问不同域名时 access_log 里的 backend 分别是各自的值,页面内容不再串站。

补一句。map 的变量名不要和内置变量重名,default 要放在最后一行;调试时把变量打进日志比反复改配置快得多。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189