nginx是如何匹配过来的请求,然后做处理的呢?这个匹配的过程可以分为两步:
1.选择server
2.选择location 
 
选择server
仅仅匹配server name
加入Nginx的配置文件有这么几项:
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仅仅匹配server_name指令。根据Request请求头的"Host"参数,去匹配server_name的指令参数,从而决定路由到哪个虚拟服务器。如果HOST 请求头参数找不到对应的server,或者压根没有这个请求头,那么nginx将会选择默认的——往往是第一个,这里是 server_name example.org www.example.org;   但是你也可以直接指定:
server {
    listen      80 default_server;
    server_name example.net www.example.net;
    ...
}
在listen指令的后面,使用default_server参数就指定了默认的server。注意,这里指令参数default_server是放在指令listen后面,不是server_name后面,是指定一个具体的端口,不是指定一个虚拟机名称,后面会说明原因。
如果请求头Header没有HOST参数,在0.8.48之后的版本,此请求会被丢弃。在之前的版本中,你可以用下面的指令来完成丢弃的功能:
server {
    listen      80;
    server_name "";
    return      444;
}
指令server_name 的参数设为空数组将匹配不带Host请求头的请求。
 
同时匹配server name和IP
来看看同时带有IP和server name的server的配置情况:
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;
    ...
}
在这种情况下,Ngxin首先根据请求的IP和Port匹配listen指令,然后再根据请求的Host头匹配server_name 指令。比如本机的ip是192.168.1.1,那么所有过来的请求都不会到192.168.1.2上去。如果Host没有匹配上,再用默认的server来处理。
例如: 发往192.168.1.1:80端口的www.example.com请求,只会从前面两个server中去找对应的server_name,发现没有匹配上,那么采用默认的(第一个)server。
我看来看看在多个IP的配置文件下,如何指定默认的server:
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;
    ...
}
所以,server是针对某个IP,某个端口的,并不是针对某个域名,因此default_server也是针对某个IP,某个端口的,是listen的属性而不是server_name 的属性。
 
选择 location 
location指令都是针对请求的uri部分进行匹配,不是整个url,也不包含任何请求参数,比如:
/index.php
/user/index/get
 
Nginx的locating指令可以分为两种,即"prefix location"和"regular expression location",即“前缀location”和“正则location”。
前缀location形如下面:
location / {
       ....
}
location /path/to {
        .....
 }
location /index.php {
       .....
 }
 

正则location location后面需要匹配正则表达式,比如:

  location ~* \.(gif|jpg|png)$ {
        expires 30d;
   }
 
