posts

《Java 响应式编程·Reactive Streams 与背压原理》· 全书目录与章节索引(50 篇)

《Java 响应式编程·Reactive Streams 与背压原理》全 50 篇:从 Reactive Streams 规范、自实现 Publisher/Subscriber/Processor,到 Project Reactor 核心(Mono/Flux/调度器/背压策略)、Hot 与 Cold 多播、RxJava 3 对照、RS TCK 合规测试,最后以 eventd v1 背压演示系统验收。纯 JDK 25 + Project Reactor BOM 2025.0.8(reactor-core 3.8.8),不含 Spring WebFlux 或 Netty 源码沉底。

全书概览

项目内容
书稿《Java 响应式编程·Reactive Streams 与背压原理》
篇数50 篇(14 章 42 节 + 序、前言、目录 + 附录 A–E)
领域Reactive Streams 规范实现、Project Reactor 核心、背压原理、RS TCK 合规验证
贯穿项目eventd-v1 —— 自实现 RS Publisher → Project Reactor 重写 → 背压演示系统
阅读方式从目录篇 进入按顺序通读,或按机制跳读
主线版本JDK 25 LTS(Temurin 25.0.5+8)、Project Reactor BOM 2025.0.8、RxJava 3.1.12
关键依赖reactor-core 3.8.8(BOM 2025.0.8)、rxjava 3.1.12、reactive-streams-tck 1.0.4
上级专题书稿专题

三卷分工

卷书名关注点
卷一《Java 响应式编程·Reactive Streams 与背压原理》RS 规范、Reactor 核心、背压策略、RS TCK 合规
卷二《Java 响应式编程·系统构建与数据访问》Reactor Netty、WebFlux、R2DBC、响应式安全与测试
卷三《Java 响应式编程·流处理引擎与实时计算》Kafka Streams、Flink DataStream、窗口、CEP

本卷不展开 Reactor Netty/WebFlux(留给卷二),不展开 Kafka Streams/Flink(留给卷三)。需要时写「卷二第 N 章」「卷三第 N 章」。

全书目录

前置

篇文章核心内容
序序:从回调地狱到背压契约回调地狱三宗罪、RS 规范的诞生、三卷分工、本书不承诺什么
前言前言:环境、项目与读法读者对象、前置知识、环境清单、eventd-v1 骨架、代码约定
目录目录与学习路径三条学习路径、三卷衔接、章节索引

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

节文章核心内容
1.1异步编程的演进回调、Promise/Future、CompletableFuture 的局限;为什么需要「流」
1.2Reactive Streams 规范:四个接口Publisher/Subscriber/Subscription/Processor;43 条规则概述
1.3规范规则逐条分析onSubscribe 先调用、request 信号、onNext 与 request 关系、取消与完成、空 Publisher

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

节文章核心内容
2.1同步 Publisher 最小实现单值同步 Publisher、标准 subscribe 流程、request(n) 同步响应
2.2异步 Publisher 与背压信号异步生产、Subscription 内 request 累积、Executor 调度、取消传播
2.3Subscriber 实现与信号契约onSubscribe 内保存 Subscription、request 与 cancel 线程安全、onNext 不阻塞
3.1Processor:Subscriber 与 Publisher 的桥接Processor 同时实现两者;桥接场景(编码转换、日志、指标)
3.2操作符链:map、filter、take懒订阅、每个操作符返回新 Publisher、request 信号转发与变换
3.3调度切换:subscribeOn 与 publishOn订阅线程 vs 发射线程;Executor 作为调度器;信号不能乱序

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

