《Java 响应式编程·Reactive Streams 与背压原理》目录与学习路径

《Java 响应式编程·Reactive Streams 与背压原理》全书 50 篇目录页:14 章 42 节覆盖 RS 规范、从零实现 Publisher、Project Reactor 核心(Mono/Flux/操作符/调度器)、背压四大策略、Hot 与 Cold 多播、RxJava 3 对照、RS TCK 合规测试,最后以 eventd v1 背压演示系统验收。另含序、前言与五份附录。

本书定位

你很可能已经用过 Flux.just(1, 2, 3).map(x -> x * 2).subscribe(),甚至能在生产环境把 WebFlux 跑起来。但如果你被问到下面这些问题,还能给出可验证的答案吗?

  • request(n) 信号是在哪条线程被处理的?上一个 onNext 还没处理完,下一个 request 会不会把它覆盖掉?
  • flatMap 的无序合并和 concatMap 的顺序保证,到底是在订阅时决定的还是运行时决定的?
  • onBackpressureDrop() 丢下元素时,onNext 总共被调用了几次?limitRate(10) 发送的请求序列是什么?
  • 你自己写的 Publisher 能不能通过 Reactive Streams TCK(Technology Compatibility Kit)全部 38 个测试用例?

如果答不上来,说明你停留在「会用」阶段。本书的目标是把「会用」推进到「知道每条规则在什么条件下成立」——从 Reactive Streams 规范的四接口 43 条规则出发,用手写 Publisher 验证每一条信号契约,再用 Project Reactor 的内建能力解决工程问题。

本书不承诺什么:

  • 不是框架使用说明书——我们不展开 Spring WebFlux 的自动配置、Reactor Netty 的 Channel 实现(留给卷二)。
  • 不是分布式流处理入门——我们不展开 Kafka Streams 的拓扑设计、Flink 的 Checkpoint 机制(留给卷三)。
  • 不是 JMM 或 AQS 源码解析——已有《Java 并发编程》三卷覆盖。

本书许诺什么:读完能对一条数据在响应式流中的完整生命周期做出可验证的判断,而不是背操作符名称。

读者画像与前置知识

  • 前置:Java 语法、Lambda、Stream API、ExecutorService 用法;了解 NIO 的 Channel/Buffer/Selector 概念更佳。
  • 读者画像:
    • 写过业务代码但背压总调不对的后端开发
    • 想了解响应式原理而非只记操作符的人
    • 其他语言(JavaScript/Rust/Kotlin)转 Java、想对照响应式实现的工程师
    • 准备面试需要串起 RS 规范 → Reactor 实现 → 背压策略知识链的人

三卷路线

卷书名核心能力输出
卷一《Reactive Streams 与背压原理》规范 + 实现 + 策略能手写合规 Publisher,能判断背压策略适用场景
卷二《系统构建与数据访问》Reactor Netty + WebFlux + R2DBC能建响应式网关与数据管道
卷三《流处理引擎与实时计算》Kafka Streams + Flink能搭实时指标与事件处理系统

三卷共享同一个贯穿项目 eventd(事件驱动演示系统),v1、v2、v3 分别对应三卷的验收目标。

环境清单

组件版本
JDKTemurin 25.0.5+8(javac --release 25)
Maven3.9.12
JUnit Jupiter5.14.4
Project ReactorBOM 2025.0.8
RxJava3.1.12
RS TCK1.0.4

本机口径:

Apple M1 Pro,10 核,32 GB,macOS 26.3 (25D125)
Temurin 25.0.5+8

学习路径

路径 A:零基础顺序通读(推荐)

按章顺序阅读,每章内部按 1→2→3 顺序。预计 3–4 周完成。

  1. 先读 序 → 前言,确认环境可运行 eventd-v1 骨架。
  2. 第一部分(第 1 章) 建立规范概念:RS 四个接口 + 43 条规则。
  3. 第二部分(第 2–3 章) 手写实现:同步/异步 Publisher、Subscriber、Processor、操作符链。
  4. 第三部分(第 4–7 章) 进入 Project Reactor:Mono/Flux 创建、变换、组合、错误处理、调度器、背压策略。
  5. 第四部分(第 8–10 章) 延伸:Hot/Cold、Sinks、RxJava 3 对照。
  6. 第五部分(第 11 章) 验证:RS TCK 合规测试。
  7. 第六部分(第 12 章) 调试:生命周期钩子、Hooks、装配时 vs 订阅时。
  8. 第七部分(第 13–14 章) 验收:eventd v1 完整演示 + 性能基线。
  9. 附录 作为速查手册。

