nginx处理请求之匹配server、location

本文详细解析了nginx如何处理请求,包括server匹配优先级:先按IP、Port匹配,接着是server_name,若无匹配则选择default server。在server内部,location匹配根据uri进行,优先级为:精确匹配 > 通配符 > 正则表达式 > /。通过实例分析了不同uri的处理流程,涉及正则匹配、文件查找及FastCGI协议交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • server匹配优先级:

    • 通过server监听 IP、Port 匹配
    • IP、Port 相同,通过server_name匹配
    • IP、Port 相同,server_name匹配不上,nginx将请求分配到default server。配置未指定default server情况,nginx默认相同 IP、Port 的第一个server为default server
  • server name匹配细节

    • server name配置方式支持:确切名称、通配符名称、正则表达式名称
    • 不同配置方式优先级:
优先级由高到低
完全名称(确切名称)
以星号开头的最长通配符名称,例如:"*.example.org"
以星号结尾的最长通配符名称,例如:"mail.*"
按配置顺序,依次匹配正则表达式名称
>[更多server name有关细节](https://blog.youkuaiyun.com/m0_37929735/article/details/97657157)
  • location匹配优先级:
符号含义
=完全精确匹配
^~前缀匹配,以XX开头
~正则匹配,区分大小写
~*正则匹配,不区分大小写
!~不匹配,区分大小写
!~*不匹配,不区分大小写
/通用匹配

注意:nginx仅使用请求的 uri 进行 locaiton 匹配,uri 不包含其他请求参数

  • 例1:nginx配置不止一个server,server监听相同IP、Port
    • 分析:
      1)IP和Port相同,nginx通过server_name匹配server
      2)nginx读取请求头中HOST字段用以匹配server_name(如请求头中没有HOST字段对应的server_name为"")
      3)以上server_name匹配不成功,nginx将请求路由到default server处理,下例情况,default server是第一个server
server {
    listen      80;
    server_name example.org www.example.org;
    ...
}

server {
    listen      80;
    server_name example.net www.example.net;
    ...
}

server {
    listen      80;
    server_name example.com www.example.com;
    ...
}

#default server可以通过手动配置
server {
    listen      80 default_server;
    server_name example.net www.example.net;
    ...
}

#假如需求:丢弃请求头中不带HOST字段的请求
#server_name配置为空可以匹配到对应server,不带HOST字段请求统一返回444状态码,并关闭连接
server {
    listen      80;
    server_name "";
    return      444;
}
  • 例2:nginx配置不止一个server,server监听不同IP、Port
    • 分析:
      1)nginx通过请求IP、Port 首先进行匹配
      2)步骤1)匹配成功的server中(如果不止一个),继续匹配server_name
      3)继续匹配server_name失败,nginx将请求路由到对应default server处理
      如:IP=192.168.1.1:80,HOST=www.example.com,请求将由192.168.1.1:80 default server处理(第一个server)
server {
    listen      192.168.1.1:80;
    server_name example.org www.example.org;
    ...
}

server {
    listen      192.168.1.1:80;
    server_name example.net www.example.net;
    ...
}

server {
    listen      192.168.1.2:80;
    server_name example.com www.example.com;
    ...
}
  • 例3:nginx处理综合请求
    • nginx处理php请求分析:
      1)nginx首先确定server,再继续匹配server中的location
      2)location根据优先级依次匹配
      3)下例中,直接开始正则表达式匹配
      4)正则匹配失败,nginx使用通用匹配 / 处理请求

    • nginx处理 uri=/logo.gif 请求分析:
      1)~3)前3个步骤上述一致
      4)正则匹配成功,".(gif|jpg|png)$",请求交由对应location处理
      5)因 root=/data/www,nginx查看文件 /data/www/logo.gif 是否存在,并将资源返回客户端

    • nginx处理 uri=/index.php 请求分析:
      1)~3)前3个步骤上述一致
      4)正则匹配成功,".(php)$",请求交由对应location处理
      5)该请求将通过fastcgi协议转发给FastCGI服务处理(监听本地9000端口),其中fastcgi_param指令可以设置FastCGI参数

    • nginx处理 uri=/about.html 请求分析:
      1)~3)前3个步骤上述一致
      2)正则匹配失败,请求由"通用匹配" / 处理
      3)因 root=/data/www,nginx查看文件 /data/www/about.html 是否存在,并将资源返回客户端

    • nginx处理 uri=/ 请求分析:
      1)nginx匹配到"通用匹配" /,请求由"通用匹配" / 处理
      2)因 root=/data/www,index指令指定默认访问索引文件 index.html、index.php,nginx查看文件 /data/www/index.html 是否存在,存在则将资源返回客户端。不存在nginx继续查找目录下index.php文件,假如index.php文件存在(非静态资源),nginx将在内部发起请求重定向,新请求 uri=/index.php,nginx将重走uri=/index.php的请求匹配流程

server {
    listen      80;
    server_name example.org www.example.org;
    root        /data/www;

    location / {
        index   index.html index.php;
    }

    location ~* \.(gif|jpg|png)$ {
        expires 30d;
    }

    location ~ \.php$ {
        fastcgi_pass  localhost:9000;
        fastcgi_param SCRIPT_FILENAME
                      $document_root$fastcgi_script_name;
        include       fastcgi_params;
    }
}

参考:How nginx processes a request

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值