Disruptor 等待策略介绍
一、等待策略分类与原理
1. BlockingWaitStrategy(阻塞等待策略)
- 原理:
使用ReentrantLock和Condition实现线程阻塞,当没有新事件时,消费者线程被挂起,直到生产者发布新事件后唤醒。 - 特点:
- 低 CPU 消耗:线程挂起时不占用 CPU。
- 高延迟:线程唤醒涉及上下文切换,延迟较高(微秒级)。
- 适用场景:
- 对延迟不敏感的后台任务(如日志异步写入)。
- 资源受限环境(如嵌入式系统)。
RingBuffer<Order> ringBuffer = RingBuffer
.createMultiProducer(() -> new Order(), ringBufferSize,
new BlockingWaitStrategy());
2. BusySpinWaitStrategy(忙循环等待策略)
- 原理:
消费者线程通过 死循环(Busy Spin) 持续检查是否有新事件,不释放 CPU 资源。 - 特点:
- 极低延迟:无上下文切换,延迟可低至纳秒级。
- 高 CPU 消耗:持续占用 CPU 核心(100% 利用率)。
- 适用场景:
- 超低延迟的金融交易系统(如高频交易)。
- 物理隔离的 CPU 核心(独占核心避免干扰)。
RingBuffer<Order> ringBuffer = RingBuffer
.createMultiProducer(() -> new Order(), ringBufferSize,
new BusySpinWaitStrategy());
3. YieldingWaitStrategy(让步等待策略)
- 原理:
在循环检查事件时,若未发现新事件,调用Thread.yield()主动让出 CPU 时间片。 - 特点:
- 低延迟:延迟在百纳秒至微秒级。
- 中 CPU 消耗:比忙循环更友好,但仍有较高占用。
- 适用场景:
- 延迟敏感且 CPU 资源充足的场景(如实时风控系统)。
- 需要平衡吞吐量与资源消耗的服务。
RingBuffer<Order> ringBuffer = RingBuffer
.createMultiProducer(() -> new Order(), ringBufferSize,
new YieldingWaitStrategy());
4. SleepingWaitStrategy(睡眠等待策略)
- 原理:
采用渐进式等待:- 先进行有限次数的忙循环检查(默认 200 次)。
- 若仍无事件,调用
Thread.sleep(1)进入睡眠。
- 特点:
- 中低延迟:初始阶段快速响应,睡眠后延迟增加。
- 低 CPU 消耗:睡眠期间不占用 CPU。
- 适用场景:
- 突发流量场景(如电商秒杀)。
- 允许偶尔延迟波动的数据处理任务。
RingBuffer<Order> ringBuffer = RingBuffer
.createMultiProducer(() -> new Order(), ringBufferSize,
new SleepingWaitStrategy());
5. LiteBlockingWaitStrategy(轻量级阻塞策略)实验性
- 原理:
类似BlockingWaitStrategy,但使用更轻量的锁机制(如自旋锁短暂尝试后阻塞)。 - 特点:
- 中延迟:比传统阻塞策略略快。
- 中低 CPU 消耗:减少锁竞争开销。
- 适用场景:
- 中等吞吐量的订单处理系统。
- 需要平衡稳定性和性能的服务。
6. TimeoutBlockingWaitStrategy(超时阻塞策略)
- 原理:
在BlockingWaitStrategy基础上增加超时机制,若指定时间内无事件,抛出超时异常。 - 特点:
- 可控延迟:避免无限期阻塞。
- 低 CPU 消耗:与阻塞策略一致。
- 适用场景:
- 需要超时控制的批处理任务。
- 防止消费者线程饿死的容错场景。
RingBuffer<Order> ringBuffer = RingBuffer
.createMultiProducer(() -> new Order(), ringBufferSize,
new TimeoutBlockingWaitStrategy(10, TimeUnit.SECONDS));
二、策略对比与选型指南
| 策略类型 | 延迟 | CPU 占用 | 吞吐量 | 适用场景 |
|---|---|---|---|---|
| BlockingWaitStrategy | 高 (μs级) | 低 | 中 | 资源敏感型后台任务 |
| BusySpinWaitStrategy | 极低 (ns级) | 极高 | 极高 | 高频交易、雷达信号处理 |
| YieldingWaitStrategy | 低 (百ns) | 高 | 高 | 实时计算、游戏服务器 |
| SleepingWaitStrategy | 中 (μs级) | 低 | 中高 | 流量突增场景、日志收集 |
| LiteBlockingWaitStrategy(实验性) | 中 | 中低 | 中 | 通用业务系统 |
| TimeoutBlockingWaitStrategy | 高 | 低 | 中 | 需要超时控制的异步任务 |
三、使用场景示例
1. 金融交易系统
- 需求:纳秒级延迟,容忍高 CPU 消耗。
- 策略:
BusySpinWaitStrategy - 配置要点:
- 绑定消费者线程到独立 CPU 核心。
- 关闭其他无关后台进程。
2. 实时日志收集
- 需求:允许微秒级延迟,减少 CPU 占用。
- 策略:
SleepingWaitStrategy或BlockingWaitStrategy - 配置要点:
- 设置合理的忙循环次数(如 100~500 次)。
- 监控缓冲区填充率,动态调整生产者速率。
3. 电商订单处理
- 需求:平衡吞吐量与稳定性,避免资源耗尽。
- 策略:
YieldingWaitStrategy - 配置要点:
- 结合背压机制控制生产者速度。
- 使用多级消费者链(如:订单校验 → 库存扣减)。
4. 动态策略切换
- 根据系统负载动态调整策略(需自定义实现):
public class AdaptiveWaitStrategy implements WaitStrategy { // 根据 CPU 使用率或缓冲区填充率切换策略 }
总结
Disruptor 的等待策略是其高性能的基石,选择合适策略需要综合考量 延迟要求、吞吐量目标 和 资源约束。对于关键系统,建议通过以下步骤决策:
- 压测验证:模拟真实流量,对比不同策略的指标。
- 渐进调优:从保守策略(如
Blocking)开始,逐步向激进策略(如BusySpin)优化。 - 监控告警:实时监控消费者延迟和 CPU 负载,设置动态调整阈值。

浙公网安备 33010602011771号