Nginx 学习笔记:Server 块配置详解,域名路由与多站点部署实战


📝 本文首发于 栏轩·阁

欢迎访问阅读原文,获取更好的阅读体验。


什么是 Server 块?

在 Nginx 中,Server 块 (也叫做虚拟主机配置)是路由分发的基础单元。Nginx 通过 listen 和 server_name 两个关键参数,决定每个请求该由哪个 Server 块处理,从而实现一台服务器托管多个网站。

可以把 Server 块想象成 Nginx 内部的"虚拟服务器"------每个 Server 块独立配置自己的域名、端口、根目录和路由规则,互不干扰。

一、基础配置:listen + server_name

最基本的 Server 块配置如下:

nginx 复制代码
server {
    listen       80;             # 监听端口
    server_name  localhost;      # 域名匹配

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

listen ------ 监听端口

写法 说明
listen 80; 监听 IPv4 的 80 端口
listen [::]:80; 监听 IPv6 的 80 端口
listen 8080; 监听非标准端口(如 8080)
listen 443 ssl; 监听 HTTPS 端口并启用 SSL
listen 80 default_server; 设为默认服务器,当没有匹配时使用

server_name ------ 域名匹配

server_name 匹配的是请求头中的 Host 字段 。浏览器访问 http://example.com 时,请求头中会携带 Host: example.com,Nginx 拿这个值与所有 Server 块的 server_name 对比,找到对应的处理规则。

可以在浏览器开发者工具 → 网络面板中查看每个请求的 Host 请求头。

二、请求路由流程

当一个请求到达 Nginx 时,匹配顺序如下:

复制代码
客户端请求 ──→ 根据 listen 端口找到 Server 块列表
                       │
                       ▼
               根据 server_name 匹配 Host 请求头
                       │
            ┌──────────┼──────────┐
            ▼          ▼          ▼
         精确匹配   通配符匹配   正则匹配
                       │
                       ▼
               进入对应的 Server 块
                       │
                       ▼
               继续匹配 location 路由

如果所有 server_name 都没有匹配到,Nginx 会使用该端口上第一个 Server 块(或标记了 default_server 的那个)来处理请求。

三、多域名实战

场景

假设我们有一个 Nginx,想同时托管两个网站:

  • blog.com ------ 博客站点,首页为 blog 页面
  • login.com ------ 登录站点,首页为 login 页面

第一步:修改 hosts 文件

由于本机没有真实的域名解析,需要在本机的 hosts 文件中添加域名映射,把两个域名指向本地:

bash 复制代码
# Windows: C:\Windows\System32\drivers\etc\hosts
# Linux/macOS: /etc/hosts

127.0.0.1  blog.com
127.0.0.1  login.com

修改 hosts 后在 Windows 上需要刷新 DNS 缓存才能生效:

bash 复制代码
ipconfig /flushdns

这样访问 blog.com 和 login.com 就会解析到本机。

第二步:准备站点目录

复制代码
nginx-learning/
├── conf.d/
│   ├── blog.conf          # blog.com 配置
│   └── login.conf         # login.com 配置
├── html/
│   ├── blog/
│   │   └── index.html     # blog 站点首页
│   └── login/
│       └── index.html     # login 站点首页
└── docker-compose.yml

第三步:Nginx 配置

blog.conf:

nginx 复制代码
server {
    listen       80;
    server_name  blog.com;

    location / {
        root   /usr/share/nginx/html/blog;
        index  index.html index.htm;
    }
}

login.conf:

nginx 复制代码
server {
    listen       80;
    server_name  login.com;

    location / {
        root   /usr/share/nginx/html/login;
        index  index.html index.htm;
    }
}

第四步:重载配置

bash 复制代码
# 验证配置是否正确
docker exec nginx-learning nginx -t

# 重载配置(不中断服务)
docker exec nginx-learning nginx -s reload

验证效果

bash 复制代码
curl http://blog.com:8080/   # 返回 blog 站点的页面
curl http://login.com:8080/  # 返回 login 站点的页面

✅ 同一个 Nginx、同一个端口(80),通过不同的域名路由到不同的网站目录,这就是虚拟主机的核心能力。

四、server_name 匹配规则详解

server_name 支持多种匹配方式,灵活应对不同场景:

1. 精确匹配(完全匹配)

nginx 复制代码
server_name  example.com;
server_name  www.example.com;

必须与请求的域名完全一致才匹配。

2. 通配符匹配

* 只能出现在开头或结尾,不能放在中间:

nginx 复制代码
server_name  *.example.com;        # 匹配 www.example.com、api.example.com 等
server_name  mail.*;               # 匹配 mail.example.com、mail.test.com 等
server_name  *.example.*;           # ❌ 错误写法,通配符不能同时出现在开头和结尾

3. 正则匹配(~ 开头)

以 ~ 开头,后面跟正则表达式,提供最灵活的匹配能力:

nginx 复制代码
server_name  ~^www\d+\.example\.com$;  # 匹配 www1.example.com、www2.example.com 等
server_name  ~^(?<subdomain>.+)\.example\.net$;  # 支持捕获变量,可在配置中引用 $subdomain

注意事项:

  • 正则表达式必须以 ~ 开头
  • 正则中的 . 需要转义为 \\.
  • 正则匹配不区分大小写(如果需要区分大小写,使用 ~*)

4. 多域名并列

一个 Server 块可以指定多个域名,用空格隔开:

nginx 复制代码
server_name  example.com  www.example.com  blog.example.com;

5. 特殊值

写法 说明
server_name _; 下划线是常见的无效域名占位符 ,表示匹配任意未定义的域名,通常配合 default_server 使用
server_name ""; 匹配没有 Host 请求头的请求(如 HTTP/1.0 请求)

完整的多站点示例

nginx 复制代码
# 站点 1:主站
server {
    listen       80;
    server_name  example.com  www.example.com;

    location / {
        root   /var/www/main;
    }
}

# 站点 2:API 子域名
server {
    listen       80;
    server_name  api.example.com;

    location / {
        root   /var/www/api;
    }
}

# 站点 3:捕获所有未匹配的域名(兜底)
server {
    listen       80 default_server;
    server_name  _;

    return 444;  # 直接关闭连接,不给任何响应
}

五、server_name 匹配优先级

当多个 Server 块的 server_name 都能匹配同一个域名时,Nginx 按以下优先级只选一个:

优先级 匹配方式 示例
1(最高) 精确匹配 example.com
2 通配符开头 *.example.com
3 通配符结尾 www.*
4(最低) 正则匹配 ~^www\\.\\d+\\.com$

重要 :正则匹配实际上在通配符之后被检查,且 Nginx 会按配置文件中 正则出现的顺序 逐一尝试,匹配到第一个即停止。因此如果有多个正则都可能匹配,注意先后顺序。

六、default_server 的用法

default_server 用于指定某个 Server 块作为默认处理器,当没有其他规则匹配时使用:

nginx 复制代码
server {
    listen       80 default_server;
    server_name  _;

    location / {
        return 404;
    }
}

常见用途:

  • 拦截未绑定的域名 ------ 返回 404 或 444(直接关闭连接)
  • 统一重定向 ------ 将所有未匹配的请求重定向到主站
  • 统一 HTTPS 跳转 ------ 将所有 HTTP 请求跳转到 HTTPS

如果没有显式指定 default_server,Nginx 会使用该端口上的第一个 Server 块作为默认。

总结

通过本文,你已经掌握了 Nginx Server 块的核心配置:

知识点 要点
Server 块 虚拟主机的基本单元,每个块独立管理一个站点的路由规则
listen 指定监听的端口和协议
server_name 匹配请求头的 Host 字段,决定请求由哪个 Server 块处理
请求路由流程 listen 过滤端口 → server_name 匹配域名 → location 匹配路径
匹配规则 精确匹配 > 通配符开头 > 通配符结尾 > 正则匹配
default_server 未匹配时的兜底方案,用于拦截非法域名或统一重定向
多域名实战 修改 hosts → 编写多个 server 块 → 重载配置即可实现一机多站
相关推荐
小天源7 小时前
从 Nginx 日志到访问分析:轻量化网站监测服务的架构实践
jvm·nginx·网络安全·架构·网络监控
幸福清风14 小时前
从域名到一行 nginx 配置:一次站点 HTTPS 证书更换与排障复盘
python·nginx·https
梅梅绵绵冰16 小时前
Nginx反向代理
运维·nginx
2601_965619692 天前
AI视频制作:财经数据可视化视频怎么做:AI 自动生成图表动画的实操流程
人工智能·nginx·音视频
2601_965619692 天前
历史解说视频怎么做:青铜器瓷器文物画面自动对齐的完整教程
运维·nginx·音视频
姜鱼问生2 天前
每次开机手动检查 6 样东西?我写了个 2 秒自检脚本
运维·网络·nginx·docker·容器
xixingzhe23 天前
Nginx 看懂请求耗时瓶颈
服务器·前端·nginx
北风toto3 天前
Windows 下用 OpenSSL 生成 SSL 密钥并配置 Nginx 教程
windows·nginx·ssl
卜锦元4 天前
Docker Compose 部署 Nginx 1.30.6 完整指南
nginx·docker·容器
小小龙学IT4 天前
Nginx 开源 Web 服务器与反向代理深度解
前端·nginx·开源