能通不等于可用
卷一结束时,你已经能手写一个通过 RS TCK 合规测试的 Publisher,能解释 flatMap 和 concatMap 的无序/有序差异,能为给定场景选择合适的背压策略。这些能力很重要,但它们解决的是「单条数据流内部如何正确运行」的问题。
真实系统中,你面对的不是一条孤立的流,而是:
- 一个 HTTP 网关接收上千并发连接,每个连接都可能触发下游的 R2DBC 查询。
- 一个 WebSocket 广播器向 10 万个会话推送行情,任意一个慢客户端不能拖垮全局。
- 一个缓存层需要在
Mono的惰性求值和数据库的同步 I/O 之间做无缝桥接。 - 一个熔断器需要在响应式流中正确记录失败率,并在半开状态下小心翼翼地恢复流量。
这些场景的共同点是:单条流的正确性只是起点,系统层面的资源管理、服务边界、故障隔离才是胜负手。
卷一回答「流内部发生了什么」。卷二回答「如何把多条流组装成一个可运营的系统」。
从 Publisher 到 HTTP 服务器
卷一最后的 eventd v1 是一个命令行演示程序——SyncSinglePublisher 发射一个字符串,BackpressureDashboard 统计请求率和消费率。虽然它验证了背压原理,但离「生产可用」还差很多层:
| 维度 | eventd v1(卷一) | eventd v2(卷二) |
|---|---|---|
| 协议 | 内存中的方法调用 | HTTP/1.1 + WebSocket |
| 并发 | 单线程演示 | 上千并发连接 |
| 数据存储 | 内存集合 | R2DBC PostgreSQL |
| 缓存 | 无 | Caffeine Async + Redis |
| 安全 | 无 | JWT + CORS |
| 监控 | 控制台打印 | Micrometer + 分布式追踪 |
| 弹性 | 无 | 熔断 + 限流 + 降级 |
| 测试 | JUnit 单元测试 | Testcontainers + 性能压测 |
eventd v2 不是推倒重来——它继承了 v1 的背压意识和信号契约,但把这些能力封装在了 Reactor Netty 和 WebFlux 的组件中。
本卷的边界
卷二不是「Reactor Netty 使用说明书」,也不是「Spring WebFlux 开发指南」。市场上已经有大量这类教程,本卷的目标是从响应式原理出发,理解每个框架能力的底层约束。
| 已有的内容 | 本卷不写 | 本卷写什么 |
|---|---|---|
| 《Netty 高性能网络编程》 | ByteBuf 引用计数、ChannelPipeline 源码 | Reactor Netty 的使用层:HttpServer/HttpClient/WebSocket |
| 《Spring Boot 高级》 | 容器启动、自动配置、AOP | WebFlux 请求管线、函数式路由、过滤器链 |
| 《Java 编程实战》 | JDBC/HikariCP、同步事务 | R2DBC 响应式驱动、响应式事务、Reactive Repository |
| 《Java 消息中间件》三卷 | Kafka Producer/Consumer API | Kafka Streams/Flink(留给卷三) |
| 《Java 并发编程》三卷 | JMM、AQS、线程池源码 | 调度器在响应式系统中的使用(卷一已覆盖) |
三卷路线图
卷一(已完成):RS 规范 → 手写 Publisher → Reactor 核心 → 背压策略 → RS TCK
↓
卷二(本卷):Reactor Netty → WebFlux → R2DBC → 缓存 → 安全 → 监控 → 弹性 → Saga
↓
卷三(未来):Kafka Streams → Flink DataStream → 窗口 → CEP → 实时指标
如何使用本卷
如果你刚读完卷一
- 先读前言确认环境(Reactor Netty 1.3、R2DBC PostgreSQL、Caffeine、Lettuce)。
- 第一部分(第 1–3 章)建立网络服务——从最小 HTTP 服务器到 WebSocket 广播。
- 第二部分(第 4–6 章)用 WebFlux 做 API 层——注解路由、函数式路由、安全、测试。
- 第三部分(第 7–9 章)接入数据——R2DBC 查询、事务、缓存。
- 第四部分(第 10–12 章)做系统整合——监控、弹性、事件驱动。
- 第五部分(第 13–14 章)测试与验收——StepVerifier、Testcontainers、性能压测。
如果你已有 WebFlux 经验
跳过第 4–6 章(WebFlux 基础),直接从第 1 章(Reactor Netty 深入)或第 7 章(R2DBC)开始。重点看第 10–12 章的系统整合和第 13–14 章的测试策略。
如果你只想看可运行代码
读前言(环境)→ 第 3 章(eventd v2 架构)→ 第 9 章(缓存)→ 第 12 章(全链路集成)→ 附录 A(Netty 配置速查)。
贯穿项目:eventd v2
外部客户端
├── HTTP/1.1 → eventd-gateway (Reactor Netty)
└── WebSocket → eventd-gateway (实时推送)
↓
eventd-api (WebFlux)
├── /api/users → UserController (注解路由)
├── /api/orders → OrderRouter (函数式路由)
└── /ws/events → EventWebSocketHandler
↓
eventd-data (R2DBC + Cache)
├── PostgreSQL (users, orders)
├── Caffeine Async (本地缓存)
└── Redis Reactive (分布式缓存)
一个提醒
响应式系统的最大陷阱不是「不会用操作符」,而是在响应式层和阻塞层之间混用,导致整个背压机制失效。
// 危险:在响应式链中调用阻塞数据库
Flux.range(1, 1000)
.flatMap(i -> {
// 阻塞!这里直接在订阅线程上执行,会卡住 Netty 事件循环
User user = jdbcTemplate.queryForObject( // JDBC是阻塞的!
"SELECT * FROM users WHERE id = ?", i);
return Mono.just(user);
})
.subscribe();
本卷的目标不是让你学会更多操作符,而是让你在需要阻塞时知道怎么隔离,在需要响应式时知道怎么衔接。
全书路线
序(本页)→ 前言(环境)→ 目录 → 第 1 章(Reactor Netty 服务器)
→ 第 2 章(客户端与弹性)→ 第 3 章(WebSocket + 网关)
→ 第 4 章(WebFlux 路由)→ 第 5 章(请求/响应/错误)
→ 第 6 章(安全与测试)→ 第 7 章(R2DBC 驱动)
→ 第 8 章(事务与优化)→ 第 9 章(缓存与一致性)
→ 第 10 章(监控与追踪)→ 第 11 章(弹性模式)
→ 第 12 章(全链路集成)→ 第 13 章(测试)
→ 第 14 章(验收)→ 附录
下一章从最小 HTTP 服务器开始:Reactor Netty 的 HttpServer.create()。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。