HTTP请求是如何关联Nginx server{}块的?

Linux命令

HTTP请求是如何关联Nginx server{}块的?

2025-04-16 00:04


1. 基础匹配流程 Nginx的 server块匹配分为两个阶段: 阶段一:根据IP和端口筛选候选server块

                                            





1. 基础匹配流程

Nginx的 server块匹配分为两个阶段:
阶段一:根据IP和端口筛选候选server块

  • 每个 server块通过 listen指令指定监听的IP地址和端口(如 listen 80;或 listen 192.168.1.1:443;)。

  • 当请求到达时,Nginx首先根据请求的目标IP和端口,筛选出所有匹配的 server块。

  • 示例

    # 监听所有IP的80端口server { listen 80; server_name example.com; }# 监听特定IP的80端口server { listen 192.168.1.1:80; server_name sub.example.com; }
    

    若请求的目标IP是 192.168.1.1且端口为 80,则第二个 server块会被选中。

阶段二:通过Host头或server_name进一步匹配

  • 若阶段一筛选出多个 server块(如多个块监听同一IP和端口),Nginx会根据请求的 Host头字段匹配 server_name指令:
    • 精确匹配server_name example.com;
    • 通配符匹配server_name *.example.com;(匹配所有子域名)
    • 正则表达式匹配server_name ~^api\..+\.com$;(需以 ~开头)
  • 无Host头时的默认规则
    若请求未携带 Host头(如HTTP/1.0或配置错误),则选择第一个匹配的 server块(即配置文件中定义的首个匹配项)。

2. server_name的匹配规则详解

Nginx的 server_name支持多种匹配模式,优先级从高到低为:

  1. 精确匹配(如 example.com
  2. 最长前缀匹配(如 www.example.com vs *.example.com
  3. 正则表达式匹配(需以 ~开头,如 ~^blog\..+\.com$

示例场景

server {
    listen 80;
    server_name example.com;  # 精确匹配
    # ...
}

server {
    listen 80;
    server_name *.example.com;  # 匹配所有子域名
    # ...
}

server {
    listen 80;
    server_name ~^api\..+\.com$;  # 正则匹配如api.blog.example.com
    # ...
}
  • 请求 Host: blog.example.com → 匹配第二个 server块(最长前缀)。
  • 请求 Host: api.test.example.com → 匹配第三个正则块。

3. 特殊场景与注意事项

  • HTTPS请求的Host头获取
    HTTPS请求的 Host头在TLS加密层内,需通过SNI(Server Name Indication)扩展提前解析域名。因此,HTTPS的 server块需在 listen指令中指定 ssl参数,并确保 server_name与证书域名一致。
    server {
        listen 443 ssl;
        server_name secure.example.com;
        ssl_certificate /path/to/cert.pem;
        # ...
    }
    
  • 默认server块
    若所有 server块均未匹配到请求的 Host头,则使用第一个配置的 server块(即默认块)。可通过显式定义默认块避免意外:
    server {
        listen 80 default_server;  # 显式标记为默认
        return 444;  # 直接关闭未匹配的请求
    }
    
  • 端口复用
    同一IP的 80和 443端口可分别配置不同 server块,互不影响。

4. 实际配置示例

假设配置如下:

# 配置1:处理主域名
server {
    listen 80;
    server_name example.com;
    root /var/www/main;
}

# 配置2:处理子域名
server {
    listen 80;
    server_name blog.example.com;
    root /var/www/blog;
}

# 配置3:默认兜底
server {
    listen 80 default_server;
    return 404;
}
  • 请求 http://example.com → 匹配配置1。
  • 请求 http://blog.example.com → 匹配配置2。
  • 请求 http://invalid-domain.com → 匹配配置3并返回404。

5. 调试与验证工具

  • 查看配置语法
    nginx -t  # 检查配置文件语法
    
  • 查看当前监听端口
    netstat -tuln | grep nginx  # 查看Nginx监听的IP和端口
    
  • 模拟请求测试
    curl -H "Host: example.com" http://localhost  # 指定Host头测试路由
    

总结

Nginx通过IP+端口Host头+server_name的双重匹配机制,将HTTP请求精准路由到对应的 server块。理解这一过程的关键在于:

  1. 配置 listen指令明确监听的IP和端口。
  2. 通过 
    標簽:
    • HTTP
    • Nginx
© 蓝易云.