美文网首页
nginx-2 如何处理一个请求

nginx-2 如何处理一个请求

作者: 苍老的小孩_a1fe | 来源:发表于2019-03-26 14:45 被阅读0次

    nginx接收一个请求后,首先由listen和server_name指令匹配server模块,再匹配server模块里的location,最后就是location里的具体处理(可以是代理转发请求或者直接返回静态内容...)

    基于名称的虚拟服务器

    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头部中的HostHost 匹配到哪个server_name就使用哪个服务器。如果都不匹配,则使用默认的服务器。在未显示指定默认服务器的情况下,比如上面的这个例子,nginx认为第一个server为默认服务器。如需显示指定,如下。

    # 0.8.21 版本以前使用的是default
    server {
        listen      80 default_server;
        server_name example.net www.example.net;
        ...
    }
    
    注意:default_server 是监听端口的一个属性。
    

    如何处理不含Host头部的请求

    server {
        listen      80;
        # 使用空字符串匹配未定义的Host
        server_name "";
        # 返回一个特殊状态码,并关闭连接
        return      444;
    }
    
    注意:0.8.48版本以后,""是server_name的默认值,所以此处可以省略server_name "";在更早的版本,server_name的默认值为主机的hostname。
    

    基于名称和IP的混合虚拟服务器

    前提知识:一台主机可以有多个IP(多网卡),一个IP可以绑定多个域名

    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首先匹配监听IP地址和端口,匹配成功之后,再匹配相应的server_name,这个通过之后就选择使用该server处理请求,否则使用默认的server。正如前面所说,default_server 是监听端口的一个属性,所以不同的默认服务器应该有且只有一个定义在不同的IP:端口,如下。

    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网站配置例子

    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)。在上面的配置中,唯一的前缀位置是“/”,因为它匹配任何请求,所以它将用作最后的匹配。然后nginx按照配置文件中列出的顺序检查正则表达式给出的位置。第一个匹配表达式停止搜索,nginx将使用此位置。如果没有与请求匹配的正则表达式,那么nginx使用前面找到的最具体的前缀位置。

    注意,所有类型的位置只测试匹配(test)请求行的URI部分,不包含参数(query_string)。这是因为查询字符串中的参数可以通过多种方式给出,例如:

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

    此外,请求查询字符串中的内容是变化的;

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

    所以location只有匹配uri的功能,没有匹配query_string的功能。

    现在,让我们看看在上面的配置中如何处理请求:

    • /log.gif
      首先匹配位置/,接着匹配~* \.(gif|jpg|png)$,因此,由后者处理。使用指令root /data/www,请求被映射到/data/www/logo.gif,该文件被发送回客户端。
    • /index.php
      首先匹配位置/,接着匹配~ \.php$,因此由后者处理。请求配传递到监听在localhost:9000的FastCGI服务器。fastcgi_param指令设置了参数SCRIPT_FILENAME/data/www/xxx.xxx(xxx.xxx = fastcgi_script_name),然后FastCGI服务器执行了该文件。变量document_root等同于root指令的参数,变量fastcgi_script_name等同于请求的uri,比如/index.php
    • /about.html
      只匹配位置/,因此由其处理,请求被映射到/data/www/about.html,该文件被发送回客户端。
    • /
      处理/比较复杂。它只匹配位置/,因此由其处理。index指令根据它的参数和root /data/www依次检测index文件是否存在。如果/data/www/index.html不存在,/data/www/index.php存在,index指令会内部重定向到/index.php,nginx再次搜索这些location,就好像请求是由客户机发送的一样。如上所述,重定向的请求将会被FastCGI服务器处理。

    相关文章

      网友评论

          本文标题:nginx-2 如何处理一个请求

          本文链接:https://www.haomeiwen.com/subject/bivgvqtx.html