nginx教程-----nginx如何处理一个请求

1. 基于名称的虚拟服务

nginx首先决定那个服务应该吹来请求。让我们以一个简单的配置开始,在这个配置中所有3个虚拟服务都监听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指令中使用default_server参数:

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

default_server从0.8.21版本开始就是可用的。在早期的版本应该使用default参数代替。

注意,默认服务是监听端口的属性而不是服务名称的。稍后讨论更多。


2. 如何防止处理带有为定义服务名称的请求

如果没有“Host”头字段的请求应该不被允许的,一个扔掉这个请求的服务可以这样定义:

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

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

自从0.8.48版本后,这是服务名称的默认设置,所以server_name ""可以省略。在早期的版本,机器的hostname被用于作为一个默认的服务名称。


3. 混合基于名称的和基于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首先测试server块中listen指令中的IP地址和端口。然后匹配ID地址和端口的server块的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;
    ...
}


4. 一个简单的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。如果没有正则表达式匹配一个请求,nginx使用之前找到的最特殊的前缀location。


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

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

除此之外,任何人可以在查询字符串中请求任何事:

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

现在让我们看看在上述的配置中请求将会如何被处理:

  • 一个请求“/logo.gif”被前缀location“/”首先匹配上,然后被正则表达式“\.(gif|jpg|png)”,因此,它被后面那个location处理。使用指令“root /data/www”这个请求被映射到/data/www/logo.gif,并且文件被发送到客户端。
  • 一个请求“/index.php”同样首先被前缀location“/”匹配然后被正则表达式“\.(php)$”.因此,它被后面的location处理并且被传递到一个监听在localhost:9000的FastCGI服务。fastcgi_param指令设置了FastCGI参数SCRIPT_FILENAME为“/data/www/index.php”,并且FastCGI服务执行那个文件。变量$document_root等价于root指令的值并且变量$fastcgi_script_name等价于请求的URI,也就是"/index.php"
  • 一个请求“/about.html”只会被前缀location“/”匹配,因此,它被这个location处理。使用指令“root /data/www”,请求被映射到文件/data/www/about.html,并且这个文件被发送到客户端。
  • 处理一个请求“/”是更复杂的。它只被前缀"/"匹配,因此,它被这个location处理。然后根据它的参数和“root /data/www”指令,index指令检测index文件的存在。如果文件/data/www/index.html不存在,并且/data/www/index.php存在,然后指令将会做一个内部重定向到"/index.php",并且nginx再次搜索location就好像请求是由一个客户端发送的。正如我们之前看到的,重定向的请求最终将会被FastCGI服务处理。








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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值