以一个PHP网站的配置为例,看看Nginx如果选择location来处理请求的。
server {
    listen      80;
    server_name example.org www.example.org;
    root        /data/www;
 
    location / {
        index  index.html index.php;
    }
 
    location /comment {
        rewrite /comment/(.*) /$1 break;
    }
 
    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中进行匹配,而且首先搜寻匹配的最为"精确"的那一项:比如请求/comment,即匹配location /comment 和location / 但是location /comment 更为“精确”因此被匹配上。location / 因为是匹配所有的请求所以被“最后考虑”。这一步匹配是无关前缀location的罗列顺序的。
接着,nginx继续匹配正则location,这一步跟正则location的顺序就有关系了。nginx是依次匹配,第一个匹配的到location时。nginx会终止匹配,然后用这个location来处理请求。如果正则location部分没有匹配到任何一项,则采用上一步前缀location匹配到的来处理请求。
在匹配到location,处理Request时,还需要加上root指令,即root   /data/www;
 
举例说明下:
"/logo.gif"——首先被前缀location的location /匹配上了,然后也被正则location的location ~* \.(gif|jpg|png)$ 匹配上了,因此会被后面的location处理。此外,在处理请求是还要加上root   /data/www ,最为请求就被定为到了 /data/www/logo.gif,最后次文件会被发送到浏览器
 
"/index.php"——同样首先被前缀location的location /匹配上,但后面正则location也匹配上了location ~ \.php$,因此由后者来处理:交给运行在localhost:9000的FASTCGI程序来处理,
fastcgi_param 指令用来设定FASTCGI的参数SCRIPT_FILENAME,$document_root和$fastcgi_script_name是nginx参数,分别为root指令参数(/data/www)和URI(/index.php)
 
"/about.html"——仅仅能被location /匹配,因此便由它处理,最后请求定位到/data/www/about.html
 
"/"——这种情况稍微复杂点。它仅能被前缀location"location /"匹配上,因此它将被这个location处理。然后location中的指令index将被执行,nginx会依次尝试index文件(俗称入口文件)是否存在,在此例中就是/data/www/index.html /data/www/index.php,如果前者不存在就继续往后找。此例中,/data/www/index.html不存在因此由/data/www/index.php处理。然后nginx会做个内部跳转到/index.php,然后,就处理好像一个从浏览器反过来的全新请求一样,重新搜寻location,就像前面分析的一样,最终交由FASTCGI程序来处理。
 
 
 

Nginx是如何处理Request的?的更多相关文章

  1. nginx 出现413 Request Entity Too Large问题的解决方法

    nginx 出现413 Request Entity Too Large问题的解决方法 使用php上传图片(大小1.9M),出现 nginx: 413 Request Entity Too Large ...

  2. Nginx出现“413 Request Entity Too Large”错误解决方法

    Nginx出现“413 Request Entity Too Large”错误解决方法 2011-03-25 13:49:55|  分类: 默认分类 |  标签:413  request  entit ...

  3. Nginx 出现413 Request Entity Too Large得解决方法

    Nginx 出现413 Request Entity Too Large得解决方法 默认情况下使用nginx反向代理上传超过2MB的文件,会报错413 Request Entity Too Large ...

  4. 多进程端口监听 How nginx processes a request Server names

    网络编程( 六):端口那些事儿 - 知乎专栏  https://zhuanlan.zhihu.com/p/20365900 不停服务reload.restart 多进程端口监听 我们都有一个计算机网络 ...

  5. nginx 是如何处理过期事件的?

    目录 什么是过期事件 nginx 是如何处理过期事件的? 参考资料 什么是过期事件 对于不需要加入到 post 队列 延后处理的事件,nginx 的事件都是通过 ngx_epoll_process_e ...

  6. wordpress 主题安装 您点击的链接已过期 nginx 出现413 Request Entity Too Large

    1 nginx 出现413 Request Entity Too Large 问题是限制上传大小,解决: 1.打开nginx配置文件 nginx.conf, 路径一般是:/etc/nginx/ngin ...

  7. nginx是如何处理一个请求的(包含https配置)

    配置https首先要有ssl证书,这个证书目前阿里有免费的,但如果自己做实验,也是可以自签证书,只不过不受信 openssl genrsa -des3 -out server.key 1024     ...

  8. nginx 自动忽略request中header name包含下划线参数的解决方法

    使用nginx过程中遇到了个问题,就是request中的header name中如果包含下划线会自动忽略掉,导致服务器接收不到该字段的内容,以下为解决方法: nginx默认request的header ...

  9. Nginx出现413 Request Entity Too Large错误解决方法

    Nginx出现的413 Request Entity Too Large错误,这个错误一般在上传文件的时候出现,打开nginx主配置文件nginx.conf,找到http{}段,添加 解决方法就是 打 ...

随机推荐

  1. MPSOC之8——启动及错误处理

    有了BOOT.BIN(fsbl+pmu+atl+uboot).uImage.uramdisk.image.gz,dtb文件,就可以启动了.把上述文件统统拷贝到SD卡,并设置开发板为SD卡启动. 0. ...

  2. Lua 数组排序 table.sort的注意事项

    1. table中不能有nil table.sort是排序函数,它要求要排序的目标table的必须是从1到n连续的,即中间不能有nil. 2. 重写的比较函数,两个值相等时不能return true ...

  3. SQL_Server 常用语句以及语法整理

    下列语句部分是Mssql语句,不可以在access中使用. SQL分类: DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE) DML—数据操纵语言(SELECT,DELETE, ...

  4. iOS 5个Xcode开发调试技巧

    转自Joywii的博客,原文:Four Tips for Debugging in XCode Like a Bro    1.Enable NSZombie Objects(开启僵尸对象) Enab ...

  5. xml文件解析(使用解析器)

    一.Xml解析,解析xml并封装到list中的javabean中 OM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这个层次结构允许开发人员在 ...

  6. .net 委托的使用方法以及使用委托的好处

    使用方法: //无返回值无参数委托的定义方法 public delegate void NoReturnPara(); 给委托赋值的几种方式 //实例化委托,并传入方法 NoReturbNoPara ...

  7. 解决 mysql 中文乱码

    mysql版本:5.6.38 虽然创建实例时选择的是utf-8的utf8_general_ci,但是用其他程序保存中文时依旧出现乱码的情况. 记录一种可行的解决方案,即修改数据库的字符集. 由于该环境 ...

  8. ogg12-ERROR OGG-01031 file D:\OGG\dirdat\ed000000 is not in any allowed output directories

    配置ogg时出现这个错误: 2018-01-04 14:22:58 ERROR OGG-01031 Oracle GoldenGate Capture for Oracle, P147148.prm: ...

  9. [编织消息框架][网络IO模型]NIO(select and poll)

    上面测试论证系统内核在read data时会阻塞,如果我们在把第一个阶段解决掉那么性能就会提高 NIO 编程 JDK 1.4中的java.nio.*包中引入新的Java I/O库,其目的是提高速度.实 ...

  10. 前端之JavaScript--基础

    JavaScript 独立的语言,浏览器具有js解释器 一. JavaScript代码存在形式: - Head中 <script> //javascript代码 alert(123); & ...