02 nginx 中几种 location 表达式的优先级问题

Posted 蓝风9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了02 nginx 中几种 location 表达式的优先级问题相关的知识,希望对你有一定的参考价值。

前言

// 无论贫穷富贵, 家能给与我们的都是一样的 

呵呵 这是一个 老生常谈的问题 

从官方文档, 或者 各种博客 中都可以找到这个问题的相关描述 

我们这里 只关注 location 上面的这五种写法, 不关注 location @name 

可以看到的是 存在五种写法 

从下面文档也可以看出 优先级大概是 精确匹配 > 前缀匹配2 > 正则匹配, 忽略大小写正则匹配 > 前缀匹配1 

我们这里 核心关注的就是 这个顺序是如何实现的?

以下截图, 调试基于 nginx-1.18.0

location /api       // 前缀匹配1
location = /api     // 精确匹配
location ^~ /api    // 前缀匹配2
location ~ /api     // 正则匹配
location ~* /api    // 忽略大小写正则匹配

测试用例 

这里构造了一下 几种 location 都存在的配置 

    server 
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / 
            root   html;
            index  index.html index.htm;
        

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html 
            root   html;
        

        location ^~ /api/ 
               root html; 
               index  index.html index.htm;
               proxy_pass http://localhost:8080/;
        

        location = /exactly.html 
               root html/exactly;
               index  index.html index.htm;
        

        location ^~ /exactly.html 
               root html/exactly;
               index  index.html index.htm;
        

        location ~ /regex.* 
               root html/regex;
               index  index.html index.htm;
        

        location ~* /RgxIgnoreCase.* 
               root html/regexIgnoreCase;
               index  index.html index.htm;
        

    

ngx_http_core_find_location 

这个函数是 查询 location 的主要驱动 

ngx_http_core_find_static_location 是查询前缀匹配相关的 locations 

pclcf->regex_locations 是查询正则匹配相关的 locations 

首先是查询 前缀匹配相关的 locations 

如果是 匹配到 "location =", ngx_http_core_find_static_location 响应的是 NGX_OK, 这里直接响应 匹配到的结果, 速度最快 

如果是 匹配到 "location ~^", ngx_http_core_find_static_location 响应的是 NGX_AGAIN | NGX_DECLINED, 但是它的 noregex 为 1, 因此 会跳过后面的 正则匹配相关 

如果 匹配到  "location ", ngx_http_core_find_static_location 响应的是 NGX_AGAIN | NGX_DECLINED, 但是它的 noregex 为 0, 因此 如果接下来会尝试正则匹配, 如果匹配上使用 正则的结果, 如果匹配不上, 使用 "location " 匹配到的结果 

如果 匹配到 "location ~", "location ~*", 那么走的是 下面的正则匹配相关, 结果为 正则匹配到的 loc_conf 

ngx_http_core_find_static_location 这里面就是根据当前 uri 和前缀树进行匹配 

如果是 uri 和 node->name 不匹配, 则根据大小 向左或者向右 迭代 node 节点 

否则 uri 是 node->name 的一部分, 或者 node->name 是 uri 的一部分, 或者 完全匹配

如果 node->name 是 uri 的一部分, 继续向右迭代, 保留当前记录作为 最长匹配

如果 node->name 和 uri 完全匹配, 如果存在精确匹配, 则返回 NGX_OK 

        如果是 其他前缀匹配, 则记录当前记录作为最长匹配

如果 uri 是 node->name 的一部分, 继续向左迭代 

        这里有一个 auto_redirect 的配置是使用于 uri 为 "/api", 然后存在 "location /api/", "location ^~ /api/" 的场景, 这里之所以没有校验配置的最后一位为 "/", 是一位配置 auto_redirect 的地方会进行校验 

对应于这里前缀匹配有 "location /", "location = /50x.html", "location ^~ /api/", "location = /exactly.html", "location ^~ /exactly.html"

构造出来的匹配树如下 

