Skip to content

分发规则匹配逻辑详解

为什么需要理解匹配逻辑

在真实的业务场景中,一个虚拟服务往往承载多种流量分发需求。例如:

  • /api/* 转发到后端应用服务器
  • /static/* 返回静态资源
  • /admin/* 需要跳转到管理后台
  • 特定域名的请求转发到特定服务器池
  • 来自某个 IP 段的请求直接拒绝

这些需求共存于同一个虚拟服务中,靠的就是多条分发规则 + 优先级 + 分发策略的组合。理解匹配逻辑,才能避免"规则写对了但效果不对"的问题。

来⾃ NGINX 的概念对照

如果您熟悉 NGINX 配置,以下对照表可以帮助快速理解矩尺平台的模型:

NGINX 概念矩尺平台对应说明
server { ... }虚拟服务定义监听 IP:端口
location /api/ { ... }分发规则(含 URL 前缀匹配策略)按 URL 路径分发
if ($host = "abc.com") { ... }分发规则(含 HOST 匹配策略)按条件匹配
if ($remote_addr ~ "10.0.0.") { ... }分发规则(含源地址匹配策略)按客户端 IP 匹配
rewrite ...七层 HTTP 策略 → 请求更改URL 重写
proxy_pass http://backend;处理方式 → HTTP 代理 + 服务器池转发到后端
root /var/www;处理方式 → 静态资源静态文件服务
return 302 ...;处理方式 → 重定向重定向响应
error_page 404 /404.html;应用失效保障页面
server 块中的多个 location多条分发规则(按优先级 + 顺序执行)多规则共存

核心区别:NGINX 通过 location 在配置文件中的书写位置和修饰符(= ~ ^~)来决定匹配优先级。矩尺平台则通过显式的优先级(高/中/低)+ URL 类型优先级 + 先后顺序三条规则来决定。

基础概念:策略与规则

在深入匹配逻辑之前,先明确两个核心概念:

分发策略:一个"条件"(匹配什么)
    ↓ 一条策略可包含多个条件(条件之间是"或"关系)
分发规则:一个"动作"(匹配后干什么)
    ↓ 一条规则可包含多条策略(策略之间是"与"关系)
虚拟服务:多条规则的容器
    ↓ 请求到达后,按优先级 + 规则匹配,找到第一条命中的规则执行

策略内的"或"关系

同一条分发策略中可以添加多个匹配条件,条件之间为**"或"**关系——只要满足其中一个即命中。

例: 源地址策略中添加了 192.168.1.0/2410.1.1.0/24 两个地址段。客户端 IP 为 192.168.1.10 时命中该策略(满足第一个地址段),客户端 IP 为 10.1.1.100 时同样命中。

源地址策略:
  ├── 192.168.1.0/24    ← 命中!
  └── 10.1.1.0/24
请求客户端 IP = 192.168.1.10  →  策略命中 ✓

规则内的"与"关系

一条分发规则可以绑定多条分发策略(不同匹配维度),策略之间为**"与"**关系——必须同时满足所有策略才命中该规则。

例: 规则绑定了 URL 前缀策略(/api/v1/)和 HOST 策略(www.abc.com)。请求必须同时满足 URL 以 /api/v1/ 开头 HOST 为 www.abc.com 才会命中。

分发规则 A:
  ├── 策略1: URL前缀匹配 = /api/v1/
  └── 策略2: HOST = www.abc.com
请求 URL = /api/v1/users,HOST = www.abc.com
  → 策略1 命中 ✓,策略2 命中 ✓ → 规则 A 命中 ✓

请求 URL = /api/v1/users,HOST = www.xyz.com
  → 策略1 命中 ✓,策略2 未命中 ✗ → 规则 A 未命中 ✗

匹配优先级总览

当同一个虚拟服务中有多条分发规则,且一个请求可能命中多条规则时,按以下层级裁决:

第一层:规则优先级(高 > 中 > 低)
    ↓ 如果同优先级有多条规则命中
第二层:URL 类型优先级(正则 > 完全匹配 > 前缀匹配)
    ↓ 如果包含 URL 策略且同类型有多条命中
第三层:配置先后顺序(UI 顺序 / API order 值)

默认分发规则:如果所有分发规则都未命中,请求将由虚拟服务的"默认分发规则"兜底处理。

下面逐层详解。

第一层:规则优先级

每条分发规则可以设置优先级:高 > 中 > 低

请求到达

  ├── 高优先级规则组:按顺序逐一匹配
  │     └── 命中? → 使用该规则的处理方式,结束匹配
  │     └── 未命中? → 继续下一个

  ├── 中优先级规则组:按顺序逐一匹配
  │     └── 命中? → 使用该规则的处理方式,结束匹配
  │     └── 未命中? → 继续下一个

  ├── 低优先级规则组:按顺序逐一匹配
  │     └── 命中? → 使用该规则的处理方式,结束匹配
  │     └── 未命中? → 继续下一个

  └── 全部未命中 → 使用默认分发规则

关键结论:高优先级规则只要命中就立即执行,不会再去尝试低优先级规则。

即使低优先级规则匹配得更精确,只要存在一条命中的高优先级规则,就会用高优先级的。

第二层:URL 类型优先级

当同一优先级下有多条规则命中时,如果这些规则都包含 URL 类型的策略,则按 URL 策略的匹配类型决定优先级:

URL 正则匹配  >  URL 完全匹配  >  URL 前缀匹配
   (最优先)                      (最靠后)

例: 三条规则都是中优先级,且都命中了同一个请求:

规则 1:URL 完全匹配 = /api/v1/login
规则 2:URL 前缀匹配 = /api/v1/
规则 3:URL 正则匹配 = /api/.*

请求 URL 为 /api/v1/login,三条规则都能命中。按 URL 类型优先级,正则 > 完全 > 前缀,所以规则 3(正则)生效。

设计建议

利用这个机制,可以将精确匹配的规则设置为较高 URL 类型优先级,宽泛匹配的规则靠后。例如:/api/v1/login 用完全匹配指向特定服务器池,/api/ 用前缀匹配指向通用服务器池,无需手动调整规则优先级。

第三层:配置先后顺序

当同一优先级、同一 URL 类型的多条规则都命中时,按照在 UI 中的先后顺序(或 API 中的 order 值,越小越先)决定:

规则 1(在前)  URL前缀 = /api/   → 先匹配 ✓
规则 2(在后)  URL前缀 = /api/   → 不执行(规则 1 已命中)

不带 URL 策略的规则之间,同样按先后顺序。

例: 两条中优先级规则都不含 URL 策略:

规则 1(在前):HTTP 方法 = POST
规则 2(在后):HOST = www.abc.com

请求同时满足 POST 方法和 HOST = www.abc.com,因为两条都不含 URL 策略,按先后顺序裁决,规则 1 生效。

NGINX 用户实战对照

场景一:多个 location

NGINX 配置:

nginx
server {
    listen 80;
    
    location = /api/v1/health {
        proxy_pass http://health_check_pool;
    }
    location ~ /api/.*/search {
        proxy_pass http://search_pool;
    }
    location /api/ {
        proxy_pass http://api_pool;
    }
    location / {
        proxy_pass http://default_pool;
    }
}

