nginx怎样处理一个请求

基于服务名的处理方式

nginx首先决定哪一个server应该处理请求,下面是三个虚拟服务器的配置,他们都监听端口 *: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”值去决定路由request到哪一个server处理,如果“Host”头的值没有匹配任何的server_name或者请求不包含“Host”头,nginx将把请求路由到default server, nginx规定第一个server是default server,或者也可以在明确指定哪一个serverdefault server, 只需要在listen指令指定default_server参数即可:

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

default_server参数从0.8.21版本可用,在早期版本中使用default

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

怎么禁止处理未定义"Host"头的请求

如果请求没有“Host”头字段应该被禁止访问,可以定义一个只删除请求的server :

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

这里把server_name设置为空,它将处理没有“Host”请求头的请求,然后返回一个nginx特定的非标准的444码去关闭这个连接。

从0.8.48开始,这是server_name的默认设置,所以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首先测试listen指令配置的ip地址和端口号,然后它根据匹配ip地址和端口号的server_name匹配“Host”请求头. 如果server_name没有找到,这个请求将被default server处理. 例如,在192.168.1.1:80端口上接收到对www.example.com的请求将要被192.168.1.1:80端口上的default server处理,例如第一个server,因为没有对这个端口定义www.example.com.

如前所述,default server是监听端口的属性,不同的端口可以定义不同的default server:

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首先搜索由字符串字面量给定的最具体的前缀地址.在上面的配置中唯一的前缀地址是 “/” 并且由于他匹配任何的请求所以将被用作最后的手段. 然后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”,并且FastCGI服务器执行这个文件. 变量$document_root与root指令的值相等且变量$fastcgi_script_name与请求URI相等,如:“/index.php”.
  • 请求 “/about.html”将仅仅被前缀地址“/”匹配,因此它被这个地址处理。使用"root /data/www"指令这个请求被映射到文件/data/www/about.html并发送给客户端
  • 处理“/”请求更加复杂,它仅仅匹配前缀地址“/”,因此请求被这个地址处理。然后这个index指令根据它的参数和“root /data/www”指令测试index文件是否存在,如果/data/www/index.html文件不存在且/data/www/index.php文件存在,则指令内部重定向到“/index.php”,nginx再次搜索位置,就像请求是由客户端发送的一样。正如我们之前看到的,重定向请求最终将由FastCGI服务器处理.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值