节文章核心内容
4.1Mono 与 Flux:零个、一个与多个元素Mono(0|1)、Flux(0..N)、创建操作符、空与错误
4.2转换操作符:map、flatMap、concatMap同步变换 vs 异步展开;flatMap 合并无序、concatMap 顺序保证
4.3组合操作符:zip、merge、combineLatest配对发射 vs 先 emit 先赢 vs 最新值组合;空流与错误传播
5.1错误处理:onErrorReturn、onErrorResume、retry错误恢复策略、重试次数与退避、retryWhen 与 Repeat 区别
5.2指数退避重试与熔断信号retryWhen 配合 Flux.interval、固定退避 vs 指数退避
5.3超时与取消传播timeout(Duration) 语义、取消信号向上游传播、doOnCancel 钩子
6.1调度器:单线程、弹性、并行与立即Schedulers.single/elastic/parallel/immediate;线程名与线程数边界
6.2BoundedElastic 与线程池模型有界弹性调度器(线程上限、队列、TTL);与 ExecutorService 的关系
6.3自定义调度器与 Worker 模型Scheduler.Worker 生命周期、任务排队、取消粒度
7.1背压策略:BufferonBackpressureBuffer() 无界/有界队列、溢出策略、钩子
7.2背压策略:Drop Latest 与 Drop OldestonBackpressureDrop / onBackpressureLatest 语义;丢元素回调
7.3背压策略:Error 与请求发射速率控制onBackpressureError、limitRate(n)、limitRequest(n);请求批量化

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

节文章核心内容
8.1Cold Publisher:每次订阅重放创建即启动 vs 订阅即启动;多次订阅独立数据流
8.2Hot Publisher:广播与共享publish().refCount()、share();late subscriber 只能收到后续元素
8.3refCount、autoConnect 与 cacherefCount(n)、autoConnect(n)、cache 的内存与重放权衡
9.1Sinks:程序化发射数据Sinks.many().unicast/multicast/replay;线程安全发射;失败类型
9.2Sinks 多播:背压与重放multicast().onBackpressureBuffer / .directBestEffort;重放缓存大小限制
9.3Sinks 重放:大小与时间限制replay().limit(n) / .limit(Duration) / .latest();内存管理与失效策略
10.1RxJava Subject:与 Sinks 的对照PublishSubject、BehaviorSubject、ReplaySubject、AsyncSubject
10.2ConnectableObservable 与 connectRxJava 的 publish + connect / refCount;与 Reactor ConnectableFlux 对照
10.3RxJava 3 与 Reactor 的迁移对照API 映射表、共同陷阱、何时选哪个库

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

节文章核心内容
11.1RS TCK:测试环境搭建PublisherVerification/SubscriberVerification/IdentityProcessorVerification
11.2Publisher 合规测试38 个用例(22 个 required);信号顺序、背压、空 Publisher、异步完成
11.3Subscriber 与 Processor 合规测试SubscriberWhitebox/Blackbox、IdentityProcessorVerification

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

节文章核心内容
12.1生命周期钩子:doOn* 系列doOnSubscribe/doOnNext/doOnError/doOnComplete/doOnCancel/doOnRequest
12.2调试技术:Hooks 与检查点Hooks.onOperatorDebug、checkpoint 订阅点追踪、性能代价
12.3装配时 vs 订阅时操作符链是蓝图、订阅才是启动;多次订阅多次执行

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

节文章核心内容
13.1eventd v1 架构与模块划分eventd-core(RS 实现)、eventd-app(背压演示 App)、模块依赖
13.2传感器模拟器:带背压的随机数据流SensorSimulatorPublisher:Poisson 到达、可配置速率、request(n) 响应
13.3背压演示面板:请求率 vs 消费率BackpressureDashboard:统计 request 累积、onNext 处理时间、buffer/drop 数量
14.1用 Project Reactor 重写 eventd同一套业务逻辑:Flux.create + BoundedElastic + onBackpressureBuffer
14.2eventd v1 性能基线吞吐量(元素/秒)、延迟分布(p50/p99)、不同背压策略资源占用
14.3v1 验收:RS 合规、背压可观测、文档TCK 全绿、三种背压策略演示、模块 README

附录

附录文章核心内容
AReactor/RxJava 操作符速查分类表(创建/变换/组合/错误/背压/工具)、操作符对照、适用场景
B调度器选择指南四种场景 → 推荐调度器 → 反例
C背压规则清单RS 规范背压相关规则逐条 + Reactor 实现映射
D从 CompletableFuture 到响应式流迁移指南CompletableFuture → Mono/Flux 映射、常见陷阱、何时不要迁移
ERS TCK 测试方法参考PublisherVerification/SubscriberVerification 全部方法列表

与站内已有内容的边界

