Nginx server_name 本身开销小,但大量域名(尤其混用通配符、正则)会增加匹配开销;优化应聚焦降低复杂度、避免回溯、提升缓存命中率,包括精简域名列表、慎用正则、利用匹配优先级、启用 server_names_hash 防哈希冲突。

Nginx 的 server_name 本身不直接消耗显著 CPU 或内存,但当配置中存在大量域名(尤其混用通配符、正则)时,匹配过程会带来可测的性能开销。优化重点不是“加速单次匹配”,而是减少匹配复杂度、避免回溯、提升缓存命中率。以下是实用、可落地的优化方向:
精简域名列表,合并同类项
多个相似域名尽量用一条规则覆盖,避免逐个罗列:
- ❌ 不推荐:写满 50 个子域名:
server_name a.example.com b.example.com c.example.com ...; - ✅ 推荐用前导通配符:
server_name *.example.com;(匹配所有二级子域名,不含 example.com 本身) - ✅ 若需包含主域,加一条精确匹配:
server_name example.com *.example.com; - ⚠️ 注意:通配符不能写成
*.com或www.*.example.com——Nginx 不支持多级或后缀通配符
慎用正则表达式,优先用静态/通配符匹配
正则匹配是线性扫描+回溯的,性能最差,且每次请求都执行。仅在必须提取变量(如子域名路由)时使用:
- ❌ 避免:
server_name ~^(?<sub>.+)\.example\.com$;</sub>用于简单分流(如只有 3–5 个固定子域) - ✅ 替代方案:显式列出高频子域 + 通配符兜底:
server_name www.example.com api.example.com *.example.com; - ✅ 必须用正则时,加上
^和$锚定,避免隐式 .* 回溯;用非捕获组(?:...)减少开销
利用 Nginx 域名匹配优先级,控制顺序
Nginx 按「精确 → 前导通配符 → 正则」顺序匹配,越靠前越快。把流量最大的域名放在最前面:
- 例如主站访问量占 80%,应放在
server_name列表首位:server_name example.com www.example.com shop.example.com; - 若使用多个
server块,把高流量域名的server块写在配置文件靠前位置(Nginx 从上到下扫描 server 块)
启用 server_name_hash,防哈希冲突
当域名数量超百、字符较长时,Nginx 默认哈希桶大小可能不足,导致链表退化为线性查找:
- 检查是否触发警告:
nginx -t若提示could not build the server_names_hash,说明需调大 - 在
http块中添加:server_names_hash_max_size 512;(默认 512,按需设为 1024/2048) - 同时建议设:
server_names_hash_bucket_size 128;(默认 64,长域名建议翻倍) - ⚠️ 注意:这两个值必须是 2 的幂;增大后会略微增加内存占用,但能避免 O(n) 匹配退化
不复杂但容易忽略。



















