server_name指令不解析DNS,仅匹配HTTP请求头Host字段以决定处理请求的server块;支持正则表达式(最高优先级)、通配符(次之)、精确匹配(最低但常用)三种方式,按序匹配且命中即止。

server_name 指令本身不解析 DNS,而是匹配客户端 HTTP 请求头中的 Host 字段,从而决定由哪个 server 块处理该请求。这是 Nginx 实现域名级流量分发的核心机制,关键在于匹配逻辑清晰、优先级明确、配置可扩展。
匹配模式与优先级必须理清
server_name 支持三种匹配方式,Nginx 按固定顺序尝试匹配,一旦命中即停止:
-
正则表达式(以 ~ 或 ~* 开头):最高优先级,适合动态子域名捕获,如
server_name ~^(?<sub>.+)\.example\.com$;</sub> -
通配符(以 * 开头或结尾):次优先级,例如
*.example.com匹配所有二级子域,www.*.com不合法(仅支持左或右通配) -
精确匹配:最低优先级但最常用,如
server_name en.example.com;,完全一致才生效
单 server 块 + map 指令适合多语言或多租户场景
当子域名数量较多(如支持 15 种语言),为每个域名写独立 server 块会导致配置冗余。推荐用 map 提前将 Host 映射为变量,在统一 server 中复用:
- map 必须定义在 http 块顶层,不能嵌套在 server 内
- 示例:
map $host $lang_root { default "/var/www/default"; zh.example.com "/var/www/zh"; en.example.com "/var/www/en"; } - 后续 server 块中直接使用
root $lang_root;,配合 try_files 即可完成目录分发
泛域名分发需配合 DNS 与证书协同生效
仅靠 server_name 配置无法让泛域名真正可用,还需两个前提:
-
DNS 泛解析:在域名管理后台设置
*.example.com → A 记录 → 服务器 IP,否则请求根本到不了 Nginx -
HTTPS 泛域名证书:若启用 HTTPS,证书必须覆盖
*.example.com,否则浏览器会报安全警告;Let’s Encrypt 支持通配符证书,但需通过 DNS-01 验证 - 正则捕获的子域名变量(如
$sub)可直接用于 proxy_pass,实现“user.example.com → 后端 user-service”类路由
避免常见陷阱
实际部署中最容易忽略的几个细节:
- 未配置
listen 443 ssl时,HTTPS 请求会被 80 端口 server 块拒绝,导致空白页或连接重置 - 多个 server 块监听相同端口但 server_name 有重叠时,Nginx 会按配置文件顺序取第一个匹配项,而非最优匹配
- Host 头为空或非法时(如直接用 IP 访问),默认由第一个 listen 相同端口的 server 块响应,建议设一个兜底 server 块返回 444 或跳转
- root 路径末尾不要加斜杠,Nginx 会自动拼接;alias 则必须注意末尾斜杠规则,二者行为不同

















