How nginx processes a request; Nginx处理一条请求的过程

 

Name-based virtual servers

FROM: http://nginx.org/en/docs/http/request_processing.html

nginx first decides which server should process the request. Let’s start with a simple configuration where all three virtual servers listen on port *:80:

server {
    listen       80;
    server_name  nginx.org  www.nginx.org;
    ...
}

server {
    listen       80;
    server_name  nginx.net  www.nginx.net;
    ...
}

server {
    listen       80;
    server_name  nginx.com  www.nginx.com;
    ...
}

 

In this configuration nginx tests only the request’s header line “Host” to determine which server the request should be routed to. If the “Host” header line does not match any server name, or the request does not contain this line at all, then nginx will route the request to the default server. In the configuration above, the default server is the first one — which is nginx’s standard default behaviour. If you do not want the first server listed to be the default server, you may set it explicitly with the “default_server” parameter in the “listen” directive:

server {
    listen       80  default_server;
    server_name  nginx.net  www.nginx.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 you do not want to process requests with undefined “Host” header lines, you may define a default server that just drops the requests:

server {
    listen       80  default_server;
    server_name  _;
    return       444;
}

We have chosen the non-existent domain name “_” as the server name and returned nginx’s special non-standard code 444 that closes the connection. Note that you should set a name for this server, otherwise nginx will use the hostname.

Mixed name-based and IP-based virtual servers

Let’s look at a more complex configuration where some virtual servers listen on different addresses:

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

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

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

In this configuration, nginx first tests the IP address and port of the request against the “listen” directives of the “server” blocks. It then tests the “Host” header line 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.nginx.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 nowww.nginx.com defined 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 listen ports:

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

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

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

 

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   nginx.org  www.nginx.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 first searches for the most specific location given by literal strings regardless of the listed order. In the configuration above the only literal 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 literal location found earlier.

Note that locations of all types test only a request URI part without a query string. 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:

  • A request “/logo.gif” is matched by the literal 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 a file “/data/www/logo.gif”, and the file is sent to the client.

  • A request “/index.php” is also matched by the literal 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_param”directive 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 “root” directive and the variable $fastcgi_script_name is equal to the request URI, i.e. “/index.php”.

  • A request “/about.html” is matched by the literal 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 literal location “/” only, therefore, it is handled by this location. Then the “index” directive tests for the existence of an index file according to its parameters and the “root /data/www” directive. If a 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.

 

written by Igor Sysoev
edited by Brian Mercer

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以在nginx配置中使用proxy_next_upstream指令来实现请求失败再反向代理一次的功能。具体配置如下: ``` http { upstream backend { server backend1; server backend2; } server { location / { proxy_pass http://backend; proxy_next_upstream error timeout; } } } ``` 在上述配置中,当请求后端服务器失败或超时时,nginx会自动尝试访问下一个服务器。如果所有的后端服务器都访问失败,则nginx会返回一个错误响应。这样就可以实现请求失败再反向代理一次的功能。 ### 回答2: 实现nginx反向代理处理请求失败再反向代理一次的方法如下: 1. 配置nginx反向代理:首先需要在nginx的配置文件中设置反向代理的相关配置。通过使用`proxy_pass`指令将请求转发到后端服务。例如: ``` location / { proxy_pass http://backend; } ``` 上述配置将会将所有的请求转发到名为`backend`的后端服务。 2. 添加错误处理机制:在配置文件中添加错误处理的相关配置。使用`error_page`指令可以对不同类型的错误进行自定义处理。例如: ``` error_page 502 = @fallback; location @fallback { proxy_pass http://fallback_backend; } ``` 上述配置将会在发生502错误时,将请求转发到名为`fallback_backend`的后端服务。 3. 配置失败的反向代理:为了实现请求失败再次反向代理的功能,可以配置一个备用的后端服务。在发生错误时,将请求转发到该备用后端服务。例如: ``` upstream backend { server backend_server1; server backend_server2 backup; } ``` 上述配置中的`backend_server1`和`backend_server2`是两个后端服务的地址。其中`backend_server2`设置为`backup`类型,表示只有在前一个后端服务(`backend_server1`)不可用时才会使用`backend_server2`。 4. 重启nginx服务:修改完配置文件后,需要重启nginx服务使配置生效。使用命令`sudo service nginx restart`即可重启。 当一个后端服务出现故障或无法处理请求时,nginx会自动将请求转发到备用的后端服务。这样可以提高整个系统的可靠性和稳定性,确保请求能够得到处理和响应。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值