# pclcf->static_locations 的 pattern 树如下
/ -> null, "/api/", null
"/api/" -> "/50x.html", null, "/exactly.html"

(gdb) print pclcf->static_locations
$16 = (ngx_http_location_tree_node_t *) 0x7fa048023f10
(gdb) print pclcf->static_locations->name
$17 = "/"
(gdb) print pclcf->static_locations->left
$18 = (ngx_http_location_tree_node_t *) 0x0
(gdb) print pclcf->static_locations->tree
$19 = (ngx_http_location_tree_node_t *) 0x7fa048023f40
(gdb) print pclcf->static_locations->right
$20 = (ngx_http_location_tree_node_t *) 0x0

(gdb) print pclcf->static_locations->tree->name
$21 = "a"
(gdb) print pclcf->static_locations->tree->left
$22 = (ngx_http_location_tree_node_t *) 0x7fa048023f70
(gdb) print pclcf->static_locations->tree->tree
$23 = (ngx_http_location_tree_node_t *) 0x0
(gdb) print pclcf->static_locations->tree->right
$24 = (ngx_http_location_tree_node_t *) 0x7fa048023fa8

(gdb) print pclcf->static_locations->tree->left->name
$25 = "5"
(gdb) print pclcf->static_locations->tree->left->left
$26 = (ngx_http_location_tree_node_t *) 0x0
(gdb) print pclcf->static_locations->tree->left->tree
$27 = (ngx_http_location_tree_node_t *) 0x0
(gdb) print pclcf->static_locations->tree->left->right
$28 = (ngx_http_location_tree_node_t *) 0x0

(gdb) print pclcf->static_locations->tree->right->name
$29 = "e"
(gdb) print pclcf->static_locations->tree->right->left
$30 = (ngx_http_location_tree_node_t *) 0x0
(gdb) print pclcf->static_locations->tree->right->tree
$31 = (ngx_http_location_tree_node_t *) 0x0
(gdb) print pclcf->static_locations->tree->right->right
$32 = (ngx_http_location_tree_node_t *) 0x0




(gdb) print pclcf->static_locations->exactly->name
There is no member named exactly.
(gdb) print pclcf->static_locations->inclusive->name
$33 = len = 1, data = 0x7fa04800f7fe "/"
(gdb) print pclcf->static_locations->exact->name
Cannot access memory at address 0x0
(gdb) print pclcf->static_locations->tree->exact->name
Cannot access memory at address 0x0
(gdb) print pclcf->static_locations->tree->inclusive->name
$34 = len = 5, data = 0x7fa048007a94 "/api/"
(gdb) print pclcf->static_locations->tree->left->exact->name
$35 = len = 9, data = 0x7fa048006653 "/50x.html"
(gdb) print pclcf->static_locations->tree->left->inclusive->name
Cannot access memory at address 0x0
(gdb) print pclcf->static_locations->tree->right->exact->name
$36 = len = 13, data = 0x7fa048008feb "/exactly.html"
(gdb) print pclcf->static_locations->tree->right->inclusive->name
$37 = len = 13, data = 0x7fa04801d8ec "/exactly.html"

location = /exactly.html 

Breakpoint 2, ngx_http_core_find_static_location (r=0x7fa049800050, 
    node=0x7fa048023fa8) at src/http/ngx_http_core_module.c:1509
1509	            if (node->exact) 
(gdb) print node
$38 = (ngx_http_location_tree_node_t *) 0x7fa048023fa8
(gdb) print node->exact->name
$39 = len = 13, data = 0x7fa048008feb "/exactly.html"
(gdb) print r.uri
$40 = len = 13, data = 0x7fa04b800004 "/exactly.html HTTP/1.1\\r\\nHost"
(gdb) next
1510	
(gdb) next
1511	
(gdb) next
1530	
(gdb) next
ngx_http_core_find_location (r=0x7fa049800050) at src/http/ngx_http_core_module.c:1393
1393	    if (rc == NGX_AGAIN) 
(gdb) next
1406	    if (rc == NGX_OK || rc == NGX_DONE) 
(gdb) next
1407	        return rc;
(gdb) bt
#0  ngx_http_core_find_location (r=0x7fa049800050)
    at src/http/ngx_http_core_module.c:1407
