Nginx:如何处理请求

基于名称的虚拟服务器

        Nginx 首先决定由哪个服务器来处理请求。下面有一个简单的配置,三个虚拟服务器都监听80端口:

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;
    ...
}

        在此配置中, Nginx 只测试请求的报头字段 Host ,以确定请求应该由哪个服务器处理。如果没有匹配任何服务器,或者请求根本不包含这个报头字段,那么这个请求将由 Nginx 默认配置的服务器处理。在此配置中,Nginx 将第一个配置的服务器作为默认配置。它也可以显式地设置哪个服务器应该是默认的,在 listen 指令中使用默认的服务器参数:

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

参数 default_server  从0.8.21版本开始可用。在早期版本中,应该使用参数 default parameter 代替。 

         注意,默认的服务器是监听端口的属性,而不是服务器名的属性。稍后再详细介绍。

 如何防止处理未定义服务器名的请求

        如果不允许没有 Host 报头字段的请求,则可以定义直接丢弃请求的服务器:

server {
    listen      80;
    server_name "";
    return      444;
}

        在这里,服务器名被设置为一个空字符串,它将匹配没有 Host 报头字段的请求,并返回一个特殊的 Nginx 的非标准代码444,它将关闭连接。

从0.8.48版本开始,这是服务器名的默认设置,因此可以省略 server_name ""。在早期版本中,机器的主机名被用作默认服务器名。 

混合基于名称和基于ip的虚拟服务器

         让我们看一个更复杂的配置,其中一些虚拟服务器监听不同的地址:

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;
    ...
}

        在这个配置中, Nginx 首先根据服务器块的监听指令测试请求的 IP 地址和端口。然后,它根据与 IP 地址和端口匹配的服务器块的服务器名称条目测试请求的 Host 报头字段。如果没有找到服务器名,则将由默认服务器处理请求。例如,在 192.168.1.1:80 端口上接收到的 www.example.com 请求将由 192.168.1.1:80 端口的默认服务器处理,即由第一个服务器处理,因为没有为该端口定义 www.example.com 。

        如前所述,默认服务器是侦听端口的一个属性,可以为不同的端口定义不同的默认服务器:

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

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

server {
    listen      192.168.1.2:80 default_server;
    server_name example.com www.example.com;
    ...
}

一个简单的PHP站点配置

        现在让我们看看 Nginx 如何选择一个位置来处理一个典型的、简单的 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;
    }
}

        Nginx 首先搜索由字面值字符串给出的最特定的前缀位置,而不管列出的顺序是什么。在上面的配置中,唯一的前缀位置是“/”,因为它匹配任何请求,所以它将被用作最后手段。然后,Nginx 按照配置文件中列出的顺序检查正则表达式给出的位置。第一个匹配的表达式将停止搜索,Nginx 将使用该位置。如果没有正则表达式匹配请求,那么 Nginx 将使用前面找到的最具体的前缀位置。

        注意,所有类型的位置只测试请求行的 URI 部分,不带参数。这样做是因为查询字符串中的参数可能以几种方式给出,例如:

/index.php?user=john&page=1
/index.php?page=1&user=john

        此外,任何人都可以请求查询字符串中的任何内容:

/index.php?page=1&something+else&user=john

        现在让我们看看如何在上面的配置中处理请求:

☆        请求'/logo.gif'首先由前缀位置'/'匹配,然后由正则表达式'\.(gif|jpg|png)$'匹配,因此由后一个位置处理。使用指令'root/data/www',请求被映射到文件/data/www.logo.gif,然后将文件发送到客户端。

☆        请求'/index.php'也首先匹配前缀位置'/',然后匹配正则表达式'\.(php)$'。因此,它由后一个位置处理,请求被传递到侦听localhost:9000的FastCGI服务器。FastCGI_param指令将FastCGI参数SCRIPT_FILENAME设置为'/data/www/index.php',FastCGl服务器执行该文件。变量$document_root等于根指令的值,变量$fastcgi_script_name等于请求URI,即'/index.php'。

☆        请求'/about.html'只与前缀位置'/'匹配,因此,它在这个位置处理。使用指令'root/data/www',请求被映射到文件/data/www.about.html,文件被发送到客户机。

☆        处理请求'/'更为复杂。它只与前缀位置'/'匹配,因此由该位置处理。然后,index指令根据其参数和'root/data/www'指令测试是否存在索引文件。如果文件/data/www/index。html不存在,文件/data/www/index。php存在,然后指令将内部重定向到'/index.php',nginx将再次搜索这些位置,就好像请求是由客户机发送的一样。如前所述,重定向的请求最终将由FastCGI服务器处理。

作者:Igor Sysoev  

编辑:Brian Mercer

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值