背压本质是下游按需拉取数据,核心是立即调用subscription.request(n)(n>0),否则流卡死;request(0)触发取消,负数抛异常;缓冲、丢弃、报错策略需依场景选;自定义processor须同步上下游许可。

Java 中响应式编程的背压与流向控制,本质是让下游消费者掌握数据节奏的主动权——不是生产者拼命推,而是消费者按需拉。核心落在 Subscription.request(n) 这个动作上,它既是起点,也是开关。
必须立刻调用 request(),否则流会卡死
在 Subscriber.onSubscribe(Subscription) 回调中,必须立即调用 subscription.request(1) 或其他正整数。这是 Reactive Streams 规范的硬性要求。不调用,上游就不会发任何数据;延迟调用,整个链路就停在那儿不动。
- 别缓存
Subscription实例,收到就用 - 不要等“准备好再请求”,而应先拿一个试探,后续按处理能力动态追加
- 测试时可故意漏掉这行,观察
onNext是否永不触发——这就是背压链路中断的明确信号
request(n) 的数值要合法且有意义
n 必须是大于 0 的正整数。传入 0 会触发取消协议(隐式调用 cancel()),负数直接抛 IllegalArgumentException。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 动态计算请求量时,务必加校验:
if (n > 0) subscription.request(n); - 避免用
request(0)表示“暂停”——这不是暂停,是放弃订阅 - 真要暂停/恢复,应把未满足的请求量暂存在原子计数器里,等消费完成再补发
-
request(Long.MAX_VALUE)等价于取消背压,仅适用于极小、极快、确定可控的场景
缓冲、丢弃、报错:选对策略比写对代码更重要
当消费者跟不上时,不同策略决定系统行为边界:
- 缓冲(Buffer):用队列暂存溢出数据,适合突发流量但需设上限,否则内存爆炸
- 丢弃(Drop):新数据来时老数据被覆盖,适合监控指标、实时音视频等允许丢失的场景
- 报错(Error):缓冲满即抛异常终止流,适合强一致性业务,宁可中断也不积压
- Project Reactor 中对应为
onBackpressureBuffer()、onBackpressureDrop()、onBackpressureError()
自定义 Processor 要同步上下游许可
Processor 同时是 Subscriber 和 Publisher,最容易出问题的地方就是“只顾一头”:
- 从上游
onNext收到数据时,得先检查下游是否还有许可(requested> 0),不能盲目转发 - 向下游
onNext发送后,必须立即减少当前许可计数 - 内部队列不能无限增长,建议用线程安全计数器 + 显式容量限制,而不是依赖默认缓冲
- SubmissionPublisher 的
maxBufferCapacity控制的是阻塞阈值,不是背压许可,别混淆
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