矩尺平台配置:

所有规则设为同一优先级(如中优先级),利用 URL 类型优先级自动裁决:

顺序分发策略处理方式说明
1URL 完全匹配 = /api/v1/healthHTTP代理 → health_check_pool完全匹配优先于前缀
2URL 正则匹配 = /api/.*/searchHTTP代理 → search_pool正则优先于前缀
3URL 前缀匹配 = /api/HTTP代理 → api_pool前缀匹配兜底
默认规则(无策略)HTTP代理 → default_pool对应 location /

场景二:location + if

NGINX 配置:

nginx
server {
    listen 80;
    
    location /admin/ {
        if ($remote_addr ~ "10.0.0.") {
            proxy_pass http://internal_admin;
        }
        if ($host = "public.example.com") {
            return 403;
        }
        proxy_pass http://admin_pool;
    }
    
    location / {
        proxy_pass http://default_pool;
    }
}

矩尺平台配置:

优先级分发策略处理方式说明
URL 前缀 = /admin/ + 源地址 = 10.0.0.0/8HTTP代理 → internal_admin内网IP访问admin,最高优先
URL 前缀 = /admin/ + HOST = public.example.com指定错误码 403公网域名访问admin被拒
URL 前缀 = /admin/HTTP代理 → admin_pool其余admin请求
默认规则(无策略)HTTP代理 → default_pool对应 location /

