Nginx 报 "conflicting server name" ignored 怎么解决?
Nginx conflicting server name 警告的含义:多个 server 块声明了相同 server_name,Nginx 只用第一个;用 grep 定位重复项、合并或删除、include 顺序坑与 FAQ。
这个警告表示:有多个 server 块声明了相同的 server_name,Nginx 按加载顺序只用第一个,其余被"ignored"。 它不会阻止启动,但被忽略的 server 块里配置的站点永远收不到流量——必须清理重复。
定位重复的 server_name
# 全局列出所有 server_name 声明
grep -rn "server_name" /etc/nginx/
# 或直接统计重复项
grep -rh "server_name" /etc/nginx/ | tr ' ' '\n' | \
grep -v '^server_name$\|^;\|^$' | sort | uniq -d
uniq -d 输出的就是撞车的域名。
常见成因与修法
成因 1:同一站点配置了两遍
sites-enabled 里同时软链了 default 和自己写的配置,或复制配置忘了改域名:
ls -l /etc/nginx/sites-enabled/
# default -> /etc/nginx/sites-available/default
# mysite -> /etc/nginx/sites-available/mysite ← 两个都写了 server_name example.com
修法:删掉多余的那个软链/文件,或把两份配置合并成一个 server 块。
成因 2:include 顺序导致"第一个"不是你要的那个
Nginx 按 include 的文件顺序加载,先出现的 server_name 赢。如果 conf.d 下 00-old.conf 和 mysite.conf 都声明了 example.com,生效的是前者。
修法:让域名只出现一次;确实需要按序覆盖时,用文件名前缀(00-、90-)显式控制加载顺序,但这很脆,不建议当设计用。
成因 3:HTTP 和 HTTPS 各写了一份但其中一个忘了 listen 443
这是合法场景:HTTP 和 HTTPS 两个 server 块用同一个域名是正常且必要的——只要它们的 listen 不同:
server { listen 80; server_name example.com; return 301 https://$host$request_uri; }
server { listen 443 ssl; server_name example.com; ... }
⚠️ 但如果两个块都 listen 80 还同名,就会触发这个警告。
验证修复
nginx -t # 警告应消失
nginx -T | grep -B2 'server_name example.com' # 确认只剩预期的那几处
观测云对照
这类"配置静默失效"的问题最难发现——Nginx 正常跑,流量却去了错的 server 块(比如打到了默认站点)。把访问日志接入观测云后按 $host 聚合分析,哪个域名实际命中了哪类响应一目了然;error.log 里的启动警告采集后设关键字告警,下次再出现 conflicting 直接通知到人,而不是等下次排障才翻到。
常见问题(FAQ)
Q:这个警告会让 Nginx 启动失败吗?
A:不会,它是 warn 级。但"被忽略"的 server 块形同虚设,其站点流量会被第一个同名块(或默认 server)接管,实际效果可能是线上事故。
Q:一个域名可以出现在多个 server 块里吗?
A:可以,前提是 listen 不同(80 vs 443)或 listen 的 IP/端口组合不同。同样的 listen + 同样的 server_name 才是冲突。
Q:默认 server(default_server)和冲突有关吗?
A:无关但容易混淆:没匹配到任何 server_name 时请求落到该 listen 地址的第一个(或标记 default_server 的)块。排查"流量去了不该去的站点"时两个机制都要看。