路径 B:有 Reactor 经验,想补原理

跳过第 4–7 章的操作符,直接从 第 1 章(RS 规范) → 第 2–3 章(手写实现) → 第 7 章(背压策略) → 第 8–10 章(Hot/Cold + Sinks + RxJava) → 第 11 章(TCK) → 第 13–14 章(eventd 验收)。预计 2 周。

路径 C:只看代码与实验

读 前言(环境)→ 第 2–3 章(手写实现)→ 第 13 章(eventd 架构 + 传感器模拟器 + 背压面板)→ 第 14 章(性能基线)。只看可运行的代码,跳过理论推导。预计 1 周。

全书目录

前置

#篇标题一句话页说明
1序从回调地狱到背压契约响应式不是「更好的回调」,而是一组有约束的信号契约无代码立场声明
2前言环境、项目与读法JDK 25、Reactor BOM 2025.0.8、eventd-v1 骨架mvn -version环境确认
3目录目录与学习路径(本页)三条路径、十四章依赖、与卷二卷三衔接无代码你在这里

第一部分:Reactive Streams 规范(第 1 章)

节篇标题一句话页
1.1异步编程的演进回调、Promise、CompletableFuture 的局限;为什么需要「流」CompletableFuture vs Flux 对照
1.2RS 规范:四个接口Publisher/Subscriber/Subscription/Processor;43 条规则概述JDK Flow 接口源码
1.3规范规则逐条分析onSubscribe 先调用、request 信号、取消与完成、空 Publisher规则表 + 违反示例

第二部分:从零实现 Publisher(第 2–3 章)

节篇标题一句话页
2.1同步 Publisher 最小实现单值同步 Publisher、subscribe 流程、request(n) 同步响应SyncSinglePublisher 完整类
2.2异步 Publisher 与背压信号异步生产、request 累积、Executor 调度、取消传播AsyncRangePublisher 完整类
2.3Subscriber 实现与信号契约onSubscribe 保存 Subscription、request/cancel 线程安全LoggingSubscriber 完整类
3.1Processor:桥接Processor 同时实现两者;编码转换、日志、指标MapProcessor 完整类
3.2操作符链:map、filter、take懒订阅、操作符返回新 Publisher、request 信号转发手写 map/filter/take
3.3调度切换:subscribeOn 与 publishOn订阅线程 vs 发射线程;信号不能乱序实跑证明差异

第三部分:Project Reactor 核心(第 4–7 章)

节篇标题一句话页
4.1Mono 与 FluxMono(0|1)、Flux(0..N)、创建操作符Mono.just vs Flux.just 对照
4.2转换操作符:map、flatMap、concatMap同步变换 vs 异步展开;flatMap 无序、concatMap 有序完整代码 + 输出顺序
4.3组合操作符:zip、merge、combineLatest配对 vs 先 emit 先赢 vs 最新值;空流与错误传播三种组合场景
5.1错误处理onErrorReturn、onErrorResume、retry 策略模拟网络失败 + 重试日志
5.2指数退避重试retryWhen + Flux.interval;固定 vs 指数退避Retry.backoff 配置与输出
5.3超时与取消传播timeout(Duration)、取消信号向上游传播、doOnCancel慢 Publisher + timeout
6.1调度器single/elastic/parallel/immediate;线程名与边界四种调度器线程名输出
6.2BoundedElastic有界弹性调度器;与 ExecutorService 的关系大量 sleep 任务行为
6.3自定义调度器Scheduler.Worker 生命周期、任务排队、取消粒度LoggingScheduler 自定义
7.1背压策略:Buffer无界/有界队列、溢出策略、钩子快生产 + 慢消费 + buffer 溢出
7.2背压策略:DroponBackpressureDrop / onBackpressureLatestdrop 与 latest 元素数量对比
7.3背压策略:Error 与速率控制onBackpressureError、limitRate(n)、limitRequest(n)limitRate(10) 请求序列分析

第四部分:Hot 与 Cold、Sinks、多播(第 8–10 章)

