disruptor高性能需严格遵循其设计规范:ringbuffer容量必须为2的幂次方,事件对象必须复用,多消费者须显式声明依赖关系,waitstrategy需按场景选型,且生产者/消费者逻辑须轻量。

Disruptor 不是“用起来快”,而是“必须按它的方式写,才快”。直接套用传统队列思维(比如当成 LinkedBlockingQueue 替代品)反而会掉进性能陷阱,甚至比原生队列还慢。
RingBuffer 初始化必须设为 2 的幂次方大小
Disruptor 的 RingBuffer 内部靠位运算 index & (size - 1) 快速定位数组下标。如果 size 不是 2 的幂(比如设成 1000),位运算失效,底层会 fallback 到取余 %,性能断崖式下跌。
- ✅ 正确:用
1024、4096、65536这类值 - ❌ 错误:用
1000、5000、10000 - ⚠️ 注意:
RingBuffer.createSingleProducer()和createMultiProducer()都要求 size 是 2 的幂,否则启动时抛IllegalArgumentException
事件对象必须复用,禁止每次 new
Disruptor 的设计前提是事件对象在 RingBuffer 中长期驻留、反复填充。如果每次 publish 都 new 一个新对象,不仅 GC 压力陡增,还会破坏 CPU 缓存局部性——因为新对象内存地址随机,无法命中 L1/L2 缓存行。
- ✅ 正确:定义
LogEvent类,提供setData()、clear()等方法,由EventFactory创建一次后反复 reset - ❌ 错误:在
onEvent()或 publish 回调里new LogEvent(...) - ⚠️ 验证点:用 JFR 或 VisualVM 观察 Eden 区 GC 频率,异常升高基本就是事件对象没复用
多消费者必须显式声明依赖关系,否则乱序
Disruptor 默认不保证多个消费者之间的执行顺序。比如你注册了 persistenceHandler 和 notificationHandler,若未用 .then() 显式串联,它们会并行读同一事件,且各自进度独立——可能通知发了但落库还没写完。
- ✅ 正确:
disruptor.handleEventsWith(persistenceHandler).then(notificationHandler) - ✅ 也可并行但需屏障:
disruptor.after(persistenceHandler).handleEventsWith(notificationHandler)表示 notification 等 persistence 处理完再开始 - ❌ 错误:连续调用两次
handleEventsWith(),以为会自动串行 - ⚠️ 关键机制:背后靠
SequenceBarrier协调,没声明依赖就等于没加 barrier,消费者序列号互不可见
WaitStrategy 选错会导致 CPU 白跑或延迟飙升
等待策略不是“越激进越快”。它决定消费者线程空闲时怎么等新事件:自旋、yield、sleep 还是阻塞?选错会直接拖垮吞吐或耗尽 CPU。
- ✅ 高吞吐低延迟场景(如金融行情):
YieldingWaitStrategy(短时 yield + 自旋) - ✅ 对延迟不敏感但要省 CPU:
BlockingWaitStrategy(本质是LockSupport.park()) - ❌ 别用
SleepingWaitStrategy在高并发写入场景——它固定 sleep 1ns,唤醒开销大,延迟毛刺明显 - ⚠️ 生产环境务必压测对比:同一负载下,
Yielding和Blocking的 P99 延迟可能差 10 倍
最易被忽略的一点:Disruptor 的“极速”只存在于生产者和消费者逻辑本身足够轻量的前提下。一旦你在 onEvent() 里做 DB 写入、HTTP 调用或复杂 JSON 序列化,环形队列再快也救不了——瓶颈立刻转移到下游。真正的优化,永远从拆离重操作开始。










