文章目录
- [Reactor 核心机制全解析:从源码到实战的底层逻辑](#Reactor 核心机制全解析:从源码到实战的底层逻辑)
-
- [一、核心概念:`actual` 与 `subscription`------双向通信的骨架](#一、核心概念:
actual与subscription——双向通信的骨架) -
- [1. `actual`:下游的实际订阅者](#1.
actual:下游的实际订阅者) - [2. `subscription`:上游的订阅对象(传送带)](#2.
subscription:上游的订阅对象(传送带))
- [1. `actual`:下游的实际订阅者](#1.
- 二、信号传递模型:四大核心线路的全生命周期
-
- [1. 取消请求线路(Cancel Path)](#1. 取消请求线路(Cancel Path))
- [2. 正常请求线路(Normal Request Path)](#2. 正常请求线路(Normal Request Path))
- [3. 正常完成线路(Complete Path)](#3. 正常完成线路(Complete Path))
- [4. 异常线路(Error Path)](#4. 异常线路(Error Path))
- 三、装饰器模式:算子链的本质
- 四、实战应用:从底层理解算子与钩子
-
- [1. `take` 算子的提前终止](#1.
take算子的提前终止) - [2. `retryWhen` 的重试逻辑](#2.
retryWhen的重试逻辑) - [3. `subscribeOn` 与 `publishOn` 的线程切换](#3.
subscribeOn与publishOn的线程切换)
- [1. `take` 算子的提前终止](#1.
- [五、总结:一张表看懂 Reactor 的核心](#五、总结:一张表看懂 Reactor 的核心)
- [一、核心概念:`actual` 与 `subscription`------双向通信的骨架](#一、核心概念:
Reactor 核心机制全解析:从源码到实战的底层逻辑
在使用 Reactor 进行响应式编程时,我们常常会遇到各种算子(如 map、flatMap、retryWhen)和生命周期钩子(如 doOnNext、doOnError)。但如果只停留在 API 调用层面,很容易在复杂场景下踩坑。只有深入理解其底层的信号传递模型和装饰器模式,才能真正掌握响应式编程的精髓,写出稳定、高效的代码。
一、核心概念:actual 与 subscription------双向通信的骨架
Reactor 的算子链本质上是一个双向通信的管道,而 actual 和 subscription 就是构成这个管道的核心骨架。
1. actual:下游的实际订阅者
- 定义 :在 Reactor 源码中,
actual是一个约定俗成的变量名,代表当前节点(算子或生产者)的直接下游订阅者。 - 作用 :所有下行信号(
onNext、onComplete、onError)都通过actual从上游传递到下游,最终到达终端订阅者。 - 类比 :就像快递员(当前算子)把包裹(数据/信号)交给下一个收件人(
actual),层层传递直到用户手中。
2. subscription:上游的订阅对象(传送带)
- 定义:代表当前节点与上游之间的订阅关系,是上行信号的载体。
- 作用 :所有上行信号(
request(n)、cancel)都通过subscription从下游传递到上游,实现背压控制和流的取消。 - 类比 :就像用户(下游)通过快递单(
subscription)向快递公司(上游)发起"派送请求"或"取消订单"。
二、信号传递模型:四大核心线路的全生命周期
Reactor 的流生命周期由四条核心线路构成,每条线路都有明确的触发时机、信号流向和钩子函数。
1. 取消请求线路(Cancel Path)

- 触发时机 :下游主动调用
dispose()或cancel()时。 - 信号流向 :从右到左(下游 → 上游),通过
subscription传递。 - 核心流程 :
- 终端订阅者发起
cancel信号(1.1)。 - 信号依次传递给每个算子(1.2),最终到达上游生产者(1.3)。
- 每个算子执行
doOnCancel钩子(1.1.1、1.2.1),执行资源清理;生产者执行清理任务(1.3.1)。 - 订阅者执行
hookOnCancel(1.4),流进入Final状态,触发hookOnFinally(1.5)。
- 终端订阅者发起
2. 正常请求线路(Normal Request Path)

- 触发时机:订阅成功后,下游申请数据时。
- 信号流向 :
- 上行:
request(n)从右到左(2.1 → 2.2 → 2.3),申请数据。 - 下行:
onNext从左到右(2.4 → 2.5 → 2.6),传递数据。
- 上行:
- 核心流程 :
- 终端订阅者发起
request(n)背压请求,触发hookOnSubscribe。 - 信号通过
subscription传递到上游生产者。 - 生产者生产数据,通过
onNext信号经算子处理后传递给下游,触发hookOnNext。 - 数据处理完成后,订阅者可继续根据自身的情况向上游请求更多数据.
- 终端订阅者发起
3. 正常完成线路(Complete Path)

- 触发时机 :上游生产者数据发送完毕(如
Flux.range发完所有元素),或算子(如take)提前终止流。 - 信号流向 :从左到右(上游 → 下游),通过
actual传递。 - 核心流程 :
- 上游生产者触发
onComplete信号(3.1),依次传递给每个算子(3.2),最终到达终端订阅者(3.3)。 - 每个算子执行
doOnComplete钩子,订阅者执行hookOnComplete(3.4)。 - 流正常结束,触发
hookOnFinally(3.5),进入Final状态。
- 上游生产者触发
4. 异常线路(Error Path)

- 触发时机 :流处理过程中发生异常(如
map中抛出业务异常)。 - 信号流向 :从左到右(上游 → 下游),通过
actual传递。 - 核心流程 :
- 任意节点(生产者或算子)抛出异常,被捕获并转为
onError信号(4.1、4.2、4.3)。 - 信号依次传递,触发各节点的异常处理逻辑(触发1-4)。
- 最终到达终端订阅者,执行
hookOnError(4.4),流异常终止,进入Final状态。
- 任意节点(生产者或算子)抛出异常,被捕获并转为
三、装饰器模式:算子链的本质
Reactor 的算子链本质上是装饰器模式的实现:
- 每个算子(如
map、filter、take)既是上游的订阅者(Subscriber),又是下游的发布者(Publisher)。 - 算子内部持有
actual(下游订阅者)和subscription(上游订阅对象)的引用,从而将信号在链中传递。 - 这种设计使得我们可以无限组合算子,而无需修改核心逻辑。
四、实战应用:从底层理解算子与钩子
1. take 算子的提前终止
- 本质 :在正常完成线路中,
take算子收到指定数量的onNext后,主动向上游发送cancel信号,终止上游生产,然后向下游发起onComplete信号。 - 底层 :
take作为中间算子,接管了流的终止逻辑,同时触发取消和完成两条线路。
2. retryWhen 的重试逻辑
- 本质 :在异常线路中捕获
onError信号,不直接传递给下游,而是重新发起订阅,让流重新走一遍正常请求线路。 - 底层 :重试时,
retryWhen算子会创建一个新的订阅(Companion Stream),将信号重新注入到算子链中。
在实际应用中,我们需要考虑更多稳定可靠的设计,比如使用退避重试算法能够一定程度上缓解上游的故障,故障是不可知的,可能是其他服务熔断了,需要点时间缓冲一下。
3. subscribeOn 与 publishOn 的线程切换
subscribeOn:改变上行信号(订阅、请求、取消)的执行线程。publishOn:改变下行信号(onNext、onComplete、onError)的执行线程。- 底层:这两个算子通过在信号传递时切换线程,实现了异步处理,而不改变信号的传递方向和顺序。
五、总结:一张表看懂 Reactor 的核心
| 信号类型 | 方向 | 载体 | 核心钩子 | 终止状态 |
|---|---|---|---|---|
| 数据(onNext) | 左→右 | actual | doOnNext, hookOnNext | - |
| 完成(onComplete) | 左→右 | actual | doOnComplete, hookOnComplete, hookOnFinally | Final (正常) |
| 异常(onError) | 左→右 | actual | doOnError, hookOnError, hookOnFinally | Final (异常) |
| 请求(request(n)) | 右→左 | subscription | hookOnSubscribe | - |
| 取消(cancel) | 右→左 | subscription | doOnCancel, hookOnCancel, hookOnFinally | Final (取消) |
理解了这张表,你就掌握了 Reactor 的核心。所有的算子和钩子,都是在这个双向通信模型上的扩展和应用。
以上的几个信号传递,我这边给大家整理一下,方便大家

这些图是我从源码reactor-core 3.8.3整理出来的。有什么不对的地方,或者有什么哪里理解的地方,欢迎大家在评论区指正,我好方便调整图,这个图是我未来出【reactor全局算子图的核心基础】
未来的计划,接下来我会在后面几天陆续全部的算子集合。