#1  0x0000000107d22f03 in ngx_http_core_find_config_phase (r=0x7fa049800050, 
    ph=0x7fa048025258) at src/http/ngx_http_core_module.c:953
#2  0x0000000107d22d3e in ngx_http_core_run_phases (r=0x7fa049800050)
    at src/http/ngx_http_core_module.c:868
#3  0x0000000107d22cae in ngx_http_handler (r=0x7fa049800050)
    at src/http/ngx_http_core_module.c:851
#4  0x0000000107d31f36 in ngx_http_process_request (r=0x7fa049800050)
    at src/http/ngx_http_request.c:2060
#5  0x0000000107d3407a in ngx_http_process_request_headers (rev=0x107ee40d0)
    at src/http/ngx_http_request.c:1480
#6  0x0000000107d33415 in ngx_http_process_request_line (rev=0x107ee40d0)
    at src/http/ngx_http_request.c:1151
#7  0x0000000107d35979 in ngx_http_keepalive_handler (rev=0x107ee40d0)
    at src/http/ngx_http_request.c:3333
#8  0x0000000107d1cc10 in ngx_kqueue_process_events (cycle=0x7fa048800c50, 
    timer=55093, flags=1) at src/event/modules/ngx_kqueue_module.c:669
#9  0x0000000107d0c9f6 in ngx_process_events_and_timers (cycle=0x7fa048800c50)
    at src/event/ngx_event.c:247
#10 0x0000000107d1aac5 in ngx_worker_process_cycle (cycle=0x7fa048800c50, data=0x0)
    at src/os/unix/ngx_process_cycle.c:750
#11 0x0000000107d17cfa in ngx_spawn_process (cycle=0x7fa048800c50, 
    proc=0x107d1aa10 <ngx_worker_process_cycle>, data=0x0, 
    name=0x107de2a1e "worker process", respawn=-3) at src/os/unix/ngx_process.c:199
#12 0x0000000107d19be7 in ngx_start_worker_processes (cycle=0x7fa048800c50, n=1, 
    type=-3) at src/os/unix/ngx_process_cycle.c:359
#13 0x0000000107d19558 in ngx_master_process_cycle (cycle=0x7fa048800c50)
    at src/os/unix/ngx_process_cycle.c:131
#14 0x0000000107cd18ba in main (argc=3, argv=0x7ffee7f2f548) at src/core/nginx.c:382

location ^~ /api/

请注意下面 noregex 为 1, 不进行正则匹配 

Breakpoint 3, ngx_http_core_find_static_location (r=0x7fa049804c50, 
    node=0x7fa048023f10) at src/http/ngx_http_core_module.c:1464
(gdb) print r->uri
$47 = len = 37, 
  data = 0x7fa049800004 "/api/HelloWorld/listFormWithoutHeader HTTP/1.1\\r\\nHost"
