Reactor核心机制:本质的信号传递流程源码到实战

文章目录

  • [Reactor 核心机制全解析:从源码到实战的底层逻辑](#Reactor 核心机制全解析:从源码到实战的底层逻辑)
    • [一、核心概念:`actual` 与 `subscription`------双向通信的骨架](#一、核心概念:actualsubscription——双向通信的骨架)
      • [1. `actual`:下游的实际订阅者](#1. actual:下游的实际订阅者)
      • [2. `subscription`:上游的订阅对象(传送带)](#2. subscription:上游的订阅对象(传送带))
    • 二、信号传递模型:四大核心线路的全生命周期
      • [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. subscribeOnpublishOn 的线程切换)
    • [五、总结:一张表看懂 Reactor 的核心](#五、总结:一张表看懂 Reactor 的核心)

Reactor 核心机制全解析:从源码到实战的底层逻辑

在使用 Reactor 进行响应式编程时,我们常常会遇到各种算子(如 mapflatMapretryWhen)和生命周期钩子(如 doOnNextdoOnError)。但如果只停留在 API 调用层面,很容易在复杂场景下踩坑。只有深入理解其底层的信号传递模型和装饰器模式,才能真正掌握响应式编程的精髓,写出稳定、高效的代码。


一、核心概念:actualsubscription------双向通信的骨架

Reactor 的算子链本质上是一个双向通信的管道,而 actualsubscription 就是构成这个管道的核心骨架。

1. actual:下游的实际订阅者

  • 定义 :在 Reactor 源码中,actual 是一个约定俗成的变量名,代表当前节点(算子或生产者)的直接下游订阅者
  • 作用 :所有下行信号(onNextonCompleteonError)都通过 actual 从上游传递到下游,最终到达终端订阅者。
  • 类比 :就像快递员(当前算子)把包裹(数据/信号)交给下一个收件人(actual),层层传递直到用户手中。

2. subscription:上游的订阅对象(传送带)

  • 定义:代表当前节点与上游之间的订阅关系,是上行信号的载体。
  • 作用 :所有上行信号(request(n)cancel)都通过 subscription 从下游传递到上游,实现背压控制和流的取消。
  • 类比 :就像用户(下游)通过快递单(subscription)向快递公司(上游)发起"派送请求"或"取消订单"。

二、信号传递模型:四大核心线路的全生命周期

Reactor 的流生命周期由四条核心线路构成,每条线路都有明确的触发时机、信号流向和钩子函数。

1. 取消请求线路(Cancel Path)

  • 触发时机 :下游主动调用 dispose()cancel() 时。
  • 信号流向 :从右到左(下游 → 上游),通过 subscription 传递。
  • 核心流程
    1. 终端订阅者发起 cancel 信号(1.1)。
    2. 信号依次传递给每个算子(1.2),最终到达上游生产者(1.3)。
    3. 每个算子执行 doOnCancel 钩子(1.1.1、1.2.1),执行资源清理;生产者执行清理任务(1.3.1)。
    4. 订阅者执行 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),传递数据。
  • 核心流程
    1. 终端订阅者发起 request(n) 背压请求,触发 hookOnSubscribe
    2. 信号通过 subscription 传递到上游生产者。
    3. 生产者生产数据,通过 onNext 信号经算子处理后传递给下游,触发 hookOnNext
    4. 数据处理完成后,订阅者可继续根据自身的情况向上游请求更多数据.

3. 正常完成线路(Complete Path)

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

4. 异常线路(Error Path)

  • 触发时机 :流处理过程中发生异常(如 map 中抛出业务异常)。
  • 信号流向 :从左到右(上游 → 下游),通过 actual 传递。
  • 核心流程
    1. 任意节点(生产者或算子)抛出异常,被捕获并转为 onError 信号(4.1、4.2、4.3)。
    2. 信号依次传递,触发各节点的异常处理逻辑(触发1-4)。
    3. 最终到达终端订阅者,执行 hookOnError(4.4),流异常终止,进入 Final 状态。

三、装饰器模式:算子链的本质

Reactor 的算子链本质上是装饰器模式的实现:

  • 每个算子(如 mapfiltertake)既是上游的订阅者(Subscriber),又是下游的发布者(Publisher)。
  • 算子内部持有 actual(下游订阅者)和 subscription(上游订阅对象)的引用,从而将信号在链中传递。
  • 这种设计使得我们可以无限组合算子,而无需修改核心逻辑。

四、实战应用:从底层理解算子与钩子

1. take 算子的提前终止

  • 本质 :在正常完成线路中,take 算子收到指定数量的 onNext 后,主动向上游发送 cancel 信号,终止上游生产,然后向下游发起 onComplete 信号。
  • 底层take 作为中间算子,接管了流的终止逻辑,同时触发取消和完成两条线路。

2. retryWhen 的重试逻辑

  • 本质 :在异常线路中捕获 onError 信号,不直接传递给下游,而是重新发起订阅,让流重新走一遍正常请求线路。
  • 底层 :重试时,retryWhen 算子会创建一个新的订阅(Companion Stream),将信号重新注入到算子链中。

在实际应用中,我们需要考虑更多稳定可靠的设计,比如使用退避重试算法能够一定程度上缓解上游的故障,故障是不可知的,可能是其他服务熔断了,需要点时间缓冲一下。

3. subscribeOnpublishOn 的线程切换

  • subscribeOn:改变上行信号(订阅、请求、取消)的执行线程。
  • publishOn :改变下行信号(onNextonCompleteonError)的执行线程。
  • 底层:这两个算子通过在信号传递时切换线程,实现了异步处理,而不改变信号的传递方向和顺序。

五、总结:一张表看懂 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全局算子图的核心基础】

未来的计划,接下来我会在后面几天陆续全部的算子集合。

官方网站-对于核心概念的讲解

相关推荐
阿湯哥16 天前
Reactor响应式编程中Sinks.Many
java·reactor
太阳伞下的阿呆20 天前
Reactor线程池切换publishOn与subscribeOn
reactor·高并发·响应式编程·异步
无小道22 天前
基于epoll的单进程Reactor服务器
运维·服务器·c++·网络编程·reactor·epoll
enjoy编程1 个月前
Spring boot 4 探究netty的关键知识点
spring boot·设计模式·reactor·netty·多线程
Ronin3051 个月前
【Linux网络】基于Reactor反应堆模式的高并发服务器
linux·网络·reactor·epoll·非阻塞·et模式·高并发服务器
wanghowie2 个月前
02.04.02 Reactor 实战教程:响应式编程从入门到精通
java·reactor
cccyi72 个月前
高级I/O编程:从Select、Poll到Epoll的演进与Reactor服务器实现
服务器·c++·reactor
刘家炫2 个月前
Linux 基于 Epoll 的主从 Reactor 多线程模型
linux·服务器·reactor·项目·多路转接
后端小张3 个月前
【JAVA 进阶】深入探秘Netty之Reactor模型:从理论到实战
java·开发语言·网络·spring boot·spring·reactor·netty