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

附录 E:RS TCK 测试方法参考

按 reactive-streams-tck 1.0.4 实际源码整理四类验证基类:PublisherVerification 38 个用例(22 required)、SubscriberWhiteboxVerification 27 个(14 required)、SubscriberBlackboxVerification 26 个(11 required)、IdentityProcessorVerification 68 个(38 required)。逐条列出真实方法名、对应规范条款、抽象方法签名与被标记为 untested 的规则,并给出 TestNG 运行方式、Flow 适配写法和实测通过/跳过计数。

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

附录 C:背压规则清单

按 Reactive Streams 1.0.4 原文重列 43 条规则:Publisher 11 条、Subscriber 13 条、Subscription 17 条、Processor 2 条,并标注每条规则与 request/emit 主链的关系及 TCK 覆盖情况。纠正旧文把 §2 与 §3 对调、「15 条中 9 条与背压相关」的错误,并用实测说明两参数 onBackpressureBuffer 的溢出语义,以及 delayElements 为什么不能当作背压缓冲边界。

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

附录 B:调度器选择指南

按 Reactor 3.8.8 的实际行为给出调度器选择依据:parallel 用于非阻塞 CPU 任务,boundedElastic 用于阻塞 I/O,single 用于需要串行执行的任务;同时纠正三个常见误解——interval 在 parallel 上不会并发执行、boundedElastic 的线程是按需创建而非固定 CPU×10、JDK 10+ 的 availableProcessors 已经容器感知。附 cgroup v1/v2 的核对方法与 VirtualTimeScheduler 的正确写法。

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

14.3 v1 验收:RS 合规、背压可观测、文档

按仓库真实状态做验收,而不是把计划全部打勾:编译通过(约 3 秒),但仓库里没有 TCK 测试类、没有 eventd-app 入口、没有 README,因此合规与可运行两项尚未达成。列出实际命令与真实失败输出,区分「章节中验证过的独立实验」和「仓库内可重复的测试」,并给出补齐验收所需的最小工作清单。

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

14.2 eventd v1 性能基线

给出一套可复现的小型测量方法,而不是编造吞吐数字:1M 元素的 Flux.range、1M 次 Mono.just 订阅、1M 次 SyncSinglePublisher 订阅各跑 5 轮取中位数;另用 publishOn 测 10 万元素的调度延迟分位数。本机实测 Flux.range 约 6ms、Mono.just 单次订阅约 24ns、手写订阅约 6ns,p50 调度延迟 5μs、p99 11μs。同时说明为什么 onBackpressureBuffer 加在 Flux.range 上、totalMemory 差值和 delayElements 都不能当作有效的性能证据。

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

14.1 用 Project Reactor 重写 eventd

把第 2、3、13 章的手写实现逐个映射到 Reactor:SyncSinglePublisher 对应 Mono.just,AsyncRangePublisher 对应 Flux.range + subscribeOn,SensorSimulatorPublisher 对应 Flux.create + sink.onRequest。重点不是行数,而是语义差异:Mono.just(null) 直接抛 NPE,raw Subscription.request(0) 报 §3.9 错误而 BaseSubscriber.request(0) 被静默忽略,scheduleAtFixedRate 不等于有背压的传感器源。

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

13.2 传感器模拟器:带背压的随机数据流

实现一个真正响应 request 的 SensorSimulatorPublisher:指数分布间隔、饱和需求累加、wip 串行化、取消时中断工作线程、非正请求转 onError。给出 request(5)、request(0)、取消与慢消费者的实测输出,并说明为什么总耗时接近 max(到达时间, 处理时间) 而不是简单的「生产者等待」。最后给出使用 Flux.create + onRequest 的 Reactor 等价写法及其适用边界。

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

13.1 eventd v1 架构与模块划分

按仓库当前真实状态介绍 eventd v1:父 POM + eventd-core + eventd-app 三个模块,eventd-core 目前只有 SyncSinglePublisher 与 LoggingSubscriber 两个类。给出本机 mvn clean compile 的真实结果和 dependency:tree 原始输出,并解释一个容易踩的坑:这两个类实现的是 java.util.concurrent.Flow 接口,而 RS TCK 验证的是 org.reactivestreams 接口,两者形状相似但不能直接互传,需要适配。

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

12.2 调试技术:Hooks 与检查点