1464	    rv = NGX_DECLINED;
(gdb) next
1468	        if (node == NULL) 
(gdb) next
1476	        n = (len <= (size_t) node->len) ? len : node->len;
(gdb) print node->name
$44 = "/"
(gdb) next
1478	        rc = ngx_filename_cmp(uri, node->name, n);
(gdb) next
1480	        if (rc != 0) 
(gdb) next
1486	        if (len > (size_t) node->len) 
(gdb) next
1488	            if (node->inclusive) 
(gdb) next
1490	                r->loc_conf = node->inclusive->loc_conf;
(gdb) next
1491	                rv = NGX_AGAIN;
(gdb) next
1493	                node = node->tree;
(gdb) next
1494	                uri += n;
(gdb) next
1495	                len -= n;
(gdb) next
1497	                continue;
(gdb) next
1468	        if (node == NULL) 
(gdb) next
1476	        n = (len <= (size_t) node->len) ? len : node->len;
(gdb) print node->name
$45 = "a"
(gdb) next
1478	        rc = ngx_filename_cmp(uri, node->name, n);
(gdb) next
1480	        if (rc != 0) 
(gdb) next
1486	        if (len > (size_t) node->len) 
(gdb) next
1488	            if (node->inclusive) 
(gdb) next
1490	                r->loc_conf = node->inclusive->loc_conf;
(gdb) next
1491	                rv = NGX_AGAIN;
(gdb) next
1493	                node = node->tree;
(gdb) next
1494	                uri += n;
(gdb) next
1495	                len -= n;
(gdb) next
1497	                continue;
(gdb) next
1468	        if (node == NULL) 
(gdb) next
1469	            return rv;
(gdb) next
1530	
(gdb) next
ngx_http_core_find_location (r=0x7fa049804c50) at src/http/ngx_http_core_module.c:1393
1393	    if (rc == NGX_AGAIN) 
(gdb) next
1396	        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
(gdb) next
1398	        noregex = clcf->noregex;
(gdb) next
1403	        rc = ngx_http_core_find_location(r);
(gdb) print noregex
$46 = 1
(gdb) next

Breakpoint 3, ngx_http_core_find_static_location (r=0x7fa049804c50, node=0x0)
    at src/http/ngx_http_core_module.c:1464
1464	    rv = NGX_DECLINED;
(gdb) next
1468	        if (node == NULL) 
(gdb) next
1469	            return rv;
(gdb) next
1530	
(gdb) next
ngx_http_core_find_location (r=0x7fa049804c50) at src/http/ngx_http_core_module.c:1393
1393	    if (rc == NGX_AGAIN) 
(gdb) next
1406	    if (rc == NGX_OK || rc == NGX_DONE) 
(gdb) next
1414	    if (noregex == 0 && pclcf->regex_locations) 
(gdb) next
1442	    return rc;
(gdb) bt
#0  ngx_http_core_find_location (r=0x7fa049804c50)
    at src/http/ngx_http_core_module.c:1442
#1  0x0000000107d23366 in ngx_http_core_find_location (r=0x7fa049804c50)
    at src/http/ngx_http_core_module.c:1403
#2  0x0000000107d22f03 in ngx_http_core_find_config_phase (r=0x7fa049804c50, 
    ph=0x7fa048025258) at src/http/ngx_http_core_module.c:953
#3  0x0000000107d22d3e in ngx_http_core_run_phases (r=0x7fa049804c50)
    at src/http/ngx_http_core_module.c:868
#4  0x0000000107d22cae in ngx_http_handler (r=0x7fa049804c50)
    at src/http/ngx_http_core_module.c:851
#5  0x0000000107d31f36 in ngx_http_process_request (r=0x7fa049804c50)
    at src/http/ngx_http_request.c:2060
#6  0x0000000107d3407a in ngx_http_process_request_headers (rev=0x107ee40d0)
    at src/http/ngx_http_request.c:1480
#7  0x0000000107d33415 in ngx_http_process_request_line (rev=0x107ee40d0)
    at src/http/ngx_http_request.c:1151
#8  0x0000000107d3076d in ngx_http_wait_request_handler (rev=0x107ee40d0)
    at src/http/ngx_http_request.c:500
#9  0x0000000107d1cc10 in ngx_kqueue_process_events (cycle=0x7fa048800c50, 
    timer=59999, flags=1) at src/event/modules/ngx_kqueue_module.c:669
#10 0x0000000107d0c9f6 in ngx_process_events_and_timers (cycle=0x7fa048800c50)
    at src/event/ngx_event.c:247
#11 0x0000000107d1aac5 in ngx_worker_process_cycle (cycle=0x7fa048800c50, data=0x0)
    at src/os/unix/ngx_process_cycle.c:750