全部文章 Books game Java Indie golang 客户端开发 Minigame Saas rust Python
java

9.3 Sinks 重放:大小与时间限制

讲解 Sinks.Many.replay() 的五种策略:all() 无限历史、limit(n) 保留最近 n 个、limit(Duration) 按 TTL 淘汰、limit(n, Duration) 同时受限、latest() 只留最新值。实测 late subscriber 在 limit(3) 下只收到 [2,3,4]、只 request(1) 时只收到 1 个元素,证明重放仍受下游背压约束;并给出 latestOrDefault、过期后无新元素、完成后订阅的真实输出。示例基于 reactor-core 3.8.8。

4 分钟阅读
书稿 Java 响应式编程
java

9.2 Sinks 多播:背压与重放

用实跑对比 Sinks.Many 多播的三种背压策略:directBestEffort 只丢慢订阅者自己的元素,directAllOrNothing 只要一人无需求就让所有人收不到并返回 FAIL_OVERFLOW,onBackpressureBuffer 用共享队列导致队头阻塞,慢订阅者不补齐需求时快订阅者也拿不到元素。实测缓冲区容量取整(1→1、2/3/5→8、10→16)、默认 256,以及 busyLooping 只重试 FAIL_NON_SERIALIZED、不挽救 FAIL_OVERFLOW。示例基于 reactor-core 3.8.8。

5 分钟阅读
书稿 Java 响应式编程
java

9.1 Sinks:程序化发射数据

讲解 Reactor Sinks API 的设计目标——在 Publisher 外部程序化地发射数据。对比 unicast、multicast、replay 三种 Many 工厂的订阅模型与零订阅者行为,实测 tryEmitNext 的 EmitResult 语义、emitNext 在 FAIL_OVERFLOW 时会终止整条 sink,以及并发发射实测出现的 FAIL_NON_SERIALIZED,纠正「Sinks 线程安全、可任意线程发射」的误解。示例基于 reactor-core 3.8.8。

4 分钟阅读
书稿 Java 响应式编程
java

8.3 refCount、autoConnect 与 cache

对比 refCount(n)、autoConnect(n)、replay()、replay(n) 与 cache() 的启动时机、断开条件、后订阅者行为与内存代价。实测 refCount(1) 在订阅归零时取消源、在源完成后重新订阅源,autoConnect(1) 在订阅者全部取消后仍持续运行,replay(2) 只给后订阅者回放最近 2 个元素,cache(2) 只保留最近 2 个元素给后订阅者。示例基于 reactor-core 3.8.8。

5 分钟阅读
书稿 Java 响应式编程
java

8.2 Hot Publisher:广播与共享

深入讲解 Hot Publisher 的语义:源流独立于订阅存在,late subscriber 只能收到订阅之后的元素。用 Flux.create 手工驱动 publish、connect,确定性演示后订阅者丢失历史;实测 autoConnect(n) 的连接阈值、refCount(1) 在订阅归零时断开并在下次订阅时重新连接,并纠正「Hot Publisher 无背压、会无限缓冲」的误解。示例基于 reactor-core 3.8.8。

5 分钟阅读
书稿 Java 响应式编程
java

8.1 Cold Publisher:每次订阅重放

系统讲解 Cold Publisher 的语义:数据流与订阅绑定,每次 subscribe 独立启动新序列、重新执行副作用。用实跑输出对比 Flux.range 的重复订阅、Mono.fromCallable 的重复调用、Mono.cache 的成功与失败缓存、Flux.cache(n) 对后订阅者只回放最近 n 个元素,并区分 just 的急切求值与 fromCallable 的延迟求值。示例基于 reactor-core 3.8.8。

4 分钟阅读
书稿 Java 响应式编程
java

7.3 背压策略:Error 与请求发射速率控制

讲清 onBackpressureError 的快速失败语义,以及 limitRate、limitRate(highTide, lowTide)、limitRequest 三种请求控制手段的真实行为。用 doOnRequest 实测 limitRate(10) 的请求序列 [10, 8, 8, ...] 与 75% 补请求规则,实测 limitRequest(5) 取满即完成、limitRequest(0) 不订阅上游,并给出 Flux.create + onRequest 的生产端限流写法。示例基于 reactor-core 3.8.8。

