nginx如何执行请求的

http://nginx.org/en/docs/http/request_processing.html#simple_php_site_configuration


基于名字的虚拟服务

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的值不匹配任何服务名,或者请求中根本不包含host地段,nginx将把请求路由到此端口默认的服务上去。上面的配置中,默认服务是第一个--这是nginx的标准的默认行为。也可以明确指定哪个服务作为默认的,使用参数default_server,放到listen指令后面:

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

The  default_server parameter has been available since version 0.8.21. In earlier versions the default parameter should be used instead.

Note that the default server is a property of the listen port and not of the server name. More about this later.

注意:默认服务是监听的端口的属性而不是服务名的属性

如何不执行没有定义服务名的请求
How to prevent processing requests with undefined server names

If requests without the “Host” header field should not be allowed, a server that just drops the requests can be defined:

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

Here, the server name is set to an empty string that will match requests without the “Host” header field, and a special nginx’s non-standard code 444 is returned that closes the connection.

Since version 0.8.48, this is the default setting for the server name, so the  server_name ""can be omitted. In earlier versions, the machine’s  hostname was used as a default server name.

基于服务名和IP地址的混合虚拟服务
Mixed name-based and IP-based virtual servers

我们看一个更复杂的配置,这里有一些虚拟服务监听不同的地址:

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地址和端口和server blocks中的listen指定进行比较。再然后将请求中的host头字段同ip地址和端口已经匹配的这些server blocks中的server name进行比较。如果server name没有找到,请求将会被默认的虚拟服务器执行。比如,在192.168.1.1:80端口上接收到了www.example.com的请求,这个请求就会被默认的92.168.1.1:80端口执行。就是上面的第一个服务,因为92.168.1.1:80端口没有定义www.example.com。


In this configuration, nginx first tests the IP address and port of the request against thelisten directives of the server blocks. It then tests the “Host” header field of the request against the server_name entries of the server blocks that matched the IP address and port. If the server name is not found, the request will be processed by the default server. For example, a request for www.example.com received on the 192.168.1.1:80 port will be handled by the default server of the 192.168.1.1:80 port, i.e., by the first server, since there is no www.example.comdefined for this port.

As already stated, a default server is a property of the listen port, and different default servers may be defined for different ports:

正如已经说明的,默认服务是监听端口的属性,对于不同的端口有可能会定义不同的默认服务:

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站点配置
A simple PHP site configuration

Now let’s look at how nginx chooses a location to process a request for a typical, simple PHP site:

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的列表顺序的,nginx首先对location进行逐个查找,找到最准确的前缀location。在上面的配置中,只有前缀“/”location是匹配所有的请求你的,这个location将被用作最后考虑。nginx按照配置文件中列出的顺序检查是正则表达式的location。一旦匹配到了一个正则表达式就停止搜索,然后nginx就会使用此location。如果没有正则表达式匹配到此请求,nginx就会使用先前发现的最准确的prefix location。

nginx first searches for the most specific prefix location given by literal strings regardless of the listed order. In the configuration above the only prefix location is “/” and since it matches any request it will be used as a last resort. Then nginx checks locations given by regular expression in the order listed in the configuration file. The first matching expression stops the search and nginx will use this location. If no regular expression matches a request, then nginx uses the most specific prefix location found earlier.

Note that locations of all types test only a URI part of request line without arguments. This is done because arguments in the query string may be given in several ways, for example:

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

Besides, anyone may request anything in the query string:

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

现在我们来看看根据上面的配置,请求是如何执行的:

Now let’s look at how requests would be processed in the configuration above:

/logo.gif”请求首先匹配前缀location/”,然后又匹配到了正则表达式\.(gif|jpg|png)$”,因此,这个请求被后者处理。根据指令root /data/www”,请求映射到文件/data/www/logo.gif,然后文件被发送到客户端。

  • A request “/logo.gif” is matched by the prefix location “/” first and then by the regular expression “\.(gif|jpg|png)$”, therefore, it is handled by the latter location. Using the directive “root /data/www” the request is mapped to the file /data/www/logo.gif, and the file is sent to the client.
  • /index.php”请求也是先匹配location “/”,然后又匹配到\.(php)$”。因此也是被后者映射处理,所以请求被传送到监听ocalhost:9000的FastCGI服务。fastcgi_param指令设置FastCGI参数SCRIPT_FILENAME到/data/www/index.php,然后FastCGI服务执行这个文件。变量$document_root的值等于root指令的值,变量$fastcgi_script_name的值等于请求的URI,比如这里的"index.php"
  • A request “/index.php” is also matched by the prefix location “/” first and then by the regular expression “\.(php)$”. Therefore, it is handled by the latter location and the request is passed to a FastCGI server listening on localhost:9000. The fastcgi_paramdirective sets the FastCGI parameter SCRIPT_FILENAME to “/data/www/index.php”, and the FastCGI server executes the file. The variable $document_root is equal to the value of the rootdirective and the variable $fastcgi_script_name is equal to the request URI, i.e. “/index.php”.
  • 请求/about.html”仅仅匹配location “/”,因此被此location处理。
  • A request “/about.html” is matched by the prefix location “/” only, therefore, it is handled in this location. Using the directive “root /data/www” the request is mapped to the file /data/www/about.html, and the file is sent to the client.
  • Handling a request “/” is more complex. It is matched by the prefix location “/” only, therefore, it is handled by this location. Then the index directive tests for the existence of index files according to its parameters and the “root /data/www” directive. If the file/data/www/index.html does not exist, and the file /data/www/index.php exists, then the directive does an internal redirect to “/index.php”, and nginx searches the locations again as if the request had been sent by a client. As we saw before, the redirected request will eventually be handled by the FastCGI server.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值