序:从能通到可运营

本序声明卷二的定位——把卷一手写的 Publisher/Subscriber 能力组装成可运行的 HTTP 服务和数据管道,覆盖 Reactor Netty、WebFlux、R2DBC、响应式安全与监控;同时声明与卷一(背压原理)和卷三(流处理引擎)的边界。

能通不等于可用

卷一结束时,你已经能手写一个通过 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 高级》容器启动、自动配置、AOPWebFlux 请求管线、函数式路由、过滤器链
《Java 编程实战》JDBC/HikariCP、同步事务R2DBC 响应式驱动、响应式事务、Reactive Repository
《Java 消息中间件》三卷Kafka Producer/Consumer APIKafka Streams/Flink(留给卷三)
《Java 并发编程》三卷JMM、AQS、线程池源码调度器在响应式系统中的使用(卷一已覆盖)

三卷路线图

卷一(已完成):RS 规范 → 手写 Publisher → Reactor 核心 → 背压策略 → RS TCK
       ↓
卷二(本卷):Reactor Netty → WebFlux → R2DBC → 缓存 → 安全 → 监控 → 弹性 → Saga
       ↓
卷三(未来):Kafka Streams → Flink DataStream → 窗口 → CEP → 实时指标

如何使用本卷

如果你刚读完卷一

  1. 先读前言确认环境(Reactor Netty 1.3、R2DBC PostgreSQL、Caffeine、Lettuce)。
  2. 第一部分(第 1–3 章)建立网络服务——从最小 HTTP 服务器到 WebSocket 广播。
  3. 第二部分(第 4–6 章)用 WebFlux 做 API 层——注解路由、函数式路由、安全、测试。
  4. 第三部分(第 7–9 章)接入数据——R2DBC 查询、事务、缓存。
  5. 第四部分(第 10–12 章)做系统整合——监控、弹性、事件驱动。
  6. 第五部分(第 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()。

继续阅读

探索更多技术文章

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

全部文章 返回首页

「java」更多文章

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