消息驱动、回压、隔离——弹性系统的三根支柱

反应式设计的方法结构不是一组独立的模式清单,是围绕'在压力下保持响应'这个核心目标的分层防御体系

本页目录

反应式设计建立在一个和传统架构不同的假设上:系统运行时,故障是常态而非异常。网络会分区、服务会宕机、负载会突增、依赖方会变慢。设计的目标不是防止故障发生,而是让故障发生时系统仍然能响应。

Reactive Manifesto 定义了四个特性:Responsive(响应性)、Resilient(弹性)、Elastic(可伸缩)、Message Driven(消息驱动)。前三个是目标,最后一个是实现手段。

消息驱动是基础设施层

把同步调用替换成异步消息传递,不是为了"更快",是为了解耦。

同步调用意味着调用方的线程被阻塞直到响应返回。被调用方慢了,调用方也慢。被调用方挂了,调用方也挂。故障沿着调用链双向传播。

消息驱动在调用方和被调用方之间插入了一个缓冲层(队列、Actor 邮箱、事件总线)。调用方把请求放进去就返回,不等响应。被调用方从缓冲里取请求处理。两端的速度和可用性解耦了。

这层解耦是所有后续模式的前提。没有消息驱动,隔离和回压都实现不了——因为同步调用链上没有可以插入控制逻辑的缝隙。

隔离是故障防御层

隔离的核心目的是控制故障的爆炸半径。一个组件挂了,影响范围应该被限制在预定义的边界内。

实现隔离的模式按粒度从粗到细:

Bulkhead(隔板)——按调用对象分配独立的资源池。每个下游服务有自己的线程池、连接池和超时配置。一个下游耗尽了自己的资源配额,不影响其他下游的请求。

Circuit Breaker(熔断器)——检测下游的健康状态。错误率超过阈值时断开调用,让请求走降级路径。定期探测下游是否恢复。恢复后逐渐放量,不是一下全开。

Supervisor(监管者)——在 Actor 模型中,父 Actor 决定子 Actor 失败后的处理策略:重启、停止、升级。失败不是由出错的组件自己处理,而是由专门的监管层决策。

三个模式不是替代关系,是叠加关系。Bulkhead 控制资源隔离,Circuit Breaker 控制调用隔离,Supervisor 控制生命周期隔离。

回压是过载控制层

隔离解决的是"一个组件挂了不拖累其他组件"。回压解决的是"负载超过处理能力时不把自己压垮"。

回压的实现从简单到复杂:

有界队列——最简单的回压形式。队列满了生产者被阻塞或收到拒绝。缺点是颗粒度粗——要么全速,要么完全停。

Reactive Streams(request(n) 模型)——下游显式告诉上游"再给我 n 个"。上游据此动态调整发送速率。颗粒度细,可以实现平滑的速率适配。

自适应限流——根据系统实时指标(延迟、错误率、队列深度)动态调整准入量。不需要下游显式发信号,靠指标反馈间接调控。

三种方式的选择取决于系统的异步程度。全异步的流处理系统用 Reactive Streams 最自然;半同步半异步的系统用有界队列加自适应限流更实际。

弹性来自三层的协同

单独用消息驱动,只是解耦了调用方式,没有处理过载和故障。单独用隔离,控制了故障范围但没有控制负载。单独用回压,控制了流量但如果某个组件直接挂掉仍然会影响上游。

三层一起工作的效果:消息驱动提供了异步基础;隔离把故障限制在边界内;回压让系统在接近能力上限时平滑降级而不是突然崩溃。

这个分层结构也决定了引入的顺序:先做消息驱动的基础改造,再加隔离机制,最后加回压。反过来做很难——同步调用链上加不了有效的回压。

同分类继续看