在开始处理一个http请求时,nginx会取出header头中的host,与nginx.conf中每个server的server_name进行匹配,以此决定到底由哪一个server块来处理这个请求。

server_name与host匹配优先级如下:

1、完全匹配

2、通配符在前的,如*.test.com

3、在后的,如www.test.*

4、正则匹配,如~^\.www\.test\.com$

如果都不匹配

1、优先选择listen配置项后有default或default_server的

2、找到匹配listen端口的第一个server块

空口无凭,验证一下:

1、最高优先级:完全匹配

首先,在nginx.conf中创建2个server,1个完全匹配,1个通配符匹配

通配符server放在最前,以证明完全匹配的优先级与配置顺序无关

nginx 配置匹配规则 nginx server匹配_正则匹配

接下来配置域名映射

vim /etv/hosts

nginx 配置匹配规则 nginx server匹配_nginx 配置匹配规则_02

访问测试:

nginx 配置匹配规则 nginx server匹配_优先级_03

结论:完全匹配的优先级高于通配符匹配

 2、第二优先级:通配符在前

 修改server配置,还是2个server,通配符在后的server放到前面,同样是为了消除配置顺序给测试带来的影响

nginx 配置匹配规则 nginx server匹配_nginx 配置匹配规则_04

访问测试

nginx 配置匹配规则 nginx server匹配_正则匹配_05

结论:通配符在前的优先级高于在后的

 3、第三优先级:通配符在后

修改server配置,还是2个server,通配符在后的server放到前面,同样是为了消除配置顺序给测试带来的影响

nginx 配置匹配规则 nginx server匹配_nginx_06

访问测试

nginx 配置匹配规则 nginx server匹配_nginx_07

结论:通配符在后的优先级高于正则匹配的server

到此,第一部分的匹配规则已经验证完毕。接下来验证都不匹配的情况

4、listen配置项中default的影响

配置3个server

nginx 配置匹配规则 nginx server匹配_正则匹配_08

访问测试

nginx 配置匹配规则 nginx server匹配_正则匹配_09

结论:正则匹配虽然优先级较低,但是仍然高于default;在都匹配不到的情况下,default开始起作用。

5、验证default的作用域,default在匹配成功的情况下是否会影响优先级

2个server,给优先级低的server配置default属性

nginx 配置匹配规则 nginx server匹配_正则匹配_10

访问测试

nginx 配置匹配规则 nginx server匹配_正则匹配_11

结论:default只能作用于匹配不到的情况下,而且nginx.conf不可以配多个default,否则nginx重启时候会提示错误

nginx 配置匹配规则 nginx server匹配_nginx 配置匹配规则_12

6、验证没有匹配成功,且没有default的情况

2个server

nginx 配置匹配规则 nginx server匹配_优先级_13

访问测试

nginx 配置匹配规则 nginx server匹配_nginx 配置匹配规则_14

结论:在server_name都匹配失败的前提下,并且listen没有default属性,那么端口号和server的顺序将发挥作用,它会去找端口匹配的位置最靠前的server。

最终的结论就是开头的这段话:

1、完全匹配

2、通配符在前的,如*.test.com

3、在后的,如www.test.*

4、正则匹配,如~^\.www\.test\.com$

如果都不匹配

1、优先选择listen配置项后有default或default_server的

2、找到匹配listen端口的第一个server块

 

 

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid             /var/run/nginx.pid;


events {
        worker_connections  1024;
}


http {
        include    /etc/nginx/mime.types;
        default_type  application/octet-stream;

        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                                          '$status $body_bytes_sent "$http_referer" '
                                          '"$http_user_agent" "$http_x_forwarded_for"';

        access_log  /var/log/nginx/access.log  main;

        sendfile                on;
        #tcp_nopush      on;

        keepalive_timeout  65;

        #gzip  on;

        include /etc/nginx/conf.d/*.conf;

        server {
                listen 80;
                server_name ~^\w+\.\w+$;

                location / {
                        default_type font/woff;
                        root /web/d;
                }
        }

        server {
                listen 80;
                server_name b.*;

                location / {
                        default_type text/xml;
                        root /web/c;
                }
        }

        server {
                listen 80;
                server_name *.bb;

                location / {
                        default_type text/html;
                        root /web/a;
                }
        }

        server {
                listen 80 default;
                server_name bb.bb;

                location / {
                        default_type text/plain;
                        root /web/b;
                }

        }


}