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 时,匹配顺序如下:

arduino 复制代码
客户端请求 ──→ 根据 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 就会解析到本机。

第二步:准备站点目录

arduino 复制代码
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 块 → 重载配置即可实现一机多站
相关推荐
Csvn1 小时前
Hooks 原理:把"每次重跑的函数"变成"有记忆的组件"
前端
计算机魔术师1 小时前
用AI拒批老人看病?美国这个试点项目的激励机制出了大问题
前端
风骏时光牛马1 小时前
AI服务线上响应异常故障
前端
IT_陈寒1 小时前
JavaScript的this指向问题又让我加了个班
前端·人工智能·后端
美好世界1 小时前
Codex 源码导读:第一部分——工程分层
后端
行百里er1 小时前
Redis 核心数据结构(四)——Set 与 Sorted Set,去重与排名神器
redis·后端
lizhongxuan1 小时前
Firecracker 与 KVM
后端
YIAN1 小时前
LangChain.js 对话记忆体系(一):内存存储与文件持久化,让 AI 拥有对话记忆
前端·后端·langchain
flash俊杰1 小时前
pgvector 实战:把向量检索"塞"进关系数据库,一条 SQL 搞定联合查询
后端