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 路由优先级
当多个路由规则同时匹配一个请求时,网关必须通过优先级机制决定最终使用哪一条。优先级规则通常遵循以下原则:
- 显式优先级优先: 路由表中
Priority字段数值越小,优先级越高。例如 Priority=1 的路由优先于 Priority=10 的路由。 - 路径精确度优先: 在未显式配置优先级时,路径匹配越精确,优先级越高。例如
/api/user/login(精确匹配)优先于/api/user/**(前缀匹配)。 - 配置顺序优先: 当显式优先级和路径精确度都无法区分时,路由表中先配置的规则优先匹配。
常见陷阱: 很多团队在配置灰度路由时,将灰度版本路由的优先级设置得比正式版本低,导致灰度请求被正式路由“截胡”。正确的做法是:灰度路由优先级应高于正式路由,确保特殊条件先被匹配。
下图展示了路由匹配与优先级决策的完整流程:
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)。
最佳实践: 建议为每条路由显式设置优先级,避免依赖默认的“配置顺序”规则。显式优先级使路由表的行为更可预测,也便于后续维护和审计。