Nginx-4.Nginx如何处理请求
基于server_name 的虚拟站点
Nginx首先需要确定使用哪个server
来处理请求。举个简单的例子,有下面几个server
- 第一个,监听80端口,为org站点
server {
listen 80;
server_name example.org www.example.org;
...
}
- 第二个,监听80端口,为net站点
server {
listen 80;
server_name example.net www.example.net;
...
}
- 第三个,监听80端口,为com站点
server {
listen 80;
server_name example.com www.example.com;
}
因为端口一样,所以这个Nginx会检查请求头中的Host
和哪个server_name
匹配。如果过来的Host
和3个都不匹配,或者说请求中没有Host
头,那么nginx会使用默认的server。没有指定就是第一个。也可以通过default_server
这个参数来指定。这个参数属于listen
指令,不是server
指令块。
server {
listen 80 default_server;
server_name example.net www.example.net;
...
}
如何拒绝处理未定义的Host的请求
如果一个请求中没有Host
,那么可以丢弃这个请求,可以如下定义:
server {
listen 80;
server_name "";
return 444;
}
这个看到server_name定义成一个空字符串来匹配那些没有Host的请求,然后返回444状态码。0.8.48之前的版本,server_name 会默认使用计算机的hostname值。
server_name 和 IP并存的虚拟站点
让我们来看一个比较复杂一点的例子,listen
指令用到了ip和端口,并且定义了不同的server_name
。
server {
listen 192.168.1.1:80;
server_name example.org www.example.org;#org 站点
...
}
server {
listen 192.168.1.1:80; #default_server
server_name example.net www.example.net;#net站点
...
}
server {
listen 192.168.1.2:80;#.2服务器 #default_server
server_name example.com www.example.com;
...
}
这个,Nginx会先检查过来的请求的ip和端口匹配哪一个。然后再通过Host
头来决定使用的server。Host就是浏览器地址栏输入的地址。假设有一个192.168.1.1:80过来的对www.example.com的请求,由于没有匹配任意一个,那么会使用第一个。也可以通过在listen后面指定default_server
来修改。
一个简单的php站点配置
我们来看看Nginx如何确定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;
}
}
第一个location
是个/,匹配所有,所以优先级最低,Nginx会找最精确的。Nginx只会检查url部分,不会考虑地址后面的参数。因为参数顺序不定。
举几个简单的例子:
/logo.gif
,先匹配第一个location,然后也匹配第二个,所以用第二个。通过root
指令得到具体为/data/www/logo.gif
文件。/index.php
,同理,用最后一个location指令块。fastcgi_param
指令吧SCRIPT_FILENAME 设置成后面变量,$document_root 为 root的/data/www
,$fastcgi_script_name为index.php,然后cgi server 9000就会去处理/data/www/index.php
这个文件。/about.html
,只匹配第一个location。/
,只匹配第一个,所以回去请求index.html文件,如果不存在,会有一内部重定向,到index.php,然后到最后一个location去处理。