#12 0x0000000107d17cfa in ngx_spawn_process (cycle=0x7fa048800c50, 
    proc=0x107d1aa10 <ngx_worker_process_cycle>, data=0x0, 
    name=0x107de2a1e "worker process", respawn=-3) at src/os/unix/ngx_process.c:199
#13 0x0000000107d19be7 in ngx_start_worker_processes (cycle=0x7fa048800c50, n=1, 
    type=-3) at src/os/unix/ngx_process_cycle.c:359
#14 0x0000000107d19558 in ngx_master_process_cycle (cycle=0x7fa048800c50)
    at src/os/unix/ngx_process_cycle.c:131
#15 0x0000000107cd18ba in main (argc=3, argv=0x7ffee7f2f548) at src/core/nginx.c:382
(gdb) 

location ~ /regex.* 

没有 "location =" 或者 "location ^~" 的匹配, 查询正则匹配 

Breakpoint 1, ngx_http_core_find_location (r=0x7fa04800f850)
    at src/http/ngx_http_core_module.c:1391
1391	    rc = ngx_http_core_find_static_location(r, pclcf->static_locations);
(gdb) next
1393	    if (rc == NGX_AGAIN) 
(gdb) next
1406	    if (rc == NGX_OK || rc == NGX_DONE) 
(gdb) next
1414	    if (noregex == 0 && pclcf->regex_locations) 
(gdb) next
1442	    return rc;
(gdb) next
1443	
(gdb) next
1406	    if (rc == NGX_OK || rc == NGX_DONE) 
(gdb) next
1414	    if (noregex == 0 && pclcf->regex_locations) 
(gdb) next
1416	        for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) 
(gdb) next
1421	            n = ngx_http_regex_exec(r, (*clcfp)->regex, &r->uri);
(gdb) print (*clcfp)->regex
$54 = (ngx_http_regex_t *) 0x7fa048020248
(gdb) print (*clcfp)->regex->pattern
There is no member named pattern.
(gdb) print (*clcfp)->regex->name
$55 = len = 8, data = 0x7fa04801edcb "/regex.*"
(gdb) next
1423	            if (n == NGX_OK) 
(gdb) next
1424	                r->loc_conf = (*clcfp)->loc_conf;
(gdb) next
1428	                rc = ngx_http_core_find_location(r);
(gdb) next

Breakpoint 1, ngx_http_core_find_location (r=0x7fa04800f850)
    at src/http/ngx_http_core_module.c:1391
1391	    rc = ngx_http_core_find_static_location(r, pclcf->static_locations);
(gdb) next
1393	    if (rc == NGX_AGAIN) 
(gdb) next
1406	    if (rc == NGX_OK || rc == NGX_DONE) 
(gdb) next
1414	    if (noregex == 0 && pclcf->regex_locations) 
(gdb) next
1442	    return rc;
(gdb) next
1443	
(gdb) next
1430	                return (rc == NGX_ERROR) ? rc : NGX_OK;

location ~* /RgxIgnoreCase.*

没有 "location =" 或者 "location ^~" 的匹配, 查询正则匹配 

Breakpoint 1, ngx_http_core_find_location (r=0x7fa04a004e50)
    at src/http/ngx_http_core_module.c:1391
1391	    rc = ngx_http_core_find_static_location(r, pclcf->static_locations);
(gdb) print r->uri
$56 = len = 21, data = 0x7fa04a000004 "/rgxIGNORECASExx.html HTTP/1.1\\r\\nHost"
(gdb) next
1393	    if (rc == NGX_AGAIN) 
(gdb) next
1396	        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
(gdb) next
1398	        noregex = clcf->noregex;
(gdb) next
1403	        rc = ngx_http_core_find_location(r);
(gdb) next

Breakpoint 1, ngx_http_core_find_location (r=0x7fa04a004e50)
    at src/http/ngx_http_core_module.c:1391
