3. 路由分发基本原理

路由分发是 API Gateway 的核心职能,它决定了“一个请求到达网关后,应该转发给哪个后端微服务”。理解路由表结构、匹配规则与优先级机制,是正确配置网关接入的基础。本章从这三个维度展开,帮助你在实际项目中设计出清晰、可维护的路由策略。

3.1 路由表结构

路由表是网关内部维护的一组有序规则集合,每条规则定义了一组匹配条件与一个目标后端。典型的单条路由条目包含以下核心字段:

字段 类型 说明 示例
ID String 路由唯一标识 route-user-v1
Path String 请求路径匹配模式 /api/user/**
Method Set<String> 允许的 HTTP 方法 GET, POST
Headers Map<String, String> 请求头匹配条件 X-Version: v2
Target URI 后端服务地址 lb://user-service
Priority Integer 路由优先级(数值越小越优先) 10
Filters List<String> 关联的过滤器链 rate-limit, auth
设计建议: 路由 ID 应具备可读性,推荐使用 {领域}-{版本}-{序号} 的命名规范,便于运维人员快速定位问题。

路由表在网关启动时加载到内存中,通常以 有序列表 或 前缀树(Trie) 的形式存储。前缀树结构在路径匹配场景下具有 O(L) 的时间复杂度(L 为路径长度),适合高并发场景。

3.2 匹配规则

网关支持多维度的请求匹配,常见的匹配维度包括路径、HTTP 方法和请求头。匹配过程遵循“与(AND)”逻辑——所有条件同时满足才算匹配成功。

3.2.1 路径匹配

路径匹配是最基础也是最常用的规则。主流网关支持以下三种路径模式:

  • 精确匹配: /api/user/login —— 仅匹配该完整路径。
  • 前缀匹配: /api/user/** —— 匹配以 /api/user/ 开头的所有路径。
  • 参数化匹配: /api/user/{id} —— 匹配 /api/user/123,并将 id 提取为路径参数。
避坑指南: 前缀匹配中的 ** 与 * 含义不同。** 匹配多级路径(如 /a/b/c),而 * 仅匹配单级路径(如 /a)。配置时请根据实际需求选择。

3.2.2 方法匹配

方法匹配用于限制请求的 HTTP 动词。常见用法包括:

  • 单方法: GET —— 只允许 GET 请求。
  • 多方法: GET, POST, PUT —— 允许列表中的多个方法。
  • 全匹配: 不配置方法字段,默认匹配所有 HTTP 方法。

3.2.3 Header 匹配

Header 匹配用于实现灰度发布、版本路由、A/B 测试等高级场景。常见的匹配方式包括:

匹配方式 配置示例 说明
精确匹配 X-Version: v2 Header 值必须完全等于 v2
正则匹配 X-Region: ^cn-.* Header 值匹配正则表达式
存在性匹配 X-Canary 只要请求包含该 Header 即匹配
前缀匹配 X-Lang: zh* Header 值以指定前缀开头

3.3 路由优先级

当多个路由规则同时匹配一个请求时,网关必须通过优先级机制决定最终使用哪一条。优先级规则通常遵循以下原则:

  1. 显式优先级优先: 路由表中 Priority 字段数值越小,优先级越高。例如 Priority=1 的路由优先于 Priority=10 的路由。
  2. 路径精确度优先: 在未显式配置优先级时,路径匹配越精确,优先级越高。例如 /api/user/login(精确匹配)优先于 /api/user/**(前缀匹配)。
  3. 配置顺序优先: 当显式优先级和路径精确度都无法区分时,路由表中先配置的规则优先匹配。
常见陷阱: 很多团队在配置灰度路由时,将灰度版本路由的优先级设置得比正式版本低,导致灰度请求被正式路由“截胡”。正确的做法是:灰度路由优先级应高于正式路由,确保特殊条件先被匹配。

下图展示了路由匹配与优先级决策的完整流程:

路由匹配与优先级决策流程 请求到达网关 按优先级顺序遍历路由表 路径 / 方法 / Header 匹配 匹配成功 → 执行转发 匹配失败 → 继续下一条 遍历下一条路由 全部匹配失败 → 返回 404 说明:优先级数值越小越优先;精确路径匹配优先于前缀匹配;灰度路由应配置更高优先级

3.4 综合匹配示例

以下是一个实际的路由表配置示例,展示了多维度匹配与优先级协同工作的场景:

# 路由表配置(YAML 格式)
routes:
  - id: user-gray-v2
    path: /api/user/**
    method: GET
    headers:
      X-Version: v2
    target: lb://user-service-v2
    priority: 1

  - id: user-stable
    path: /api/user/**
    method: GET
    target: lb://user-service-v1
    priority: 10

  - id: user-admin
    path: /api/user/admin
    method: POST
    target: lb://admin-service
    priority: 5

在这个示例中:

  • 当请求 GET /api/user/profile 携带 X-Version: v2 时,匹配 user-gray-v2(优先级 1),转发到 v2 服务。
  • 当请求 GET /api/user/profile 不携带版本头时,匹配 user-stable(优先级 10),转发到 v1 服务。
  • 当请求 POST /api/user/admin 时,虽然路径前缀也匹配前两条路由,但方法不匹配,最终匹配 user-admin(优先级 5)。
最佳实践: 建议为每条路由显式设置优先级,避免依赖默认的“配置顺序”规则。显式优先级使路由表的行为更可预测,也便于后续维护和审计。