nginx-2 如何处理一个请求

2019-03-26  本文已影响0人  苍老的小孩_a1fe

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的功能。

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

上一篇下一篇

猜你喜欢

热点阅读