1391	    rc = ngx_http_core_find_static_location(r, pclcf->static_locations);
(gdb) next
1393	    if (rc == NGX_AGAIN) 
(gdb) next
1406	    if (rc == NGX_OK || rc == NGX_DONE) 
(gdb) next
1414	    if (noregex == 0 && pclcf->regex_locations) 
(gdb) next
1442	    return rc;
(gdb) next
1443	
(gdb) next
1406	    if (rc == NGX_OK || rc == NGX_DONE) 
(gdb) next
1414	    if (noregex == 0 && pclcf->regex_locations) 
(gdb) next
1416	        for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) 
(gdb) next
1421	            n = ngx_http_regex_exec(r, (*clcfp)->regex, &r->uri);
(gdb) print (*clcfp)->regex->name
$57 = len = 8, data = 0x7fa04801edcb "/regex.*"
(gdb) next
1423	            if (n == NGX_OK) 
(gdb) next
1433	            if (n == NGX_DECLINED) 
(gdb) next
1434	                continue;
(gdb) next
1416	        for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) 
(gdb) next
1421	            n = ngx_http_regex_exec(r, (*clcfp)->regex, &r->uri);
(gdb) print (*clcfp)->regex->name
$58 = len = 16, data = 0x7fa048020334 "/RgxIgnoreCase.*"
(gdb) next
1423	            if (n == NGX_OK) 
(gdb) next
1424	                r->loc_conf = (*clcfp)->loc_conf;
(gdb) next
1428	                rc = ngx_http_core_find_location(r);
(gdb) next

Breakpoint 1, ngx_http_core_find_location (r=0x7fa04a004e50)
    at src/http/ngx_http_core_module.c:1391
1391	    rc = ngx_http_core_find_static_location(r, pclcf->static_locations);
(gdb) next
1393	    if (rc == NGX_AGAIN) 
(gdb) next
1406	    if (rc == NGX_OK || rc == NGX_DONE) 
(gdb) next
1414	    if (noregex == 0 && pclcf->regex_locations) 
(gdb) next
1442	    return rc;
(gdb) next
1443	
(gdb) next
1430	                return (rc == NGX_ERROR) ? rc : NGX_OK;

location / 

找到 "location /" 的匹配, 然后尝试 查询正则匹配 

然后 没有找到 合适的正则匹配 

最终使用 "location /" 匹配 

Breakpoint 1, ngx_http_core_find_location (r=0x7fa04b004e50)
    at src/http/ngx_http_core_module.c:1391
1391	    rc = ngx_http_core_find_static_location(r, pclcf->static_locations);
(gdb) print r->uri
$59 = len = 11, data = 0x7fa04b000004 "/index.html HTTP/1.1\\r\\nHost"
(gdb) enable 3
(gdb) c
Continuing.

Breakpoint 3, ngx_http_core_find_static_location (r=0x7fa04b004e50, 
    node=0x7fa048023f10) at src/http/ngx_http_core_module.c:1464
1464	    rv = NGX_DECLINED;
(gdb) next
1468	        if (node == NULL) 
(gdb) next
1476	        n = (len <= (size_t) node->len) ? len : node->len;
(gdb) next
1478	        rc = ngx_filename_cmp(uri, node->name, n);
(gdb) next
1480	        if (rc != 0) 
(gdb) next
1486	        if (len > (size_t) node->len) 
(gdb) next
1488	            if (node->inclusive) 
(gdb) next
1490	                r->loc_conf = node->inclusive->loc_conf;
(gdb) next
1491	                rv = NGX_AGAIN;
(gdb) print node->name
$60 = "/"
(gdb) next
1493	                node = node->tree;
(gdb) next
1494	                uri += n;
(gdb) next
1495	                len -= n;
(gdb) next
1497	                continue;
(gdb) next
1468	        if (node == NULL) 
(gdb) next
1476	        n = (len <= (size_t) node->len) ? len : node->len;
(gdb) next
1478	        rc = ngx_filename_cmp(uri, node->name, n);
(gdb) print node->name
$61 = "a"
(gdb) next
1480	        if (rc != 0) 
(gdb) next
1481	            node = (rc < 0) ? node->left : node->right;
(gdb) next
1483	            continue;
(gdb) next
1468	        if (node == NULL) 
(gdb) next
1476	        n = (len <= (size_t) node->len) ? len : node->len;
(gdb) next
1478	        rc = ngx_filename_cmp(uri, node->name, n);
(gdb) print node->name
$62 = "e"
(gdb) next
1480	        if (rc != 0) 
(gdb) next
1481	            node = (rc < 0) ? node->left : node->right;
(gdb) next
1483	            continue;
(gdb) next
1468	        if (node == NULL) 
(gdb) next
1469	            return rv;
(gdb) next
1530	
(gdb) next
ngx_http_core_find_location (r=0x7fa04b004e50) at src/http/ngx_http_core_module.c:1393
1393	    if (rc == NGX_AGAIN) 
(gdb) next
1396	        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
(gdb) next
1398	        noregex = clcf->noregex;
(gdb) next
1403	        rc = ngx_http_core_find_location(r);
(gdb) next