7 分钟阅读
书稿 Java 响应式编程
java

7.2 背压策略:Drop Latest 与 Drop Oldest

区分 onBackpressureDrop、onBackpressureLatest 与 onBackpressureError 的真实语义:三者都向上游请求 Long.MAX_VALUE,只在下游没有需求时丢弃或覆盖。用确定性订阅实验实测「无需求」和「先请求 1 个」两种情况下保留与丢弃的元素,说明 delayElements 一次只请求一个元素因而会触发丢弃,并给出状态面板、日志采集与快速失败的选型边界。示例基于 reactor-core 3.8.8。

6 分钟阅读
书稿 Java 响应式编程
java

6.3 自定义调度器与 Worker 模型

从 Scheduler/Worker 的真实接口契约出发,手写一个可运行的 LoggingScheduler:直接调度与 Worker 串行调度的区别、Worker.dispose 的取消语义、Scheduler.dispose 对 Worker 的回收,以及延迟/周期调度默认被拒绝的原因。再用 reactor-test 的 VirtualTimeScheduler 演示 StepVerifier 虚拟时间与手动 advanceTimeBy 两种测试方式,并给出按 key 分区和包装现有调度器的完整实现。示例基于 reactor-core 3.8.8、reactor-test 3.8.8。

9 分钟阅读
书稿 Java 响应式编程
java

6.2 BoundedElastic 与线程池模型

深入 BoundedElastic 的实现:最多 10×CPU 个单线程 worker、每 worker 10 万任务队列、60 秒空闲 TTL,以及「空闲优先、再新建、最后选最闲 worker」的分配策略。用 reactor-core 3.8.8 实测线程创建、复用、回收与队列拒绝,区分直接 schedule 抛异常和 subscribeOn 转成 onError 两种表现,并说明 JDK 21+ 虚拟线程模式与 ExecutorService 的本质差异。

7 分钟阅读
书稿 Java 响应式编程
java

6.1 调度器:单线程、弹性、并行与立即

系统讲解 Reactor 四种内置调度器的线程模型:single 的单线程 FIFO、boundedElastic 的 10×CPU 上限与 10 万/线程队列、parallel 的核数线程与轮询分配、immediate 的调用线程执行。用 reactor-core 3.8.8 实跑输出对比线程名、线程创建数量与任务排队行为,并纠正「boundedElastic 只有 CPU 个线程」「parallel 能让单条流并行」等常见误解。

6 分钟阅读
书稿 Java 响应式编程
java

5.3 超时与取消传播

讲清 timeout(Duration) 的真实语义——首元素超时与元素间隔超时,而不是整个流的总时长;对比 take(Duration) 的完成语义。用实测代码展示取消信号如何向上游传播、doFinally 放在不同位置看到的信号差异、Disposable/CompositeDisposable 的生命周期管理,以及 timeout 无法中断同步阻塞调用的原因与替代方案。示例基于 reactor-core 3.8.8。

6 分钟阅读
书稿 Java 响应式编程
java

5.2 指数退避重试与熔断信号

剖析 retryWhen(Retry) 的 companion 协议:手写 companion 正常完成会向下游发 onComplete 并吞掉原始异常(实测),正确做法是在重试耗尽时显式发出原始错误。对比 Retry.fixedDelay、Retry.backoff、Retry.max 的订阅次数、退避序列与异常类型,给出线性/指数退避的可运行实现、重试与熔断的边界,以及避免无限重试和惊群的配置模板。示例基于 reactor-core 3.8.8。

8 分钟阅读
书稿 Java 响应式编程
java

4.3 组合操作符:zip、merge、combineLatest

对比 zip(配对等待)、merge(先到先发)、combineLatest(最新值组合)三种组合操作符的语义差异,说明它们在元素数量不对等、时序差异、错误传播场景下的行为。重点讲清 zip 的木桶效应与有界预取、merge 的 prefetch 回压(不是无限缓冲)、combineLatest 的初始等待陷阱,以及三种操作符在生产中的选型。

5 分钟阅读
书稿 Java 响应式编程