高性能Web服务器Nginx的配置与部署研究(3)Nginx的请求处理机制

释放双眼,带上耳机,听听看~!

本文为您解读,Nginx是如何处理请求的,让你从逻辑上有一个清晰的认识。

1. 处理什么样的请求

处理访问到 Nginx 所在 IP 地址的请求,并且这些请求的 HTTP 头信息中的 Host 为所要处理的域名(如下以80端口为例),如下几个 server 就对应响应的请求:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1server {
2    listen       80;
3    server_name  nginx.org  www.nginx.org;
4    ...
5}
6
7server {
8    listen       80;
9    server_name  nginx.net  www.nginx.net;
10    ...
11}
12
13server {
14    listen       80;
15    server_name  nginx.com  www.nginx.com;
16    ...
17}
18
  1. 默认 server

如果不主动设置默认server,那么第一个server就会被当做默认server。若要主动设置,应该如下配置:


1
2
3
4
5
6
1server {
2    listen       80  default_server;
3    server_name  nginx.net  www.nginx.net;
4    ...
5}
6

1
2
1  此项的版本注意事项:
2
  • 0.8.21 版本之前,使用default关键词;
  • 从 0.8.21 版本开始,使用default_server关键词。

另外注意,default_server是端口的一个属性,不是server_name的一个属性。

3. 如何处理未定义 host 为 server_name 的请求

比如,如果不想处理 HTTP 请求中没有 HOST 字段的头信息的情况,那么可以如下:


1
2
3
4
5
6
1server {
2    listen       80;
3    server_name  "";
4    return       444;
5}
6

此项的版本注意事项:

  • 0.8.48 之前的版本,如果没有设置server_name的话,那么会把server_name设置为本机的 hostname。
  • 0.8.48 开始的版本,如果没有设置server_name的话,那么会把server_name设置为"",所以如果要达到上述代码的效果,在此版本开始可以不设置server_name。

4. Nginx 的虚拟主机监听

请先看如下配置:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1server {
2    listen       192.168.1.1:80;
3    server_name  nginx.org  www.nginx.org;
4    ...
5}
6
7server {
8    listen       192.168.1.1:80;
9    server_name  nginx.net  www.nginx.net;
10    ...
11}
12
13server {
14    listen       192.168.1.2:80;
15    server_name  nginx.com  www.nginx.com;
16    ...
17}
18

1
2
1  这个应该很好理解,如果 listen的 IP 地址和端口号都吻合了,就看 HTTP 请求中的 HOST 头信息与某个 server_name中的 name 是否吻合。如果 server_name不吻合,就到该端口对应的 default_server那里处理请求,如果 default_server的 server_name也没有与 HOST 头信息吻合,那么就放弃该请求。
2

特别再次强调,default_server是端口的属性,而非server_name的属性。所以可以有如下配置:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1server {
2    listen        192.168.1.1:80;
3    server_name   nginx.org  www.nginx.org;
4    ...
5}
6
7server {
8    listen        192.168.1.1:80  default_server;
9    server_name   nginx.net  www.nginx.net;
10    ...
11}
12
13server {
14    listen        192.168.1.2:80  default_server;
15    server_name   nginx.com  www.nginx.com;
16    ...
17}
18

5. 一个简单的 PHP 站点的 Nginx 配置


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1server {
2    listen        80;
3    server_name   nginx.org  www.nginx.org;
4    root          /data/www;
5
6    location / {
7        index     index.html  index.php;
8    }
9
10    location ~* \.(gif|jpg|png)$ {
11        expires   30d;
12    }
13
14    location ~ \.php$ {
15        fastcgi_pass   localhost:9000;
16        fastcgi_param  SCRIPT_FILENAME
17                       $document_root$fastcgi_script_name;
18        include        fastcgi_params;
19    }
20}
21

Nginx 在匹配location的时候,不是按照配置代码给出的顺序进行匹配的,而是先按照匹配表达式中的文字字符串(literal string)的明确程度,从最明确的开始匹配。这么说可能有点含混不清,简单说,没有正则规则的匹配表达式,是最明确的。比如如果这个匹配表达式就是一个“/”或者“/abc”,那么这就是最明确的。上例中的"/"就是这个最明确的文字字符串(the most specific literal string),其实也是该例中唯一的。所以先从这个location开始,然后再按照location的列出顺序,依次匹配,直到出现第一个匹配的location后停止。如果所有的location都不匹配,就用第一个找到的最明确的文字字符串来匹配(the most specific literal string)。

6. 待查询的 HTTP 请求

Nginx只处理无查询的HTTP请求,因为查询请求的查询字段的顺序不确定,比如:


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

再比如:


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

7. 几个location的例子

例1:


1
2
1/logo.gif
2

“/”先被找到,然后匹配".(gif|jpg|png)$",再根据 redirective 找到root是/data/www,然后这个请求就被映射到"/data/www/logo.gif"了,最后文件就被发送给到了客户端。

例2:


1
2
1/index.php
2

"/"先被找到,然后匹配".(php)$",然后 request 就被传递给在 9000 端口上监听的 FastCGI 服务器,"fastcgi_param" directive 设置 FastCGI 的参数SCRIPT_FILENAME为"/data/www/index.php",然后FastCGI服务器就执行这个文件。(注意其中document_root是/data/www,fastcgi_script_name是/index.php。)

例3:


1
2
1/about.html
2

"/"先被找到,且只有这一个匹配的。然后根据root值/data/www,就找到了文件/data/www/about.html,然后发送给客户端。

例4:


1
2
1/
2

"/"是很复杂的,先找到"/"这个location,然后根据root值/data/www,看/data/www/index.php是否存在,如果存在 directive 就在内部重定向到/index.php,然后 Nginx 根据这个再次搜索location,重复上面第二个例子。

给TA打赏
共{{data.count}}人
人已打赏
安全运维

WordPress网站专用docker容器环境带Waf

2020-7-18 20:04:44

安全运维

运维安全-Gitlab管理员权限安全思考

2021-9-19 9:16:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索