Nginx是什么?Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为“engine X”, 是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器.Nginx是由俄罗斯人 Igor Sysoev为俄罗斯访问量第二的 Rambler.ru站点开发的,它已经在该站点运行超过两年半了。Igor Sysoev在建立的项目时,使用基于BSD许可。
笔者的VPS使用的是nginx服务器,以前配置都是从网上拷贝过来的,一直一知半解,正好手头有VPS可以玩,趁这个机会认真学习下nginx的配置.下面的文章是讲nginx如何处理web请求(web request)过程的。
一、基于域名的虚拟服务器
nginx首先确定使用哪一个server域来处理请求,下面的例子中有3个虚拟服务器监听*:80端口。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
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; ... } |
在上面的配置中,nignx根据HTTP请求“Host”的值,确定具体哪一个server接收web请求。如果“Host”不存在或者Host的值无法匹配任何sever中的$host_name,nginx就会把web请求送到默认的server中。如果没有定义default_server,默认将请求传递给第一个server。
1
2
3
4
5
|
server { listen 80 default_server; server_name nginx.net www.nginx.net; ... } |
参数“default_server” 是0.8.21后版本新增的内容. 此前的版本用“default”代替。
上面是针对web请求中包含“Host”值的情况,如果这个值不存在,那么可以使用下面的方法。
二、如何处理无server_name的请求?
1
2
3
4
5
6
|
server { listen 80 default_server; server_name _; return 444; #所用"Host"为空的请求返回444响应。 } |
三、处理基于IP和域名的虚拟主机
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
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地址和端口,然后在确定响应IP下的server_name,如果没有找到任何匹配的server_name,ngixn将请求传递给默认server。例如,当nginx收到来自 192.168.1.1:80 端口的请求www.nginx.com,
上例中没有定义默认server,那么这个请求将被传递到第一个server中。
nginx可以为不同的IP地址和端口定义多个默认server:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
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是如何确定web请求的location的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
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会优先处理定位符"/"、"/images"这些location,其次才按顺序匹配包含正则的location。例如:"./logo.gif"的请求首先会匹配定位符"/",其次是通用表达式"\.(gif|jpg|png)$",因此它被第二个定位符所匹配.Nginx会使用指令"root /data/www"将请求映射到文件"/data/www/logo.gif",之后文件被返回给客户端。换言之,ngixn总是会把请求传递到最后一个匹配的location中。
需要注意到的是,ngixn处理的URI中不包含查询字符串(query string)部分,因为这些查询字符串的不确定因素太多,例如:
1
2
|
/index.php?user=john&page=1 /index.php?page=1&user=john |
也可以这样写:
1
|
/index.php?page=1&something+else&user=john |
最后看一下上面的例子中,nignx是如何处理的:
- “./logo.gif”的请求首先会匹配定位符”/”,其次是通用表达式”\.(gif|jpg|png)$”,因此它被第二个定位符所匹配.Nginx会使用指令”root /data/www”将请求映射到文件”/data/www/logo.gif”,之后文件被返回给客户端
- “/index.php”的请求也一样,首先匹配定位符”/”,其次是通常表达式”\.(php)$”.因而它由后者处理,请求被传递给在localhost:9000监听的FastCGI服务.”fastcgi_param”指令将FastCGI的参数SCRIPT_FILENAME设置为”/data/www/index.php”,再由FastCGI服务器执行该文件.变量$document_root的值与”root”指令的值是相等的,变量$fastcgi_script_name的值等于所请求的url,如”/index.php”等等
- 带”/about.html”的请求只匹配定位符”/”,因此它将在这个定位符中得到处理,由”root /data/www”指令将请求映射到”/data/www/about.html”,最后文件才被返回给客户端.
- 处理”/”这样的请求就更复杂了,因为只匹配”/”定位符所以只能在其中处理.”index”指令会根据它的参数及”root /data/www”指令,测试该目录下是否有默认文件存在.例如,如果存在”/data/www/index.php”文件,请求会被内部重定向到”/index.php”,然后Nginx会据此再进行一次定位符搜索,看起来就像是新接收到一个请求命令.一般而言,被重定向的请求最后会由FastCGI服务处理.