路由决策的本质:一场关于「谁来做」的选择题

路由决策,说白了就是一道选择题。

订单来了,到底交给哪个渠道去处理?

我刚开始做支付系统时,觉得这事特简单——哪个渠道便宜就用哪个呗。后来被现实狠狠教育了一回。有一次某个银行渠道突然延迟飙升,所有订单都往另一个渠道涌,结果那个渠道直接被打挂了。嗯,路由决策远没你想的那么简单。

它的本质是什么?在多个候选渠道中,根据当前状态和业务规则,选出一个最优解

这个「最优」的定义,取决于你的业务目标:

  • 想省钱?选费率最低的
  • 想提高成功率?选最近成功率最高的
  • 想平衡负载?选当前压力最小的

但现实往往是——这些目标互相打架。你想想看,最便宜的渠道可能成功率最低,成功率最高的可能贵得离谱。所以路由决策本质上是一个多目标优化问题

核心观点:路由决策不是简单的「选一个」,而是在成本、成功率、时效、合规等多个维度之间找平衡点。

确定性路由 vs 概率路由:两种截然不同的思路

确定性路由:我说了算

确定性路由,就是按照固定的规则,每次都能唯一确定走哪个渠道。

举个例子:

// 确定性路由伪代码
if (amount < 1000) {
    channel = "A银行";
} else if (amount < 5000) {
    channel = "B银行";
} else {
    channel = "C银行";
}

这种方式的优点很明显:可预测、易排查。出问题了,顺着规则查就行。

缺点呢?太死板。我在项目中遇到过,某个渠道白天表现很好,晚上就卡得要命。但确定性路由不会管这些,它只看金额。

概率路由:让运气说话

概率路由就不一样了。它给每个渠道分配一个权重,然后按权重随机选。

// 概率路由伪代码
channels = [
    {"name": "A银行", "weight": 0.6},
    {"name": "B银行", "weight": 0.3},
    {"name": "C银行", "weight": 0.1}
];

// 按权重随机选择
selected = weightedRandom(channels);

为什么要用概率?

  • 灰度发布:新渠道先给 5% 的流量试试水
  • 负载均衡:避免所有流量都挤到一个渠道
  • A/B 测试:对比不同渠道的效果

我的经验:概率路由不是真随机,而是「伪随机+一致性」。同一个用户、同一笔订单,应该路由到同一个渠道。否则会出现「用户第一次支付成功,第二次却失败」的尴尬情况。

两者怎么选?

维度 确定性路由 概率路由
可预测性
灵活性
适合场景 规则明确、变化少 灰度发布、负载均衡
排查难度 容易 较难

我个人习惯的做法是:先用确定性路由兜底,再用概率路由做微调。比如,金额小于 1000 的订单走 A 渠道,这是确定性规则。但 A 渠道的流量中,再拿出 10% 去测试新渠道 B,这就是概率路由。

路由表设计原则:别让路由表成为你的噩梦

路由表,就是路由决策的「规则库」。我见过最夸张的路由表,有 2000 多条规则,维护它的人已经离职三年了,没人敢动。

为什么会这样?因为路由表设计没做好。

原则一:规则要分层

别把所有规则都塞到一个大表里。分层设计:

  • 第一层:全局规则(所有订单都适用)
  • 第二层:商户规则(针对特定商户)
  • 第三层:用户规则(针对特定用户群体)

这样设计的好处是:上层规则优先,下层规则兜底。改规则时,影响范围可控。

原则二:规则要可配置

我曾经遇到一个项目,路由规则写死在代码里。每次改规则都要发版,运维同学都快疯了。

路由表一定要做成可配置的

// 路由表配置示例(JSON格式)
{
    "rules": [
        {
            "id": "rule_001",
            "priority": 1,
            "condition": {
                "amount_range": [0, 1000],
                "channel_type": "bank"
            },
            "action": {
                "channel": "A银行",
                "weight": 1.0
            }
        },
        {
            "id": "rule_002",
            "priority": 2,
            "condition": {
                "amount_range": [1000, 5000],
                "channel_type": "bank"
            },
            "action": {
                "channel": "B银行",
                "weight": 0.7
            }
        }
    ]
}

避坑指南:我曾经把路由表存在数据库里,每次请求都查一次库。结果高峰期数据库扛不住了。后来改成缓存+本地文件的方式,性能提升了 10 倍。

原则三:规则要有优先级

多条规则可能同时匹配,这时候谁说了算?

必须给每条规则设置优先级。优先级高的先执行,匹配到了就直接返回,不再往下走。

这有点像 Java 里的 switch-case,但比它灵活得多。

原则四:规则要可回滚

改路由表就像改代码,随时可能出问题。所以:

  • 每次修改都要记录版本号
  • 支持一键回滚到上一个版本
  • 修改前要模拟验证,别直接上线

路由决策的核心流程(SVG 图)

下面这张图,是我做路由系统时画的。它展示了路由决策的完整流程:

路由决策核心流程 订单请求 规则匹配(分层匹配) 是否命中规则? 执行路由动作 走默认路由 路由结果 图1:路由决策流程示意图

这个流程看起来简单,但实际落地时坑很多。比如规则匹配的顺序、缓存策略、异常处理等等。后面几章我会详细讲。

一个小建议:刚开始做路由系统时,别想着一步到位。先实现一个简单的确定性路由,跑通了再加概率路由。我见过太多人一上来就想搞「智能路由」,结果连基础功能都没做好。

好了,路由决策的本质、两种路由方式、路由表设计原则,这些就是本章的核心内容。下一章我们聊聊路由算法的具体实现,包括权重计算、动态调整这些实战技巧。


公众号:蓝海资料掘金营,微信deep3321