Reactive Streams 规范
什么是 Reactive Streams
Reactive Streams 是 JVM 上响应式编程的标准规范,定义了异步流处理的接口和协议。
- 发起者:Netflix、Pivotal、Lightbend、Twitter 等公司联合制定
- 目标:解决异步数据流处理中的背压问题
- Java 9:已纳入 JDK,位于
java.util.concurrent.Flow
四个核心接口
Reactive Streams 只定义了 4 个接口,非常简洁:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public interface Publisher<T> { void subscribe(Subscriber<? super T> s); }
public interface Subscriber<T> { void onSubscribe(Subscription s); void onNext(T t); void onError(Throwable t); void onComplete(); }
public interface Subscription { void request(long n); void cancel(); }
public interface Processor<T, R> extends Subscriber<T>, Publisher<R> { }
|
交互流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| ┌──────────────┐ ┌──────────────┐ │ Publisher │ │ Subscriber │ └──────────────┘ └──────────────┘ │ │ │ 1. subscribe(subscriber) │ │ ──────────────────────────────────▶ │ │ │ │ 2. onSubscribe(subscription) │ │ ◀────────────────────────────────── │ │ │ │ 3. request(n) 请求n个数据 │ │ ◀────────────────────────────────── │ │ │ │ 4. onNext(data) 发送数据(最多n个)│ │ ──────────────────────────────────▶ │ │ ... 重复 3-4 ... │ │ │ │ 5. onComplete() 或 onError() │ │ ──────────────────────────────────▶ │ ▼ ▼
|
背压(Backpressure)
背压是 Reactive Streams 的核心特性,解决生产者速度快于消费者的问题。
没有背压的问题
1 2 3
| 生产者:1000条/秒 ──────▶ 消费者:100条/秒 ↓ 内存溢出!
|
有背压的解决方案
1 2 3
| subscription.request(10);
|
背压协议规则
- Subscriber 主动请求:通过
request(n) 告诉 Publisher 需要多少数据
- Publisher 遵守约定:最多发送 n 个数据,不能超发
- 累积请求:多次
request() 的数量会累加
- 无限请求:
request(Long.MAX_VALUE) 表示不限制
规范的实现
| 实现 |
说明 |
使用场景 |
| Project Reactor |
Spring 默认实现 |
Spring WebFlux |
| RxJava |
Netflix 开源 |
Android、通用 |
| Akka Streams |
Lightbend 开源 |
Scala 生态 |
| Java 9 Flow |
JDK 内置 |
标准库 |
Spring 生态使用的是 Project Reactor,下一篇详细介绍。
相关链接
- 下一篇:Project Reactor 实现
- WebFlux - 响应式编程基础