Nginx配置与部署中文手册(1)Nginx的请求处理 .
英文原文:http://nginx.org/en/docs/http/request_processing.html
原文作者:Igor Sysoev
中文译者:Poechant
特别声明:
(1)本人提供意译,不提供咬文嚼字的逐句翻译。
(2)由于本人语言水平有限,部分词汇无法找到合适的中文词汇对应,所以仍然使用英文。另外关键词等,不会翻译成中文。
(3)本文欢迎传播,但请注明出处。
(4)欢迎提各种宝贵建议。
1.处理什么样的请求
处理访问到Nginx所在IP地址的请求,并且这些请求的HTTP头信息中的Host为所要处理的域名(如下以80端口为例),如下几个server就对应响应的请求:- view plaincopy to clipboardprint?
- 01.server {
- 02. listen 80;
- 03. server_name nginx.org www.nginx.org;
- 04. ...
- 05.}
- 06.
- 07.server {
- 08. listen 80;
- 09. server_name nginx.net www.nginx.net;
- 10. ...
- 11.}
- 12.
- 13.server {
- 14. listen 80;
- 15. server_name nginx.com www.nginx.com;
- 16. ...
- 17.}
- 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;
- ...
- }
复制代码 2.默认server
如果不主动设置默认server,那么第一个server就会被当做默认server。若要主动设置,应该如下配置:- view plaincopy to clipboardprint?
- 01.server {
- 02. listen 80 default_server;
- 03. server_name nginx.net www.nginx.net;
- 04. ...
- 05.}
- server {
- listen 80 default_server;
- server_name nginx.net www.nginx.net;
- ...
- }
复制代码 此项的版本注意事项:
0.8.21版本之前,使用default关键词;
从0.8.21版本开始,使用default_server关键词。
另外注意,default_server是端口的一个属性,不是server_name的一个属性。
3.如何处理未定义host为server_name的请求
比如,如果不想处理HTTP请求中没有HOST字段的头信息的情况,那么可以如下:- view plaincopy to clipboardprint?
- 01.server {
- 02. listen 80;
- 03. server_name "";
- 04. return 444;
- 05.}
- server {
- listen 80;
- server_name "";
- return 444;
- }
复制代码 此项的版本注意事项:
0.8.48之前的版本,如果没有设置server_name的话,那么会把server_name设置为本机的hostname。
0.8.48开始的版本,如果没有设置server_name的话,那么会把server_name设置为"",所以如果要达到上述代码的效果,在此版本开始可以不设置server_name。
4.Nginx的虚拟主机监听
请先看如下配置:- view plaincopy to clipboardprint?
- 01.server {
- 02. listen 192.168.1.1:80;
- 03. server_name nginx.org www.nginx.org;
- 04. ...
- 05.}
- 06.
- 07.server {
- 08. listen 192.168.1.1:80;
- 09. server_name nginx.net www.nginx.net;
- 10. ...
- 11.}
- 12.
- 13.server {
- 14. listen 192.168.1.2:80;
- 15. server_name nginx.com www.nginx.com;
- 16. ...
- 17.}
- 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;
- ...
- }
复制代码 这个应该很好理解,如果listen的IP地址和端口号都吻合了,就看HTTP请求中的HOST头信息与某个server_name中的name是否吻合。如果server_name不吻合,就到该端口对应的default_server那里处理请求,如果default_server的server_name也没有与HOST头信息吻合,那么就放弃该请求。
特别再次强调,default_server是端口的属性,而非server_name的属性。所以可以有如下配置:- view plaincopy to clipboardprint?
- 01.server {
- 02. listen 192.168.1.1:80;
- 03. server_name nginx.org www.nginx.org;
- 04. ...
- 05.}
- 06.
- 07.server {
- 08. listen 192.168.1.1:80 default_server;
- 09. server_name nginx.net www.nginx.net;
- 10. ...
- 11.}
- 12.
- 13.server {
- 14. listen 192.168.1.2:80 default_server;
- 15. server_name nginx.com www.nginx.com;
- 16. ...
- 17.}
- 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;
- ...
- }
复制代码 5.一个简单的PHP站点的Nginx配置- view plaincopy to clipboardprint?
- 01.server {
- 02. listen 80;
- 03. server_name nginx.org www.nginx.org;
- 04. root /data/www;
- 05.
- 06. location / {
- 07. index index.html index.php;
- 08. }
- 09.
- 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.}
- 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在匹配location的时候,不是按照配置代码给出的顺序进行匹配的,而是先按照匹配表达式中的文字字符串(literal string)的明确程度,从最明确的开始匹配。这么说可能有点含混不清,简单说,没有正则规则的匹配表达式,是最明确的。比如如果这个匹配表达式就是一个“/”或者“/abc”,那么这就是最明确的。上例中的"/"就是这个最明确的蚊子字符串(the most specific literal string),其实也是该例中唯一的。所以先从这个location开始,然后再按照location的列出顺序,依次匹配,直到出现第一个匹配的location后停止。如果所有的location都不匹配,就用第一个找到的最明确的文字字符串来匹配(the most specific literal string)。
6.待查询的HTTP请求
Nginx只处理无查询的HTTP请求,因为查询请求的查询字段的顺序不确定,比如:- view plaincopy to clipboardprint?
- 01./index.php?user=john&page=1
- 02./index.php?page=1&user=john
- /index.php?user=john&page=1
- /index.php?page=1&user=john
复制代码 再比如:- view plaincopy to clipboardprint?
- 01./index.php?page=1&something+else&user=john
- /index.php?page=1&something+else&user=john
复制代码 7.几个location的例子
例1:- view plaincopy to clipboardprint?
- 01./logo.gif
- /logo.gif
复制代码 “/”先被找到,然后匹配"\.(gif|jpg|png)$",再根据redirective找到root是/data/www,然后这个请求就被映射到"/data/www/logo.gif"了,最后文件就被发送给到了客户端。
例2:- view plaincopy to clipboardprint?
- 01./index.php
- /index.php
复制代码 "/"先被找到,然后匹配"\.(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:- view plaincopy to clipboardprint?
- 01./about.html
- /about.html
复制代码 "/"先被找到,且只有这一个匹配的。然后根据root值/data/www,就找到了文件/data/www/about.html,然后发送给客户端。
例4:
- view plaincopy to clipboardprint?
- 01./
- /
复制代码 "/"是很复杂的,先找到"/"这个location,然后根据root值/data/www,看/data/www/index.php是否存在,如果存在directive就在内部重定向到/index.php,然后Nginx根据这个再次搜索location,重复上面第二个例子。 |