4. 策略与网关的联动模式:同步调用、异步事件、旁路决策
策略引擎和网关怎么配合,说白了就三种路子:同步、异步、旁路。这三种模式我都在生产环境里折腾过,各有各的脾气。今天咱们就掰开揉碎了聊聊。
4.1 同步调用模式
这是最直接的一种方式。网关收到请求,立马调策略引擎,等结果回来再决定放行还是拒绝。
核心流程:请求 → 网关 → 策略引擎 → 决策返回 → 网关执行
我在做电商平台的限流系统时,用的就是这种模式。用户下单,网关先问策略引擎:“这个用户能下单吗?”引擎查了查限流配额,说“行”,网关才放过去。
// 伪代码示例:同步调用
public Response handleRequest(Request req) {
// 1. 网关拦截请求
Decision decision = policyEngine.evaluate(req);
// 2. 根据决策执行
if (decision.isAllow()) {
return proxyToBackend(req);
} else {
return buildBlockResponse(decision.getReason());
}
}
| 优势 | 劣势 |
|---|---|
| 实时性强,决策立等可取 | 增加请求延迟(通常 1-5ms) |
| 实现简单,逻辑清晰 | 策略引擎挂了,网关也跟着瘫 |
| 适合对一致性要求高的场景 | 吞吐量受限于引擎性能 |
我曾经踩过的坑:有一次策略引擎的数据库连接池爆了,结果所有请求都在等超时,网关线程全堵死了。后来我加了熔断和降级,引擎超时就默认放行,至少保住了核心业务。
4.2 异步事件模式
这种模式就不一样了。网关不等着策略引擎出结果,而是把请求信息扔到消息队列里,先放行再说。策略引擎异步处理,事后做分析或补偿。
你想想看,什么场景适合异步?审计日志、风控分析、流量统计——这些都不需要实时阻断,但数据得完整记录下来。
// 伪代码示例:异步事件
public void onRequestReceived(Request req) {
// 1. 网关直接放行
proxyToBackend(req);
// 2. 异步发送事件
eventBus.publish(new RequestEvent(req));
}
// 策略引擎异步处理
@EventListener
public void handleRequestEvent(RequestEvent event) {
Decision decision = policyEngine.evaluate(event.getRequest());
if (decision.isBlock()) {
// 补偿操作:比如加入黑名单
blacklistService.add(event.getUserId());
}
}
| 优势 | 劣势 |
|---|---|
| 对网关性能几乎无影响 | 无法实时阻断恶意请求 |
| 策略引擎可以批量处理 | 需要处理事件丢失、重复等问题 |
| 系统解耦,各自独立扩缩容 | 补偿逻辑复杂,容易出bug |
我个人习惯:异步模式一定要加消息队列的监控。我记得有一次 Kafka 分区挂了,事件积压了半小时,风控策略全没生效。从那以后,我每个异步链路都配了告警和重试机制。
4.3 旁路决策模式
这个模式有点意思。策略引擎不直接参与网关的请求处理,而是独立运行,定期把决策结果推给网关。网关本地缓存一份策略规则,自己判断。
说白了,就是策略引擎做“幕后军师”,网关拿着“锦囊妙计”自己打。
// 策略引擎推送规则
public void pushRules() {
List<Rule> rules = policyEngine.compileRules();
gatewayClient.updateRules(rules);
}
// 网关本地执行
public Response handleRequest(Request req) {
for (Rule rule : localRules) {
if (rule.matches(req)) {
return rule.getAction().execute(req);
}
}
return proxyToBackend(req);
}
| 优势 | 劣势 |
|---|---|
| 网关处理速度极快(本地执行) | 规则更新有延迟 |
| 策略引擎故障不影响网关 | 网关内存占用增加 |
| 适合大规模分布式部署 | 规则一致性难保证 |
我曾经遇到的问题:有一次规则推送出了bug,某个IP白名单没更新到部分网关节点,结果线上误拦了半小时。后来我加了版本号和灰度推送,每次更新先推10%的节点验证。
4.4 三种模式对比
嗯,这里我把三种模式放在一起对比一下,方便你选型时参考。
| 维度 | 同步调用 | 异步事件 | 旁路决策 |
|---|---|---|---|
| 实时性 | 高 | 低 | 中(取决于更新频率) |
| 网关性能影响 | 大 | 小 | 极小 |
| 策略引擎依赖 | 强 | 弱 | 极弱 |
| 实现复杂度 | 低 | 中 | 高 |
| 典型场景 | 限流、鉴权 | 审计、风控分析 | AB测试、灰度发布 |
4.5 架构图:三种联动模式
下面这张图把三种模式的交互关系画清楚了。我建议你仔细看看数据流向的差异。
4.6 如何选择?我的经验之谈
说实话,没有银弹。我一般按这几个问题来选:
- 能不能接受延迟? 不能 → 同步调用;能 → 异步或旁路
- 策略引擎挂了怎么办? 业务不能停 → 旁路或异步+降级
- 规则变化频繁吗? 频繁 → 同步调用(实时生效);不频繁 → 旁路(定时推送)
- 需要事后分析吗? 需要 → 异步事件(天然带审计日志)
我推荐的最佳实践:核心链路用同步调用做实时控制,非核心链路用异步事件做数据采集,大规模分布式场景用旁路决策做本地执行。三种模式可以共存,关键看你的业务优先级。
嗯,这三种模式就聊到这儿。每种模式我都吃过亏,也尝过甜头。你根据自己系统的实际情况来选,别盲目追求“高大上”的架构。