本节摘要:2013 年 Netflix、Lightbend、Pivotal 等联合发布的 Reactive Manifesto 将响应式系统凝练为 Responsive、Resilient、Elastic、Message-Driven 四支柱。本节说明每柱在流契约中的对应物,而非空泛口号。
| 支柱 | 系统承诺 | 流/运行时对应 |
|---|---|---|
| Responsive 响应性 | 及时、可预期地响应 | SLA、timeout、端到端延迟预算 |
| Resilient 回弹性 | 故障隔离、降级恢复 | onErrorResume、retryWhen、舱壁 |
| Elastic 弹性 | 负载变化下伸缩 | 背压、request(n)、无固定线程绑定 |
| Message-Driven 消息驱动 | 异步、位置透明 | 非阻塞 I/O、事件/流为一等公民 |
Manifesto 强调:四者相互依赖——没有消息驱动就难以弹性;没有背压就难以在弹性下保持响应性。
四支柱不是四个可勾选的 checkbox,而是一组互相支撑的循环。把循环画出来会更容易记忆:消息驱动是地基(异步消息把组件解耦),弹性是横向维度(无状态负载可以自由扩缩),回弹性是纵向维度(故障被隔离在局部),而响应性是这三维共同作用在用户侧的可观察结果——用户不关心你的弹性策略,只关心 200ms 内有没有拿到响应。
Manifesto 是系统设计宪法;2014 年诞生的 Reactive Streams 规范是** JVM 互操作宪法**:Publisher、Subscriber、Subscription、Processor 共 13 个方法,约束 onNext 串行、onError 后禁止再 onNext、cancel 必须停发等。
这使 Project Reactor、RxJava 2+、Akka Stream 可在同进程内无缝协作——就像 TCP 让异构主机互通。
四支柱如何落到这张时序图上?Message-Driven 对应图中每一跳都是异步消息(订阅、request、onNext);Elastic 对应 request(32)——网关能按下游能力动态申领配额,因此可以横向扩容而不压垮下游;Resilient 对应 Note over G,S: 故障时 onError → 降级流——下游故障被信号化为 onError,网关转而执行降级流,故障不扩散;Responsive 则是 U 侧始终能在预算时间内得到聚合响应。一张图,四柱齐备。
Responsive:是否定义 P99 与超时策略,而非仅平均延迟?
Resilient:下游超时是否变成 Mono.error 并触发 fallback,还是阻塞整个 EventLoop?
Elastic:线程数是否随 QPS 线性涨?Reactor 下单 EventLoop 可承载大量并发 I/O。
Message-Driven:组件间是否通过流/消息传递,而非共享可变状态 + 锁?
Zuul 2 迁移案例(SOURCE):响应式网关单节点吞吐升约 300%,GC 停顿降约 90%——四支柱在流量面上的可观测结果。
评审时建议用一个「四问法」逐项打分,每个问题给出 0/1/2 分:
| 问题 | 0 分 | 1 分 | 2 分 |
|---|---|---|---|
| 超时策略存在吗 | 无 timeout | 有但散落 | timeout 是流的一部分 |
| 故障隔离了吗 | 异常冒泡到外层 | 部分 try/catch | onError 链 + 降级流 |
| 能弹性伸缩吗 | 线程随请求线性涨 | 有连接池 | request(n) 控流 |
| 组件如何通信 | 共享内存 + 锁 | 同步 RPC | 异步消息/流 |
当某系统四项总分低于 4 分时,「响应式」标签值得怀疑。这种打分法比「用了 WebFlux 所以是响应式」可靠得多——它评审的是行为特征,而不是技术栈外观。
// 评审清单在代码层面的直接映射 // Responsive: 超时声明在流上 return userRepo.findById(id) .timeout(Duration.ofMillis(200)) // Resilient: 降级分支 .onErrorResume(TimeoutException.class, e -> Mono.just(User.cached(id))) // Elastic: 下游主动 request 受控 .limitRate(64);
这段代码逐行对应评审问题:.timeout(200ms) 回答「Responsive」——用户等多久有答案;.onErrorResume(TimeoutException.class, ...) 回答「Resilient」——超时降级为缓存读;.limitRate(64) 回答「Elastic」——下游每次最多申领 64 个元素,避免一次拉爆内存。至于「Message-Driven」,它不在这一条链上,而在网关与下游服务的传输边界上(Netty 的非阻塞传输)。一个评审合格的系统,每个问题都能在代码里找到证据行。

四支柱不仅是对单个组件的评审标准,更描述了组件之间的关系。画出一张典型响应式系统的拓扑图,你会发现四支柱各管一段:
// 一次典型的四支柱评审实现(网关聚合场景) public Mono<GatewayResponse> aggregate(String userId) { return Mono.zip( userService.get(userId), // 用户信息 profileService.get(userId), // 画像 riskService.check(userId)) // 风控 .timeout(Duration.ofMillis(300)) // Responsive: 响应预算 .onErrorResume(TimeoutException.class, e -> Mono.just(GatewayResponse.timeoutFallback())) // Resilient .onErrorResume(RiskServiceException.class, e -> Mono.just(GatewayResponse.riskDenied())); }
这条链是四支柱的浓缩演示:zip 并行聚合三个异步源(Message-Driven 的基础),timeout 声明响应预算(Responsive),onErrorResume 按错误类型降级(Resilient),而整体无状态、可按 QPS 横向扩容(Elastic)。评审时拿着这张代码逐行标注它满足了哪一柱,比空谈「我们要做到响应式」可操作得多。
Manifesto 的分量不在那四段宣言,而在于它给了架构师一套可以逐条对表的提问清单。 1.2 的价值是把「响应式」从一个形容词变成一个可审计的工程目标。
Responsive 看超时与 P99,Resilient 看故障隔离与降级,Elastic 看 request 控流与无状态扩缩,Message-Driven 看边界是否走异步消息——把这四句话贴在你的评审模板里,比背四段宣传文案有用。
下一节沿时间线看 FRP、Rx、Manifesto、Java 9 Flow 如何衔接。