节篇标题一句话页
8.1Cold Publisher每次订阅重放;多次订阅独立数据流两次订阅同一 Flux.range
8.2Hot Publisherpublish().refCount()、share();late subscriber 只能收后续ConnectableFlux connect 时机
8.3refCount、autoConnect 与 cache内存与重放权衡三种模式对照
9.1Sinks:程序化发射Sinks.many().unicast/multicast/replay;线程安全发射Sinks.Many 发射与订阅
9.2Sinks 多播onBackpressureBuffer / .directBestEffort多播 + 不同背压策略
9.3Sinks 重放replay().limit(n) / .limit(Duration) / .latest()重放缓存命中与失效
10.1RxJava SubjectPublish/Behavior/Replay/Async Subject;与 Sinks 对照四种 Subject 行为对比
10.2ConnectableObservableRxJava publish + connect / refCount;与 Reactor 对照两个库并行展示
10.3RxJava 3 与 Reactor 迁移API 映射表、共同陷阱、何时选哪个同一段逻辑双写

第五部分:RS TCK 合规验证(第 11 章)

节篇标题一句话页
11.1TCK 环境搭建Publisher/Subscriber/Processor Verification;TestNG 7.3.0 驱动mvn test 跑通 TCK
11.2Publisher 合规测试38 个用例(22 个 required);信号顺序、背压、空 PublisherFlux.range 包装实测 29 通过、9 跳过
11.3Subscriber 与 Processor 合规测试Whitebox/Blackbox/IdentityProcessor VerificationPublishProcessor 实测 30 通过、14 失败、24 跳过

第六部分:调试与生命周期(第 12 章)

节篇标题一句话页
12.1生命周期钩子doOnSubscribe/Next/Error/Complete/Cancel/Request完整链路上的钩子输出
12.2调试:Hooks 与检查点onOperatorDebug、checkpoint 订阅点追踪异常栈定位操作符
12.3装配时 vs 订阅时操作符链是蓝图、订阅才是启动log() 装配 vs 订阅打印

第七部分:eventd v1 验收(第 13–14 章)

节篇标题一句话页
13.1eventd v1 架构eventd-core + eventd-app 模块划分、依赖关系模块图 + dependency:tree
13.2传感器模拟器Poisson 到达、可配置速率、request(n) 响应不同速率下消费速率对比
13.3背压演示面板统计 request 累积、onNext 处理时间、buffer/drop 数量运行后输出统计表
14.1Project Reactor 重写同一套逻辑:Flux.create + BoundedElastic + onBackpressureBuffer双版本并行展示
14.2性能基线吞吐量、订阅开销、调度延迟分位数、资源测量方法System.nanoTime 自测量
14.3v1 验收清单TCK 全绿、三种背压策略演示、模块 README检查清单

附录

附录篇标题用途
A操作符速查分类表、操作符对照、适用场景日常速查
B调度器选择指南四种场景 → 推荐调度器 → 反例选型决策
C背压规则清单RS 规范背压规则 + Reactor 实现映射规范对照
DCompletableFuture 迁移指南CompletableFuture → Mono/Flux 映射迁移参考
ERS TCK 方法参考全部测试方法列表与说明TCK 开发

关于代码与实验

卷一所有代码在 eventd-v1 多模块 Maven 工程中:

eventd-v1/
├── eventd-core/   # RS 规范实现(自写 Publisher/Subscriber/Processor)
└── eventd-app/    # 背压演示应用(依赖 eventd-core + reactor)
  • 卷一只引入 reactor-core 和 rxjava,不引入 Spring、Netty、R2DBC(留给卷二/卷三)。
  • 每节代码用 javac --release 25 编译,完整项目用 mvn -q -DskipTests compile。
  • 所有「本机输出」来自同一台机器:Apple M1 Pro,10 核,32 GB,macOS 26.3 (25D125),Temurin 25.0.5+8。

章节依赖关系

以下依赖图说明「读第 N 章前必须先读哪些章」。箭头表示「依赖」。