要点:将最具体的匹配条件(策略多、限制严)放在高优先级,通用匹配放在低优先级或默认规则。

场景三:多 server(多域名)

NGINX 配置:

nginx
server {
    listen 80;
    server_name api.example.com;
    location / { proxy_pass http://api_pool; }
}
server {
    listen 80;
    server_name static.example.com;
    location / { root /var/www/static; }
}
server {
    listen 80;
    server_name _;
    location / { proxy_pass http://default_pool; }
}

矩尺平台配置:

由于矩尺的虚拟服务对应 NGINX 的 server,多域名场景有两种做法:

做法一(推荐): 同一虚拟服务内用 HOST 策略区分

优先级分发策略处理方式
HOST = api.example.comHTTP代理 → api_pool
HOST = static.example.com静态资源
默认规则(无策略)HTTP代理 → default_pool

做法二: 创建多个虚拟服务,各自监听不同端口或 IP(等同于多个 server 块)。

完整实战案例

需求

某公司网站 www.example.com 需要以下流量分发:

  1. /api/v2/ → 新版后端服务(灰度中)
  2. /api/ → 旧版后端服务
  3. /static/ → 静态资源(已上传的压缩包)
  4. /admin/ → 管理后台(仅限内网 IP 10.0.0.0/8 访问,其余返回 403)
  5. 首页 / 和其余路径 → 静态资源中的 index.html(SPA 应用)

矩尺平台配置

优先级顺序分发策略处理方式说明
1URL 前缀 = /admin/ + 源地址 = 10.0.0.0/8HTTP代理 → admin_pool内网可访问管理后台
2URL 前缀 = /admin/指定错误码 403外网访问/admin/被拒
3URL 前缀 = /api/v2/HTTP代理 → api_v2_pool新版API
4URL 前缀 = /api/HTTP代理 → api_v1_pool旧版API(兜底)
5URL 前缀 = /static/静态资源 → 去前缀 /static静态文件
默认(无策略)静态资源 → 完全映射SPA:所有未匹配路径返回 index.html

关键技巧

规则 1 和 2 都是高优先级且都匹配 /admin/,通过策略的多少来区分:规则 1 多一个源地址条件,只有内网请求同时满足两个条件才命中;规则 2 没有源地址条件,任何来源的 /admin/ 请求都命中(但只有规则 1 未命中时才会轮到规则 2,因为同优先级下规则 1 先匹配)。

实际上这里规则 1 包含了 URL 策略,会先进行 URL 匹配。URL 前缀相同的情况下,按先后顺序裁决——规则 1 在前,内网 IP 请求命中规则 1(同时满足 URL 前缀 + 源地址);外网请求 URL 前缀命中但源地址未命中,规则 1 不命中,继续往下,规则 2 命中(只要求 URL 前缀)。

常见配置误区

误区正确理解
"我把精确匹配放低优先级,但它后面还有高优先级的宽泛匹配"高优先级一定先执行,与匹配精确度无关。精确匹配应当放在更高优先级
"URL 前缀 /api/ 在前,URL 完全匹配 /api/login 在后,应该后面的精确匹配生效吧?"不会。同优先级下先匹配到 /api/ 就停了。应该把完全匹配放在前缀匹配前面
"我设了多条同优先级规则,为什么总是第一条生效?"可能是因为多条规则都命中了同一个请求。检查是否有多余的策略导致误命中
"默认分发规则和普通分发规则有什么区别?"默认分发规则没有匹配条件,当所有普通规则都未命中时才执行。每个虚拟服务恰好有一条默认分发规则

调试技巧

  1. 从简到繁:先用一条规则验证单个策略是否生效,再逐步增加规则和策略
  2. 利用日志:开启虚拟服务的客户端访问日志(日志功能),通过日志查看请求实际命中了哪条分发规则
  3. 使用 curl 精确测试
bash
 # 测试特定 URL 路径
 curl -v http://10.1.9.117:80/api/v1/test
 
 # 测试特定 HOST
 curl -v -H "Host: www.abc.com" http://10.1.9.117:80/api/v1/test
 
 # 测试特定方法
 curl -v -X POST http://10.1.9.117:80/api/v1/test

分发策略的创建和配置详见 分发策略,七层分发规则的详细参数参见 七层分发规则