Disruptor之基础入门
什么是Disruptor
Disruptor是一个高性能的并发编程框架,旨在提供低延迟和高吞吐量的数据处理能力。它由LMAX交易所开发,最初用于金融交易系统,但其设计理念和实现方式使其适用于各种需要高性能数据处理的场景;
核心的设计理念是认为队列是一种糟糕的抽象,因为它暗示了数据必须在不同上下文之间被复制排队进行处理,LMAX Disruptor哲学核心是通过共享内存、序列同步,而不是通过消息排队,来实现线程间通信。
由于Disruptor只是一个队列,对于事件的处理并不会有性能上的提高,它提高的是使用传统队列时的性能损耗,传统的队列会因为锁竞争、缓存行失效等问题导致性能下降,而Disruptor通过无锁设计和缓存行填充等技术来减少这些问题,从而实现高性能的事件传递。
Disruptor的使用
基础使用
- 单个生产者,单个消费者模式
Disruptor1P1C
使用Disruptor步骤如下
第一步是创建一个Disruptor实例,需要指定4个参数分别是:
- 事件工厂,用于RingBuffer预创建事件实例对象使用
- 消费者线程工厂,用于创建消费者线程,这一点设计可以参考下一篇文章有详细的分析
- 环形缓冲区大小,必须是2的N次方,用于设置RingBuffer的大小
- 生产者类型(单个生产者或多个生产者)
- 等待策略(BlockingWaitStrategy、SleepingWaitStrategy、YieldingWaitStrategy、BusySpinWaitStrategy),用于设置消费者等待事件的策略;
第二步是注册消费者
第三步是生产者填充RingBuffer并发布事件
- 单个消费者,多个生产者-广播模式
通过handleEventsWith方法注册多个消费者,消息会被多个消费者消费

- 单个消费者,单个消费组-事件模式
事件只会被同一个消费组中的某一个hadnler消费,不同消费组之间是并行消费的,消费组之间是完全隔离的互不影响

- 单个消费者,多个消费组-事件模式
事件只会被同一个消费组中的某一个hadnler消费,不同消费组之间是并行消费的,消费组之间是完全隔离的互不影响

- 单个消费者,多个消费组串行-事件模式
Disruptor1P1GThan1G

小结:通过实现EventHandler接口的处理方法是处理广播模式,通过WorkHandler接口的处理方法是处理事件模式;
对事件的处理方法可以使用handleEventsWithWorkerPool方法注册多个消费组,消费者之间可以通过then方法串行处理,通过after方法配合handleEventsWith来指定消费组之间的依赖关系,实现链式\菱形\六边形等消费模式;
适用场景
Disruptor解决的问题是队列在高并发场景下由于锁竞争、缓存行失效等问题导致的性能瓶颈,因此对于性能瓶颈在事件处理上的场景,Disruptor并不能带来性能提升,反而会因为其复杂性带来额外的开销;
以下是一些适合使用Disruptor的场景:
- 高频交易系统:需要处理大量的交易请求,对延迟和吞吐量有极高的要求;
这个是一个简单的撮合引擎示例,使用Disruptor实现高性能的订单撮合交易,我们重点关注ExchangeLauncher对disruptord分组使用,ResultsHandler对事件的处理操作;
-
日志操作:Log4j2使用Disruptor实现异步日志记录,提高日志写入性能;
-
2.1 创建Disruptor实例
AsyncLoggerDisruptor.disruptor -
2.2 消费者Handler
AsyncLoggerDisruptor.createEventHandler() -
2.3 生产者发布日志事件
[AsyncLogger.handleRingBufferFull()](https://github.com/apache/logging-log4j2/blob/dc6c53ab7bb195f3878d3ee92cd0ff20634326f1/log4j-core/src/main/java/org/apache/logging/log4j/core/async/AsyncLogger.java#L277;
-
-
Axon Framework:使用Disruptor实现事件处理和命令处理;
- 3.1 创建Disruptor实例
DisruptorEventBus.createDisruptor() - 3.2 消费者Handler
EventProcessorHandler - 3.3 生产者发布事件
EventProcessorHandler.doDispatch()
- 3.1 创建Disruptor实例