nginx之location配置

[TOC]

location理论基础

语法介绍

语法

location [ = | ~ | ~* | ^~ ] uri { ... }

路径匹配

以何开头 匹配功能
= 表示精确匹配,只有请求的URL完全相等才会被匹配,匹配成功则立即停止搜索
~ 表示区分大小写的正则匹配
~* 表示不区分大小写的正则匹配
^~ 表示url以某个字符串开头,不是正则匹配,属于前缀字符串
/ 表示通用匹配,如果没有其它匹配,任何请求都会匹配到,属于前缀字符串

测试过程

  • = 表示精确匹配
#.测试配置
location = /test {
    #.精确匹配
    return 200 "hello";
}

#.测试结果
curl http://127.0.0.1/test      ok
curl http://127.0.0.1/test/     not ok
curl http://127.0.0.1/test2     not ok
curl http://127.0.0.1/test/2    not ok
  • ~ 表示区分大小写的正则匹配
#.测试配置
location ~ ^/test$ {
    #.区分大小写
    return 200 "hello";
}

#.测试结果
curl http://127.0.0.1/test      ok
curl http://127.0.0.1/Test      not ok
curl http://127.0.0.1/test/     not ok
curl http://127.0.0.1/test2     not ok
  • ~* 表示不区分大小写的正则匹配
#.测试配置
location ~* ^/test$ {
    #.不区分大小写
    return 200 "hello";
}

#.测试结果
curl http://127.0.0.1/test      ok
curl http://127.0.0.1/Test      ok
curl http://127.0.0.1/test/     not ok
curl http://127.0.0.1/test2     not ok
  • ^~ 表示url以某个字符串开头
#.测试配置
location ^~ ^/images/ {
    #.url以某个字符串开头
    return 200 "hello";
}

#.测试结果
curl http://127.0.0.1/images/1.jpg      ok
  • / 表示通用匹配
#.测试配置1
location / {
    #.通用匹配
    return 200 "hello";
}

#.测试结果1
curl http://127.0.0.1/index.html    ok



#.测试配置2
location /test {
    #.通用匹配
    return 200 "hello";
}

#.测试结果2
curl http://127.0.0.1/test      ok
curl http://127.0.0.1/test2     ok
curl http://127.0.0.1/test/     ok
curl http://127.0.0.1/Test      not ok

匹配顺序

Location的定义分为两种

  • 前缀字符串(prefix string),包括 完整路径部分起始路径
  • 正则表达式(regular expression),具体为前面带 ~*~ 修饰符的

在顺序上

  • 前缀字符串顺序不重要,按照匹配长度来确定
  • 正则表达式则按照定义顺序,先匹配到则先返回

在优先级上

  • 精确= > 完整路径 > 前缀^~ > 正则~,~* > 部分起始路径 > 通用/

测试过程

  • 场景1:如下配置,虽然 /doc 也能匹配到,但在顺序上,前缀字符串顺序不重要,按照匹配长度来确定
#.测试配置
server {
    location /doc {
        return 200 "ResultA";
    }
    location /docu {
        return 200 "ResultB";
    }
}

#.测试结果
curl http://127.0.0.1/document  匹配结果  ResultB
  • 场景2:如下配置,虽然 ~ ^/docu 也能匹配到,但 正则表达式则按照定义顺序,先匹配到则先返回
#.测试配置
server {
    location ~ ^/doc {
        return 200 "ResultA";
    }
    location ~ ^/docu {
        return 200 "ResultB";
    }
}

#.测试结果
curl http://127.0.0.1/document  匹配结果  ResultA
  • 场景3:如下配置,虽然正则表达式 ~ ^/docu 也能匹配到,但 前缀字符串 ^~ 的优先级更高
#.测试配置
server {
    location ^~ /doc {
        # 前缀字符串 ^~ 表示 url 以某个字符串开头
        return 200 "ResultA";
    }
    location ~ ^/docu {
        # 正则表达式 ~ 表示区分大小写
        return 200 "ResultB";
    }
}

#.测试结果
curl http://127.0.0.1/document  匹配结果  ResultA
  • 场景4:如下配置,虽然前缀字符串 /document 也能匹配到,但 正则表达式 ~ 的优先级更高
#.测试配置
server {
    location /document {
        # 前缀字符串 / 表示通用匹配
        return 200 "ResultA";
    }
    location ~ ^/docu {
        # 正则表达式 ~ 表示区分大小写
        return 200 "ResultB";
    }
}

#.测试结果
curl http://127.0.0.1/document  匹配结果  ResultB

root 与 alias 的区别

配置如下2个location

location ^~ /tea/ {
    root /data/html;
}

location ^~ /sta/ {
    alias /data/static;
}
  • 访问 http://test.com/tea/tea1.html >> /data/html/tea/tea1.html
  • 访问 http://test.com/sta/sta1.html >> /data/static/sta1.html

两者的区别

  • root 实际访问文件路径会拼接 root + location
  • alias 实际访问文件路径不会拼接location中的路径

server 和 location 中的 root

  • server 和 location 中都可以使用 root,如下所示,哪个优先级更高呢?
server {
    listen 80;
    server_name localhost;
    root /data/app/;
    location / {
        root /data/web/;
        index index.html;
    }
}
  • 简单的来说,就是 就近原则,如果 location 中能匹配到,就是用 location 中的 root 配置,忽略 server 中的 root
  • 当 location 中匹配不到的时候,则使用 server 中的 root 配置。

实战配置

注意配置表达式重复

  • 如下配置,若将前缀字符串中的 location /api 改成 location /api/ 则会报错,nginx: [emerg] duplicate location "/api/"
server {
    listen 80;

    location ^~ /api/ {
        # 正则表达式,匹配任何以 /api/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条
        return 200 "ResultA";
    }

    location /api {
        # 前缀字符串,匹配以 /api 开头的地址,优先级没有上面的正则表达式高
        return 200 "ResultB";
    }
}

通过location实现流量分流

  • 场景:假设某网站的请求过大导致卡顿,需要对2个流量较大的子目录做分流,需求如下:
用户访问 https://xxx.com        则流量转到  节点1或节点2
用户访问 https://xxx.com/match  则流量转到  http://节点3:8187/match
用户访问 https://xxx.com/images 则流量转到  https://节点4:443/images
  • 为了达到上述效果,可以配置如下:
http {
    #.其他省略
    upstream myservers {
        server 10.30.3.201:443 max_fails=5 fail_timeout=300s weight=10;
        server 10.30.3.202:443 max_fails=5 fail_timeout=300s weight=10;
    }

    server {
        listen 443 ssl;
        server_name xxx.com;

        ssl_certificate     /usr/local/nginx/conf/ssl/xxx.com.pem;
        ssl_certificate_key /usr/local/nginx/conf/ssl/xxx.com.key;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        location / {                    #.首页
            index index.html index.htm index.php;
            proxy_timeout 300s;
            proxy_pass https://myservers;

            #.供下面参考
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Host $http_host;
            proxy_set_header X-NginX-Proxy true;
            proxy_set_header Connection "";
            proxy_http_version 1.1;
        }

        location ^~ /match {            #.match站点
            proxy_timeout 300s;
            proxy_pass http://10.30.3.203:8187/match/;
            #.其他参考上面
        }

        location ^~ /images {           #.images站点
            proxy_timeout 300s;
            proxy_pass https://10.30.3.204:443/images/;
            #.其他参考上面
        }
    }
}
Copyright © www.sqlfans.cn 2023 All Right Reserved更新时间: 2024-06-25 15:21:38

results matching ""

    No results matching ""