用同一段代码的实测栈对比三种手段:默认 subscribe() 会把错误交给 onErrorDropped 并只打印操作符内部帧;Hooks.onOperatorDebug() 增加 Assembly trace 与 Error has been observed 站点;checkpoint() 只在标记处报告,且 3.8.8 只有三个重载,没有所谓「条件检查点」。同时给出 log() 的真实输出格式、MDC 跨线程失效的原因,以及为什么不能用一次计时估算调试开销。

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

12.1 生命周期钩子:doOn* 系列

用实测输出纠正几个常见误解:doOnTerminate 在下游收到 onComplete/onError 之前执行,doAfterTerminate 在下游处理完之后执行;doOnEach 只看到 onNext/onError/onComplete,看不到 onSubscribe 和 cancel;doOnRequest 报告的是请求量而不是实际产量。同时给出 doFinally 的 SIGNAL 类型、取消路径的顺序、钩子所在线程,以及为什么不能用一次 nanoTime 测量钩子开销。

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

11.3 Subscriber 与 Processor 合规测试

分清 SubscriberWhiteboxVerification 与 SubscriberBlackboxVerification 的真实抽象方法:白盒通过 WhiteboxSubscriberProbe 注册 onSubscribe/onNext/onError/onComplete,并用 SubscriberPuppet 控制 request 与 cancel;黑盒的 triggerRequest 默认是空实现。给出可编译、14 个必测项全部通过的白盒骨架,用实测失败信息解释 spec205 要求取消的是「新收到的重复订阅」而不是旧订阅,并展示 IdentityProcessorVerification 的四个抽象方法与 PublishProcessor 的 14 项实败。

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

11.2 Publisher 合规测试

按真实方法名梳理 PublisherVerification 的必测项:createPublisher 精确元素数、spec101 请求与发射数量、spec102 可少发、spec103 串行信号、spec105 完成信号、spec107 终止后静默、spec109 订阅规则、spec302 同步 request、spec303 递归深度、spec306/307 取消后 no-op、spec309 非正请求、spec312/313 取消语义、spec317 长整型需求。实测 38 个用例中 29 通过、7 个 untested、2 个因无失败 Publisher 跳过,并给出两条真实失败信息与定位方法。

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

11.1 RS TCK:测试环境搭建

搭建 Reactive Streams TCK 1.0.4 测试环境:确认它依赖 TestNG 7.3.0、存在独立的 reactive-streams-tck-flow 构件与 FlowPublisherVerification 类,给出普通 Publisher 与 java.util.concurrent.Flow 两套最小依赖和验证基类的真实抽象方法。实测 TestEnvironment 默认超时为 100ms(可用 DEFAULT_TIMEOUT_MILLIS 覆盖),并用一次真实运行说明 38 个用例中 29 通过、9 跳过的构成。

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

10.3 RxJava 3 与 Reactor 的迁移对照

给出 RxJava 3 到 Project Reactor 的逐项映射:Observable/Single/Maybe/Completable 与 Flux/Mono 的类型对应,doOnEach、throttleFirst、throttleLast、sample、debounce、onErrorReturn、retryWhen 的真实差异,以及调度器命名对照。重点列出六个迁移陷阱:Observable 无背压、Reactor 没有 onErrorReturn(Function)、Subject 需要 toSerialized、Sinks 返回 FAIL_NON_SERIALIZED、flatMap 默认并发 2147483647 对 256、trampoline 不等于 immediate。示例基于 RxJava 3.1.12 与 reactor-core 3.8.8。

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

10.2 ConnectableObservable 与 connect

对比 RxJava 的 ConnectableObservable 与 Reactor 的 ConnectableFlux:publish/connect 的延迟连接、refCount 在订阅归零时断开并在下次订阅时重新订阅源、autoConnect(n) 只在凑够 n 个订阅者时连接一次。实测 RxJava refCount 重连后 starts=2、interval 从 0 重新计时,autoConnect(2) 在只有一个订阅者时完全不启动;并纠正「Reactor 的 connect() 没有返回值」的错误说法。示例基于 RxJava 3.1.12 与 reactor-core 3.8.8。

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

10.1 RxJava Subject:与 Sinks 的对照

对比 RxJava 3 的五种 Subject(PublishSubject、BehaviorSubject、ReplaySubject、AsyncSubject、UnicastSubject)与 Reactor Sinks 的语义映射。实测 late subscriber 在 PublishSubject 下丢失历史、BehaviorSubject 补最新值、AsyncSubject 只在完成时发射,并用并发探针证明裸 Subject 的 onNext 不会串行化(maxConcurrent=2),必须 toSerialized()(maxConcurrent=1)。示例基于 RxJava 3.1.12 与 reactor-core 3.8.8。

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