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下理。
浙公网安备 33010602011771号