序 → 前言 → 目录(本页)
                ↓
        第 1 章(RS 规范)
                ↓
        第 2 章(Publisher)→ 第 3 章(Processor/操作符)
                ↓                        ↓
        第 4 章(Mono/Flux)←───────────┘
                ↓
        第 5 章(错误处理)→ 第 6 章(调度器)→ 第 7 章(背压策略)
                                                          ↓
        第 8 章(Hot/Cold)← 第 9 章(Sinks)← 第 10 章(RxJava)
                ↓
        第 11 章(TCK)    第 12 章(调试)
                ↓                 ↓
        第 13 章(eventd 架构)
                ↓
        第 14 章(性能基线 + 验收)
  • 第 1 章是根:不读第 1 章,第 2–3 章的「Subscriber 必须先收到 onSubscribe」等规则会缺乏上下文。
  • 第 4–7 章是主干:掌握 Reactor 核心后才能理解 Hot/Cold 的「订阅即启动」语义。
  • 第 10 章(RxJava)可跳过:如果你只用 Reactor、不关心 RxJava 对照,直接从第 9 章跳到第 11 章。
  • 第 11 章(TCK)可独立:有 TestNG 或其他测试框架基础即可直接跳着读,但自己写测试时需要回头参考第 2–3 章的实现。

与已有 Java 书稿的关系

已有书稿本卷如何衔接不重复什么
《Java 编程入门》Lambda、Stream API 是基础;本卷把 Stream 的「惰性求值」推进到「背压控制」Stream 的基础用法(filter/map/collect)
《Java 高级编程》JMM、虚拟线程是理解调度器的铺垫;本卷在 §6.1 引用JMM happens-before、AQS 源码
《Java 并发编程·线程与内存模型》ExecutorService、线程池是 §6.2 BoundedElastic 的原型;ForkJoin 与 parallelStream 提到但不展开线程状态迁移、锁优化
《Spring Boot 高级》第 8 章WebFlux 背压概述(3 节);本卷从 RS 规范写到实现细节(14 章)Spring 容器启动、自动配置
《Netty 高性能网络编程》Reactor 模式是 Netty EventLoop 的设计来源;本卷只引用、不拆源码ByteBuf、ChannelPipeline 源码
《Java 服务端通信工程》gRPC 流式调用(留到卷三衔接);本卷只给一句话边界服务发现、限流熔断
《Java 消息中间件》三卷Kafka Streams(卷三);本卷不涉及Producer/Consumer API、分区日志

验收标准

读完卷一并完成全部实验后,你应该能:

  1. 手写一个通过 RS TCK 的 Publisher:Flux.range 包装或手写 Publisher,38 个用例中 21 个 required 通过、1 个 required 因未提供失败 Publisher 跳过(默认总计 29 通过、9 跳过)。
  2. 解释任意一条 RS 规范规则:例如「§3.6:Subscription 取消后,额外的 request(long n) 必须是 NOP」为什么必须成立。
  3. 为给定场景选择合适的背压策略: Producer 比 Consumer 快 100 倍时选 drop还是 buffer?内存紧张时选 error 还是 latest?
  4. 阅读一段 Reactor 链式代码并预测输出顺序:给定 Flux.just(1,2).flatMap(i -> Mono.just(i).delayElement(Duration.ofMillis(i*10))).subscribeOn(Schedulers.boundedElastic()),说出 onNext 的顺序和所在线程。
  5. 将一段 CompletableFuture 代码迁移为响应式流:保留错误恢复、超时、重试语义。

术语速查(阅读前必知)

术语英文含义
背压Backpressure消费者通过 request(n) 控制生产者发射速率的机制
冷发布者Cold Publisher每次订阅独立启动数据流(如 Flux.range)
热发布者Hot Publisher数据流独立于订阅存在,late subscriber 只能收到后续元素
装配期Assembly time操作符链的构建阶段(还未订阅)
订阅期Subscription timesubscribe() 被调用后的执行阶段
信号SignalonSubscribe/onNext/onError/onComplete/onCancel/request 的统称

阅读导航

上一篇:前言:环境、项目与读法

下一篇:卷一从 1.1 异步编程的演进 开始,或返回书稿书架 选择其他卷。

相关阅读

主题推荐阅读
Reactive Streams 规范reactive-streams.org
Project Reactor 文档projectreactor.io/docs
RxJava 文档github.com/ReactiveX/RxJava
Reactor 背压指南Project Reactor Reference Guide §8
《Java 并发编程》本站「Java 并发基础」系列
《Netty 高性能网络编程》本站「java-netty」系列
《Java 消息中间件》本站「java-mq-*」系列

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「java」更多文章

  1. 15.3 全书总结与学习路径回顾
  2. 15.2 响应式流处理的演进趋势
  3. 15.1 引擎选型指南