Nginx服务器在处理一个请求时是按照两部分进行的,第一部分IP、域名,第二部分是URI


nginx数据处理 nginx处理请求_正则表达式

(一)、IP、域名部分的处理

    按照IP、域名、端口以及default_server标志来处理请求

1、基于名字的虚拟主机

        

nginx数据处理 nginx处理请求_正则表达式_02

        在此配置中,Nginx根据请求头行中的Host,决定将请求路由到哪个Server。如果请求头中的Host不与任何服务器匹配,或者请求头中根本没有包含Host,那么Nginx将会把请求路由到默认的server上。在上面的配置中,默认的为第一个server,也可以使用指令,明确哪一个是默认的,设置方法为:在指令listen之后添加参数“default_server”

  

server
     {
listen                           80 default_server;
server_name              test-two.spring.cc;
……

    default_server这个参数是从0.8.21版本开始提供的,早起的版本使用的是“default”参数。

注意:默认的服务器监听是针对端口来设置的,而不是针对server的名字。

2、阻止处理对不明确主机名的处理

    在客户请求头中,有可能会有Host行不明确的情况,如果你不想处理这部分用户的请求,那么可以定义一个默认的server来丢弃这列请求。

server
     {
listen                           80 default_server;
server_name              _;
return

    我们选择一个不存在的域名“_”作为服务器名字,并且将返回特殊的非标准代码“444”,以便关闭这个连接

    注意:应该为这个服务器设置一个名字,否则Nginx将会使用它的hostname。

 3、基于IP和域名的虚拟域名服务器处理请求

  

server
     {
listen                   192.168.1.1:80;
server_name       test-one.spring.cc;
……
 
     server
     {
listen                   192.168.1.1:80  default_server;
server_name       test-two.spring.cc;
……
 
     server
     {
listen                   192.168.1.2:80  default_server;
server_name       test-one.spring.cc;
……

    在这个配置中,Nginx首先测试与server段listen指令对应的IP和端口号,然后再测试与server区段server_name指令对应的请求头中Host行中的值,即IP优先,如果没有找到对应的服务器名字,那么请求将会由默认的服务器进行处理。

(二)、URI部分的处理

    URI部分是通过location实现的,可以使用正则表达式。

 

server
     {
listen80;
server_name   test-one.spring.cc;
root /data/www;
location /{
index index.html index.php;
}
location ~* \.(gif|jpg|png)${
expire30d;
}
location ~ \.php${
fastcgi_passlocation:9000;
fastcgi_paramSCRIPT_FILENAME;
$document_root$fastcgi_script_name;
include fastcgi_params;
}

    在上面配置中,location“/”,由于它可以匹配任何请求,因此它将被作为最后使用(也可以说最后的一种补救方法),然后会按照配置文件中的顺序,Nginx开始检查通过正则表达式给定的location,第一个匹配的表达式将会停止本次搜索,Nginx就会使用该location。如果没有正则表达式匹配这个请求,那么Nginx会使用先前找到的最明确的字面字符的location。

(三)、服务器的名称

    服务器的名字是由指令server_name来定义的,并且也决定了使用哪一个server段来提取对客户端请求的响应。服务器名字的定义可以使用准确名字、通配符名字或者是正则表达式。

    这些名字的顺序为: 

    (1)、准确名字

    (2)、以*号开始的通配符名字:*.spring.cc

    (3)、以*号结尾的通配符名字:spring.*

    (4)、按照正则表达列举在配置文件中的顺序

1、通配符名字

         通配符的名字仅可以再名字的开始或结尾包含一个星号,星号仅在.号的边缘。一个特殊的通配符格式“.spring.cc”,不但能够准确匹配名字“spring.cc”,还能匹配通配符名字“*.spring.cc”。

    2、正则表达式名字

        要使用Nginx提供的正则表达式,需要在编译安装Nginx的时候首先安装Perl编程语言表达式(PCRE)。为了使用正则表达式,在服务器名字开始之前使用一个波浪号字符“~”:

  

server_name   "~^(?<name>\w\d{1,3}+)\.nginx\.net$";

        否则,就会被作为准确的名字对待。或者如果在表达式中包含一个星号(*),那么会被作为一个通配符名字。不要忘记设置锚点符号“^”、“$”,他们不需要在语法上,而是要在逻辑上。

    注意:域名中的.要是用反斜线进行转义。一个包含有“{”和“}”的正则表达式要使用引号。

    被捕获的正则表达式以后可以作为变量

server{
         server_name   ~^(www\.)?(?<domain>.+)$;
         location  /{
             root /sites/$domain;
         }
     }


如果你想通过不是默认的server区段来处理一个请求头行中却没有包含Host的请求,那么你应该指定一个空的名字:

      

server_name  spring.cc  "";

        如果客户端使用了一个没有在server区段通过server_name指定的名字,那么Nginx会使用一个空的名字作为服务器的名字

        如果一个客户端请求使用了IP,那么在请求头行中,Host包含的不是服务器的名字,而是IP地址,那么在这种情况下,如果想让客户端通过IP访问到某个server区段,那么可以再Nginx配置文件中指定适当的IP地址。

        在捕获所有服务器的例子中,你可能会看到一个奇怪的名字“_”

server_name  _;

        这里指定的不是什么特别的名字,它只是一个无效的域名,从来不会与任何真实名字相匹配。也可以使用类似于“--”、“!@#”等符号。

    4、名字优化

准确的名字和通配符名字作为哈希值被存储在哈希表中,这些哈希值被绑定到监听端口上,每一个监听的端口有三个哈希值:

        (1)、一个准确名字的哈希值

        (2)、一个星号开始名字的哈希值

        (3)、一个星号结尾名字的哈希值

        该哈希值大小大小的优化配置 分阶段进行。因此,在CPU的缓存中在最少失误的情况下找到该名字。

        准确名字的哈希值最先被搜索到。如果一个哈希值没有通过准确名字被找到,将会使用星号开始的哈希值开始搜索,如果还没找到将会使用星号结束的哈希值进行搜索——搜索通配符名字哈希值要慢于搜索准确名字哈希值,只是由于名字是通过域名部分搜索所致。

        “.spring.cc”是被存储在通配符号哈希表里。

    5、兼容性

从0.8.48版本开始,可以使用空名字来表示默认服务器

        从0.8.25版本开始,可以使用命名正则表达式来捕获服务器名字

        从0.7.40版本开始,支持正则表达式服务器名字补货

        从0.7.12版本开始,支持“”服务器名称

        从0.6.25版本开始,通配符服务器名字或正则表达式名字被作为首选服务器名字来使用

        从0.6.7版本开始,支持正则表达式

        从0.6.0版本开始,支持统配符格式“nginx.*”

        从0.3.18版本开始,支持特殊格式“.nginx.org”

        从0.1.13版本开始,支持通配符格式“*.nginx.org”

    6、基于目录名的域名访问

(1)、正则表达式处于主机名字的位置上


server {  
                    listen   80;  
                    server_name  ~^(.+)?\.t1\.com$;  
                    root  /usr/local/nginx0.8/html/t1.com/$1;  
                    location   / {  
                        index  index.html index.htm;  
                    }  
               }

在这里我们使用了正则表达式域名,域名已定,主机名可以随便,但是主机名不要太长,否则也会出现其他的问题。在这里从理论上来说可以访问xxx.t1.com,其中xxx为目录/usr/local/nginx0.8/html/t1.com下的任何目录名




        (2)、正则表达式处于域名的位置上

server {  

listen   192.168.3.139:80;  
                server_name  ~^(www\.)?(.+)$;  
                index index.php index.html;  
                root  /usr/local/nginx0.8/html/www/$2;  
                location  / {  
                    index  index.html index.htm;  
                }  
            }

 7、关于$1、$2…的使用

  

server_name  ~^(www\.)?(.+)$; 
            root  /usr/local/nginx0.8/html/www/$2;

"www."作为变量$1的值了,而其余的部分作为了$2的值。