Disruptor简介:
LMAX Disruptor是一个高性能的线程间消息库。它源于LMAX对并发性,性能和非阻塞算法的研究,如今构成了Exchange基础架构的核心部分。
-
Disruptor它是一个开源的并发框架,并获得2011 Duke’s 程序框架创新奖,能够在无锁的情况下实现网络的Queue并发操作。
-
Disruptor是一个高性能的异步处理框架,或者可以认为是最快的消息框架(轻量的JMS),也可以认为是一个观察者模式的实现,或者事件监听模式的实现。
在这里你可以跟BlockingQueue队列作比对,简单的理解为它是一种高效的"生产者-消费者"模型,先了解后深入底层原理。
Disruptor 的核心概念:
- Ring Buffer 如其名,环形的缓冲区。曾经 RingBuffer 是 Disruptor 中的最主要的对象,但从3.0版本开始,其职责被简化为仅仅负责对通过 Disruptor 进行交换的数据(事件)进行存储和更新。在一些更高级的应用场景中,Ring Buffer 可以由用户的自定义实现来完全替代。
- Sequence Disruptor 通过顺序递增的序号来编号管理通过其进行交换的数据(事件),对数据(事件)的处理过程总是沿着序号逐个递增处理。一个 Sequence 用于跟踪标识某个特定的事件处理者( RingBuffer/Consumer )的处理进度。虽然一个 AtomicLong 也可以用于标识进度,但定义 Sequence 来负责该问题还有另一个目的,那就是防止不同的 Sequence 之间的CPU缓存伪共享(Flase Sharing)问题。
- Sequencer Sequencer 是 Disruptor 的真正核心。此接口有两个实现类 SingleProducerSequencer、MultiProducerSequencer ,它们定义在生产者和消费者之间快速、正确地传递数据的并发算法。
- Sequence Barrier 用于保持对RingBuffer的 main published Sequence 和Consumer依赖的其它Consumer的 Sequence 的引用。 Sequence Barrier 还定义了决定 Consumer 是否还有可处理的事件的逻辑。
- Wait Strategy 定义 Consumer 如何进行等待下一个事件的策略。 (注:Disruptor 定义了多种不同的策略,针对不同的场景,提供了不一样的性能表现)
- Event 在 Disruptor 的语义中,生产者和消费者之间进行交换的数据被称为事件(Event)。它不是一个被 Disruptor 定义的特定类型,而是由 Disruptor 的使用者定义并指定。
- EventProcessor EventProcessor 持有特定消费者(Consumer)的 Sequence,并提供用于调用事件处理实现的事件循环(Event Loop)。
- EventHandler Disruptor 定义的事件处理接口,由用户实现,用于处理事件,是 Consumer 的真正实现。
- Producer 即生产者,只是泛指调用 Disruptor 发布事件的用户代码,Disruptor 没有定义特定接口或类型。
Disruptor代码简单实现
我们就以一个简单例子来实现Disruptor:生产者传递一个long类型变量给消费者,消费者将这个变量打印出来。
单生产者,单消费者模型:
(1)向ringbuffer中插入的事件元素:就是在对象中放了一个long变量
public class LongEvent {
private long value;
public long getValue() {
return value;
}
public void setValue(long value) {
this.value = value;
}
}
(2)事件生产工厂:生产事件存入ringbuffer中
public class LongEventFactory implements EventFactory<LongEvent> {
public LongEvent newInstance() {
return new LongEvent();
}
}
(3)事件处理器,也就是消费者,就是将事件的值打印出来
public class LongEventHandler implements EventHandler<LongEvent> {
public void onEvent(LongEvent event, long sequence, boolean endOfBatch) throws Exception {
System.out.println("Event:"+event.getValue());
}
}
(4)主函数:创建生产者,向ringbuffer中填充元素
public class DisruptorMain {
public static void main(String[] agrs) throws InterruptedException {
//创建线程池:
Executor executor = Executors.newCachedThreadPool();
//事件生产工厂:
LongEventFactory longEventFactory = new LongEventFactory();
//ringbuffer的大小:
int bufferSize = 256;
//实例化disruptor对象:初始化ringbuffer
Disruptor<LongEvent> disruptor = new Disruptor<LongEvent>(longEventFactory, bufferSize, executor,ProducerType.SINGLE, new BlockingWaitStrategy());
//设置事件的执行者:(单消费者)
disruptor.handleEventsWith(new LongEventHandler());
//disruptor启动:
disruptor.start();
RingBuffer<LongEvent> ringBuffer = disruptor.getRingBuffer();
//设置事件单生产者:
for(int x = 0;x<256; x++){
// 获取下一个可用位置的下标
long sequence = ringBuffer.next();
try{
// 返回可用位置的元素
LongEvent event = ringBuffer.get(sequence);
// 设置该位置元素的值
event.set(x);
}finally{
//发布事件
ringBuffer.publish(sequence);
}
Thread.sleep(10);
}
}
}
Disruptor框架和SpringBoot 的整合可以参考Spring boot 整合disruptor