您的位置:首页 > 运维架构 > Nginx

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

Poechant 2011-12-07 14:47 351 查看


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

Author: Igor Sysoev

Translator: Poechant

Blog: blog.CSDN.net/Poechant

Email: zhongchao.ustc#gmail.com (#->@)

Date: December 7th, 2011

Update: February 26th>, 2012

Column: 《Nginx 高性能 Web 服务器》

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


1. 处理什么样的请求

处理访问到 Nginx 所在 IP 地址的请求,并且这些请求的 HTTP 头信息中的 Host 为所要处理的域名(如下以80端口为例),如下几个 server 就对应响应的请求:
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
。若要主动设置,应该如下配置:
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 字段的头信息的情况,那么可以如下:
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 的虚拟主机监听

请先看如下配置:
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
的属性。所以可以有如下配置:
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 配置

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请求,因为查询请求的查询字段的顺序不确定,比如:
/index.php?user=john&page=1
/index.php?page=1&user=john


再比如:
/index.php?page=1&something+else&user=john


7. 几个location的例子


例1:

/logo.gif


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


例2:

/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:

/about.html


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


例4:

/


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

-

更多 Nginx 技术博文请访问 CSDN 专栏 《Nginx 高性能Web服务器》

转载请注明来自“柳大的CSDN博客”: blog.CSDN.net/Poechant

-
标签: 
相关文章推荐