第一章:响应式编程的背压处理
在响应式编程中,数据流通常由发布者(Publisher)推送给订阅者(Subscriber),当发布者生产数据的速度远超订阅者消费能力时,就会引发背压(Backpressure)问题。若不妥善处理,可能导致内存溢出或系统崩溃。响应式流规范(Reactive Streams)通过提供非阻塞的回压机制,使订阅者能够按自身处理能力请求适量数据。背压的常见策略
- 缓冲(Buffer):将超出处理能力的数据暂存于队列中
- 丢弃(Drop):当缓冲满时丢弃新到达的数据
- 限速(Rate Limiting):控制数据发射频率
- 拉取模式(Pull-based):由订阅者主动请求指定数量的数据
使用 Project Reactor 实现背压控制
// 创建一个高速发射整数的 Flux
Flux fastPublisher = Flux.range(1, 1000)
.doOnRequest(n -> System.out.println("请求 " + n + " 个数据"));
// 订阅并应用背压策略:每次请求 100 个
fastPublisher
.onBackpressureBuffer(50, // 缓冲区大小为 50
(value, buffer) -> {
System.out.println("缓冲区溢出,丢弃值: " + value);
})
.subscribe(
data -> {
try {
Thread.sleep(10); // 模拟慢速处理
} catch (InterruptedException e) {}
System.out.println("接收到: " + data);
},
error -> System.err.println("错误: " + error),
() -> System.out.println("完成"),
subscription -> subscription.request(100) // 初始请求 100
);
不同背压策略对比
| 策略 | 适用场景 | 风险 |
|---|---|---|
| Buffer | 短暂速度差异 | 内存溢出 |
| Drop | 允许丢失数据 | 信息丢失 |
| Latest | 只关心最新值 | 中间状态丢失 |
graph LR
A[Publisher] -->|高速发射| B{背压策略}
B --> C[Buffer]
B --> D[Drop]
B --> E[Latest]
B --> F[Error]
C --> G[Subscriber]
D --> G
E --> G
F --> G
1527

被折叠的 条评论
为什么被折叠?



