Nginx请求处理
目录
- 基于名称的虚拟主机
- 如何避免处理没有服务器名的请求
- 混合基于名称和基于IP的虚拟服务器
- 简单的PHP站点配置
1. 基于名称的虚拟主机
Nginx首先会决定哪个主机处理请求。我们先开始一个简单的配置三个虚拟主机监听在80端口。
server {
listen 80;
server_name example.org www.example.org;
...
}
server {
listen 80;
server_name example.net www.example.net;
...
}
server {
listen 80;
server_name example.com www.example.com;
...
}
在这个配置中,nginx仅仅检查请求头部的”Host”信息来判断请求应该送到哪个服务器,如果这个值没有匹配任何服务器名,或者请求没有包含头部Host信息,nginx会使用默认服务器来处理这个请求。上面的配置,默认服务器是第一个(nginx的标准行为),你也可以精确的指定那个服务器用做默认服务器,只需要你在listen指令后面添加default_server参数。
server {
listen 80 default_server;
server_name example.net www.example.net;
...
}
注意:default_server只是监听端口的属性,而不是服务器名称。
2. 如何避免处理没有服务器名的请求
如果请求没有”Host”信息,那么可以不处理这个请求,服务器用于终止(drop)掉这个请求可以这么做
server {
listen 80;
server_name "";
return 444;
}
这里服务器名称被设置为空字符串,将会匹配任何没有”Host”头部的请求,然后返回给客户端nginx的非标准代码404。
3. 混合基于名称和基于IP的虚拟服务器
让我们看看下面一个更加复杂的配置,虚拟服务器监听的不同的地址。
server {
listen 192.168.1.1:80;
server_name example.org www.example.org;
...
}
server {
listen 192.168.1.1:80;
server_name example.net www.example.net;
...
}
server {
listen 192.168.1.2:80;
server_name example.com www.example.com;
...
}
在这个配置中,nginx首先会测试请求的IP地址和端口。然后测试头部的”Host”信息,如果服务器名称(server name)没找到,请求
会被默认服务器处理。例如一个请求www.example.com 在 192.168.1.1:80被接收将会通过192.168.1.1:80端口的默认服务器处理,因
为在这个端口上没有定义www.example.com 。
上面已经说过了,默认服务器只是监听端口的一个属性,不同的服务器可以被定义对于不同的端口来说。
server {
listen 192.168.1.1:80;
server_name example.org www.example.org;
...
}
server {
listen 192.168.1.1:80 default_server;
server_name example.net www.example.net;
...
}
server {
listen 192.168.1.2:80 default_server;
server_name example.com www.example.com;
...
}
4. 简单的PHP站点配置
现在,让我们看看nginx如何选择一个 location 处理典型的简单的PHP站点。
server {
listen 80;
server_name example.org www.example.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首先会不按照列出来的顺序 寻找最详细指定的前缀。上面的配置中,唯一的前缀是”/”,而且它匹配任何的请求,所有它会被用作最后的处理。然后nginx根据配置文件中的顺序检查正则表达式的location。第一个匹配到之后就会停止向下搜寻然后使用这个location。如果没有正则表达式匹配到,nginx会使用最通用的最早的location。
注意: 所有类型的location仅仅测试部分URI,不会测试URI的参数。因为参数在查询字符串中可以有很多种方式,例如
/index.php?user=john&page=1
/index.php?page=1&user=john
除此之外,任何人可以请求任何事情就像这样
/index.php?page=1&something+else&user=john
现在让我们看看上面的配置如何处理请求的
- 首先”/logo.gif”请求会被前缀location “/”匹配,然后通过正则表达式”\.(gif|jpg|png)”,因此,它会被后面的location处理。使用了指令 “root /data/www”,这个请求会被影射到/data/www/logo.gif文件,然后文件被发送到客户端。
- 请求”/index.php”也会被”/”匹配到,然后被正则表达式”\.(php)$”匹配到。因此它会被后面的匹配处理,然后请求传递监听在9000端口的FastCGI服务器。fastcgi_param指令设置FastCGI参数SCRIPT_FILENAME为”/data/www/index.php”,然后FastCGI服务器执行这个文件,变量$document_root等价于root指令的值,变量$fastcgi_script_name等价于请求的URI,”/index.php”
- 请求”/about.html”仅仅被前缀”/”匹配,因此仅仅在这个location被处理。使用指令”root /data/www”,这个请求映射到/data/www/about.html文件,然后文件发送到客户端。
- 处理请求”/”更加复杂。它仅仅匹配”/”,因此它被这个位置处理。然后index指令测试index文件是否存在,如果文件/data/www/index.html 不存在,文件 /data/www/index.php 存在的话,然后指令做一个内部重定向到/index.php,然后nginx再次寻找location,就好像客户端已经发出请求一样。就像上面看到的,重定向请求最终会被FastCGI服务器处理。
Nginx 的详细介绍:请点这里
Nginx 的下载地址:请点这里