Nginx平滑重载后泛解析失效,主因是哈希桶溢出、精确匹配优先、配置未加载或default_server干扰;需用nginx -T验证配置、调大server_names_hash_bucket_size、检查匹配顺序与Host头测试。

平滑重载(nginx -s reload)后虚拟主机泛解析(如 server_name *.example.com)突然失效,不是配置丢了,而是 Nginx 在重载过程中对通配符和正则的匹配逻辑被隐式降级或覆盖——尤其当多个 server 块共存、哈希桶不足、或存在更“具体”的匹配项时,泛解析会静默退场。
确认泛解析是否真被加载
运行 nginx -T(注意是大写 T),输出全部生效配置,然后搜索你的泛解析行:
-
nginx -T | grep "server_name.*\*\.example\.com"—— 看是否出现在最终合并配置中 - 若没出现,说明该配置未被 include 进来,检查
sites-enabled/下软链是否有效、文件权限是否允许读取 - 若出现但位置靠后,且前面有
server_name example.com或www.example.com等精确匹配块,Nginx 会优先选精确项,泛解析永不命中
检查 server_names_hash 是否溢出
泛解析依赖哈希查找,若域名数量多或通配符过长,哈希桶装不下就会回退为线性扫描,而 Nginx 默认禁用线性匹配泛解析(避免性能坍塌),直接跳过该 server 块:
- 错误日志中可能出现:
could not build the server_names_hash, you should increase server_names_hash_bucket_size - 在
http块顶部添加:server_names_hash_bucket_size 128;(根据域名长度逐步调大到 256 或 512) - 同时检查
server_names_hash_max_size,千级域名建议设为4096
验证泛解析的实际匹配行为
Nginx 对 *.example.com 的匹配有严格限制:只匹配一级子域(如 api.example.com),不匹配 dev.api.example.com 或纯 example.com:
- 测试请求必须带 Host 头,例如:
curl -H "Host: test.example.com" http://your-ip/ - 若想支持多级子域,不能用通配符,改用正则:
server_name ~^(?<subdomain>.+)\.example\.com$;</subdomain>,并确保http块启用perl_set或使用map提前处理 - 注意:正则匹配比通配符慢,且每次请求都编译,大规模场景慎用
排除 default_server 干扰
泛解析块若未设 default_server,又排在其他 server 块之后,Nginx 可能将所有未明确匹配的请求(包括泛解析本应承接的)交给第一个监听同端口的 server 块:
- 执行:
nginx -T | grep "listen.*80" -A 3 | grep -E "(server_name|default_server)" - 确认你的泛解析块是否带
default_server;若不想设为默认,至少保证它在include列表中字母序最前(如命名为00-wildcard.conf) - 临时加
default_server测试是否恢复,可快速定位是否被兜底劫持


