Breakpoint 1, ngx_http_core_find_location (r=0x7fa04b004e50)
    at src/http/ngx_http_core_module.c:1391
1391	    rc = ngx_http_core_find_static_location(r, pclcf->static_locations);
(gdb) next

Breakpoint 3, ngx_http_core_find_static_location (r=0x7fa04b004e50, node=0x0)
    at src/http/ngx_http_core_module.c:1464
1464	    rv = NGX_DECLINED;
(gdb) next
1468	        if (node == NULL) 
(gdb) next
1469	            return rv;
(gdb) next
1530	
(gdb) next
ngx_http_core_find_location (r=0x7fa04b004e50) at src/http/ngx_http_core_module.c:1393
1393	    if (rc == NGX_AGAIN) 
(gdb) next
1406	    if (rc == NGX_OK || rc == NGX_DONE) 
(gdb) next
1414	    if (noregex == 0 && pclcf->regex_locations) 
(gdb) print noregex
$63 = 0
(gdb) next
1442	    return rc;
(gdb) next
1443	
(gdb) next
1406	    if (rc == NGX_OK || rc == NGX_DONE) 
(gdb) next
1414	    if (noregex == 0 && pclcf->regex_locations) 
(gdb) next
1416	        for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) 
(gdb) next
1421	            n = ngx_http_regex_exec(r, (*clcfp)->regex, &r->uri);
(gdb) print (*clcfp)->regex->name
$64 = len = 8, data = 0x7fa04801edcb "/regex.*"
(gdb) next
1423	            if (n == NGX_OK) 
(gdb) next
1433	            if (n == NGX_DECLINED) 
(gdb) next
1434	                continue;
(gdb) next
1416	        for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) 
(gdb) next
1421	            n = ngx_http_regex_exec(r, (*clcfp)->regex, &r->uri);
(gdb) (*clcfp)->regex
Undefined command: "".  Try "help".
(gdb) print (*clcfp)->regex->name
$65 = len = 16, data = 0x7fa048020334 "/RgxIgnoreCase.*"
(gdb) next
1423	            if (n == NGX_OK) 
(gdb) next
1433	            if (n == NGX_DECLINED) 
(gdb) next
1434	                continue;
(gdb) next
1416	        for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) 
(gdb) next
1439	    
(gdb) next
1442	    return rc;
(gdb) print ((ngx_http_core_loc_conf_t  *)r->loc_conf[0])->name
$66 = len = 1, data = 0x7fa04800f7fe "/"
(gdb) print rc
$67 = -5

以上是关于02 nginx 中几种 location 表达式的优先级问题的主要内容,如果未能解决你的问题,请参考以下文章

python中几种自动微分库

Nginx正则表达式location匹配Rewrite重写详解

nginx-location正则表达式匹配规则及动静分离

nginx Location正则表达式

nginx配置location [=|~|~*|^~] /uri/ { … }用法

Nginx的location匹配规则