资讯专栏INFORMATION COLUMN

[译] nginx是如何处理Request的

BigTomato / 2784人阅读

摘要:如何阻止处理未定义的。如果没有被发现,将被处理。第一个匹配的表达式终止搜索,将使用这个。此外,任何人可能请求任何是在查询字符串现在我们来看将如何被处理。这个将被前缀位置首次匹配然后被正则表达式匹配,因此,被后处理。

官文:How nginx processes a request

       Nginx首先判断哪一个Server应该被用来处理这个Request。举个简单的配置例子,三个虚拟Server都在80端口上listen。

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仅找到request的header的Host field,看一下request应该被rout到哪一个server。如果请求头的Host域找不到一个匹配的server的名称,或者request压根就不包含这个header的field,那么nginx将把request route到这个端口的默认server上。上面的配置中,默认的server就是第一个,nginx的标准默认行为就是认第一个。当然 ,也可以使用default_server参数在listen的指令中显示设置哪一个server应该是默认的。

server {
    listen      80 default_server;
    server_name example.net www.example.net;
    ...
}

       default_server参数从0.8.21版本开始有效。早期版本使用的是default参数。

       注意,默认服务器是listen端口的一个属性,其他的下面说。
如何阻止处理未定义server name的request。
       如果不带有Host header field的request要被禁止,丢弃request的server可以被这样定义。

server {
    listen      80;
    server_name "";
    return      444;
}

       这里,server name设置为空字符串,将匹配无Host header field的request,指定的nginx的非标准代码444被返回来关闭连接。
从0.8.48开始,这是server name的默认设定,所以server_name “” 可以被忽略。早期版本,机器的hostname被用作默认的server name。
混合基于name和基于IP的虚拟server
       看一下一些虚拟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;
    ...
}

       这里,nginx首先测对应server块的listen指令的request。然后测匹配Ip地址和端口的针对server块的server_name 实体 request Host header field。如果server name没有被发现,request将被default server处理。例如,www.example.com的request接受在192.168.1.1:80 端口将被 192.168.1.1:80 port的default server处理,例如被第一个,因为没有www.example.com被定义在这个端口。
       nginx如已述,default server是监听端口的属性,不同的default servers可以被不同的端口定义。

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;
    ...
}
简单PHP配置

       我们来看如nginx如何选择位置来处理request,

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首先找最指定的前缀location,通过字面的字符串而不管顺序。配置中仅有前缀location是/ 因为它匹配任何请求他将被用作保底。然后nginx检查被正则表达式给出的location按照配置文件中的顺序。第一个匹配的表达式终止搜索,nginx将使用这个location。如果没有正则表达式匹配,那么nginx使用最匹配前缀location。
       注意所有类型的location仅仅试探无参数的request行的URI部分。因为请求字符串中的参数可能会有多种方式。

/index.php?user=john&page=1
/index.php?page=1&user=john

       此外,任何人可能请求任何是在查询字符串

/index.php?page=1&something+else&user=john

       现在我们来看request将如何被处理。

/logo.gif
       这个request将被前缀位置 /首次匹配然后被正则表达式.(gif|jpg|png)$匹配,因此,request被后location处理。使用指令root /data/www request被映射到文件/data/www/logo.gif,文件被送到客户端。

/index.php
       request也被/匹配然后被正则表达式.(php)$匹配。所以请求被后面的location处理同时请求被传递到FastCGI server 监听在localhost:9000。fastcgi_param 指令设置FastCGI参数SCRIPT_FILENAME 为 /data/www/index.php,root + uri,FastCGI server执行这个文件。

/about.html
       被/匹配,被处理。使用指令root /data/www; request 被映射到root + uri /data/www/about.html。

/
       匹配的复杂。被前缀location / 匹配。因此被这个location处理。然后 index 指令填补参数和 root /data/www 指令一起,并测试文件是否存在。如果文件/data/www/index.html 不存在,/data/www/index.php 存在,那么指令要进行内部重定向(凡是请求中的没有uri指定文件的,使用index自动匹配上的,都会触发重定向),nginx重新匹配location,如果这个新生成的request是从客户端发来的一样,而不是直接返回相应资源。如我们所见,重定向请求最终被最后一个FastCGI server处理了。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/39235.html

相关文章

  • [] 深入解 Promise 五部曲:5. LEGO

    摘要:一个就像一个乐高玩具。问题是不是你小时候玩儿的那个有趣,它们不是充满想象力的打气筒,也不是一种乐高玩具。这是对的并不是给开发者使用的,它们是给库作者使用的。不会超过这两种情况。第二个是根据第一个处理函数如何运行来自动变成状态成功或者失败。 原文地址:http://blog.getify.com/promis... 在 Part4:扩展问题 中,我讨论了如何扩展和抽象Promise是多么...

    LiveVideoStack 评论0 收藏0
  • Spring是如何处注解

    摘要:如果我们使用注入,如上所述,便通过调用方法注入依赖项,这一点尤其重要,因为在调用对象的构造函数时这些依赖项并不可用。 如果你看到了注解,那么一定有什么代码在什么地方处理了它. Alan Hohn 我教Java课程时强调的一点是注解是惰性的。换句话说,它们只是标记,可能具有某些属性,但没有自己的行为。因此,每当你在一段Java代码上看到一个注解时,就意味着必须有一些其他的Java代码来寻...

    oneasp 评论0 收藏0
  • Spring Security OAuth2 优雅集成短信验证码登录以及第三方登录

    摘要:前言基于做微服务架构分布式系统时,作为认证的业内标准,也提供了全套的解决方案来支持在环境下使用,提供了开箱即用的组件。 前言 基于SpringCloud做微服务架构分布式系统时,OAuth2.0作为认证的业内标准,Spring Security OAuth2也提供了全套的解决方案来支持在Spring Cloud/Spring Boot环境下使用OAuth2.0,提供了开箱即用的组件。但...

    yck 评论0 收藏0
  • dubbo之timeout超时分析

    摘要:讲到这里,超时原理基本上其实差不多了,这个类还有个地方需要注意,在初始化对象时,会去创建一个超时的延迟任务,延迟时间就是值,在这个延迟任务中也会调用方法唤醒阻塞 背景 在使用dubbo时,通常会遇到timeout这个属性,timeout属性的作用是:给某个服务调用设置超时时间,如果服务在设置的时间内未返回结果,则会抛出调用超时异常:TimeoutException,在使用的过程中,我们...

    张率功 评论0 收藏0
  • 】发送表单数据

    摘要:若该特性未指定,则数据会发送到包含该表单的页面所在的。其中使用了来处理表单数据。特殊案例发送文件文件是表单中一个特殊的例子,其他数据都是文本数据,而文件则一般是或者被认为是二进制数据。 系列文章说明 原文 多数时候,HTML表单的目的只是为了把数据发给服务器,之后服务器再处理这些数据并发送响应给用户。虽然看起来挺简单的,但我们还是得注意一些事情以确保传送的数据不会破坏服务器、或者给...

    Eidesen 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<