nginx是怎样处理请求

英文原版:http://www.nginx.org/en/docs/http/request_processing.html

nginx是怎样处理请求?

一,基于名称的虚拟服务器

首先,nginx得决定由哪个服务器来处理请求。

我们从一简音的配置开始吧,这个配置设置了三个server,它们都是监听80端口的。

configuration:

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;

    ...

}

在这个配置中,nginx只能通过请求的报文的“host”来决定哪过通过服务器处理。

如果host和server_name 全不匹配或者请求压根没带host信息,nginx就会通过默认server处理。在上面的那个配置中,每一个声明的server将会被当作默认server(这是nignx规定的标准缺省做法).当然如果你不想要让列在最前面的server做为默认的,你就得用‘default_server;’显示声明了(如下)。

server {

    listen       80  default_server;

    server_name  nginx.net  www.nginx.net;

    ...

}

注意:0.8.21版后默认的显示声明用default_server

在此之前的应该用default

再注意一下:defaut的声明应该当作listen 的一个属性,而不是server_name。

二,怎样能过undefined server names阻止当前请求?

如果佻不想处理没定义'host'信息的请求,你可定义一个default server用来拒绝请求:

server {

    listen       80  default_server;

    server_name  _;

    return       444;

}

我们选择的是域名中不存在的“_"作为server_name并且返回一个非标准code 444,这样就可 关闭掉请求的链接了。注意了,必须设一个server_name,不然nginx就会用你的主机名,到时情况就不是现在的样子了。

3,混用设轩基于名字和基于ip的虚拟主机。

我们接下来看一个稍微复杂的配置,其中会有一些监听不同地址的设置哦:

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;

...

}

在这样一个配置中,nginx会优先检测请求ip和端口,并且和各个server块的lsten指令作比对。然后才是检测请求中的“host"信息,并ip和端口匹配的server块的server_namew作比较。如果没找到server_name,请求就会由默认server处理。

例如,一个对www.nignx.com的请求在192.168.1.1:80端口被截获,但由于没有这个地方没有声明www.nignx.com,所以呢,还是会由默认server处理。

前面说过,一个声明默认server应该是声明在listen指令里。不同的”listen“都可设置缺省。

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;

    ...

}

三,一个简单的Php网站配置

现在,我们说看一下nginx是怎么选择一个location从而进行一个请求处理的,经典的,合适于php网站。

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中,定义更详细的优先级高,注意哈,是无视书写顺序的。

在上面的配置中,字面只通配符“/”的location,由于和作何请求匹配,所以通常会被当作压抽处理。

对于正则来说,nginx就比较常规了,是按列表顺序进行检查的。遇到第一个匹配的,nginx就会停止搜索,并且采用这个location进行处理。

如果往后正则都不被请求所匹配,nginx就会用前面定义最详细的Location.

注意,location的所在类型洞里,只是通过uri部分,并包括query string。这样的处理的原因是因为,query string 的形式不单一,比如说:

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

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

还有,任何人都有可能提交这样的请求字符串:

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

现在让我们来看看,基于上面的配置,nginx将会怎么处理请求:

1,logo.gif 这样一请求着先是和"/"这个匹配,接着还会匹配正则"\.(gif|jpg|png)$",

因些,它会被后面的location处理。通过“root /data/www”这个指令,请求就会映射到“/data/www/logo.gif",随后,这个文件就会被送往客户端。

2,”/index.php"这样一个请求,也会先被“/"匹配再被正则"\.(php)$"所匹配。因些,这个请求也是会被按后面的location处理的,当然请会经过一个监听“loclhost:9000”的fasctcgi服务器处理。”fastcgi_param"这个指令将fastcgi的参数SCRIPT_NAME设置为"/data/www/index.php",并且fastcgi服务器会执行这个文件。$document_root这个变量和“root"指令的是一样的。并且$fasctcgi_script_name 是和请求的uri,'/index.php',一样的。

3."/about.html"这个请求只全”/"匹配,所以,它会被这个location处理。通过”root /data/www"这个指令,这个请求就会被映射到“/data/www/about.html”文件,并且之个文件会被发送到客户端,即浏览器了。

4.到于对“/"这样一个请求,是会更复杂一些。它只和”/“匹配,所以,这是由这个location处理的。然后”index“指令会检测index 文件是否存在,如果有”/data/www/index.php"这样一个文件存在,接着就作作内部重定向,即作“/index.php"请求处理,nginx会再搜索location,就像是客户端又发了一次请求。当然,被重定向的请求最终会由fastcgi server下理。

posted on 2011-08-26 17:31  zhuoyr  阅读(1207)  评论(0)    收藏  举报

导航