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”头域检查,并根据其值决定将请求路由给哪个服务器。如果和任何一个服务器都不匹配,或者请求不包含一个“Host”头域,那么nginx会将请求路由给监听在该端口上的默认服务器。上述配置中,默认服务器为第一个,nginx默认第一项为默认服务器。通过default_server可以显示的指定默认服务器:

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

(注意:默认服务器属性在0.8.21以后的版本才有)

怎么样禁止处理携带未定义服务器名的请求

如果收到一个没有携带Host头域的请求,那么该请求应该不处理而直接抛弃掉。通过如下配置即可:

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

服务器名设置为空字符串,这样就可以配未携带Host头域的请求,然后返回一个nginx的非标准444响应并关闭连接。

混合基于名称和基于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和端口是否,然后再检查上一步各匹配项中的server_name是否存在匹配请求的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怎样为选择一个location为典型、简单的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首先选择前缀匹配最明确的location。在上述的配置中,唯一的前缀匹配location是”/”,因为它匹配任何请求,因此它是所有请求的最后选择。nginx检查配置文件中顺序列出的location中的正则表达式,遇到第一个匹配项(此处为全匹配而不是前缀匹配)时即停止然后使用该项。如果没有找到,nginx将使用此前找到的匹配前缀最明确的location。注意所有类型的locations(前缀、全部)只和请求的URI组成部分对比,而不包括参数。这是因为查询字符串中的参数可能以多种方式出现,如:

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

同时,任何人都可以再请求字符串中请求任何东西:

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

现在,我们来看一下在以上配置下,请求将会被怎么处理:
1、请求”/logo.gif” 匹配前缀location “/”,其次匹配正则表达式”.(gif|jpg|png)$”.因此,该请求将被后面的location处理。因为”root /data/www”,该请求被影射到文件/data/www/logo.gif,该文件将被发送到客户端

2、请求”/index.php” 也匹配前缀location “/”,并且匹配正则表达式\.(php)$根据规则,请求将被后者处理,被发送到监听在localhost:9000的一个FastCGI服务器。fastcgi_param指定设置FastCGI 参数SCRIPT_FILENAME 为/data/www/index.php。FastCGI服务器将执行该文件。参数$document_root的值为root指向的目录,$fastcgi_script_name和请求中携带的URI相同如"/index.php"

3、请求”/about.html”之和前缀匹location”/”匹配,因此,它将被该location处理。根据配置”root /data/www”,该请求被映射到文件 /data/www/about.html,并且该文件将被发送到客户端

4、处理请求”/”相对而言更加复杂。它只和前缀location “/” 匹配,因此将被该location处理。”index”配置项根据配置”root /data/www” 检查index文件是否存在。若果文件/data/www/index.html不存在,而文件/data/www/index.php存在,那么该请求将被在nginx内部被重定向为index.php,然后nginx好像从客户端收到该请求一样重新搜索location。如前所述,该重定向请求将被FastCGI服务器处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值