Disruptor 是一个高性能异步处理框架,也可以认为是一个消息通信框架,它本质上为生产者-消费者模型。
Disruptor消息处理流程
Disruptor核心类和接口
EventHandler
:用户提供具体的实现,在里面实现事件的处理逻辑。Sequence
:代表事件序号或一个指向缓存某个位置的序号。WaitStrategy
:功能包括:当没有可消费的事件时,根据特定的实现进行等待,有可消费事件时返回可事件序号;有新事件发布时通知等待的SequenceBarrier
。Sequencer
:生产者用于访问缓存的控制器,它持有消费者序号的引用;新事件发布后通过WaitStrategy
通知正在等待的SequenceBarrier
。SequenceBarrier
:消费者关卡。消费者用于访问缓存的控制器,每个访问控制器还持有前置访问控制器的引用,用于维持正确的事件处理顺序;通过WaitStrategy
获取可消费事件序号。EventProcessor
:事件处理器,是可执行单元,运行在指定的Executor里;它会不断地通过SequenceBarrier
获取可消费事件,当有可消费事件时调用用户提供的EventHandler
实现处理事件。EventTranslator
:事件转换器,由于Disruptor只会覆盖缓存,需要通过此接口的实现来更新缓存里的事件来覆盖旧事件。RingBuffer
:基于数组的缓存实现,它内部持有对Executor
、WaitStrategy
、生产者和消费者访问控制器的引用。Disruptor
:提供了对RingBuffer
的封装,并提供了一些DSL风格的方法,方便使用。
Disruptor门面类
public class Disruptor<T>
{
private final RingBuffer<T> ringBuffer;
private final Executor executor;
private final ConsumerRepository<T> consumerRepository = new ConsumerRepository<T>();
private final AtomicBoolean started = new AtomicBoolean(false);
private ExceptionHandler exceptionHandler;
}
EventHandler
public interface EventHandler<T>
{
/**
* Called when a publisher has published an event to the {@link RingBuffer}
*
* @param event published to the {@link RingBuffer}
* @param sequence of the event being processed
* @param endOfBatch flag to indicate if this is the last event in a batch from the {@link RingBuffer}
* @throws Exception if the EventHandler would like the exception handled further up the chain.
*/
void onEvent(T event, long sequence, boolean endOfBatch) throws Exception;
}
EventProcessor
public interface EventProcessor extends Runnable
{
/**
* Get a reference to the {@link Sequence} being used by this {@link EventProcessor}.
*
* @return reference to the {@link Sequence} for this {@link EventProcessor}
*/
Sequence getSequence();
/**
* Signal that this EventProcessor should stop when it has finished consuming at the next clean break.
* It will call {@link SequenceBarrier#alert()} to notify the thread to check status.
*/
void halt();
boolean isRunning();
}
RingBuffer
public final class RingBuffer<E> implements Cursored, DataProvider<E>
{
public static final long INITIAL_CURSOR_VALUE = Sequence.INITIAL_VALUE;
private final int indexMask;
private final Object[] entries;
private final int bufferSize;
private final Sequencer sequencer;
}
RingBuffer(EventFactory<E> eventFactory,
Sequencer sequencer)
{
this.sequencer = sequencer;
this.bufferSize = sequencer.getBufferSize();
if (bufferSize < 1)
{
throw new IllegalArgumentException("bufferSize must not be less than 1");
}
if (Integer.bitCount(bufferSize) != 1)
{
throw new IllegalArgumentException("bufferSize must be a power of 2");
}
this.indexMask = bufferSize - 1;
this.entries = new Object[sequencer.getBufferSize()];
fill(eventFactory);
}
Disruptor简单使用示例
Disruptor<MyEvent> disruptor = new Disruptor<MyEvent>(MyEvent.FACTORY, 32, Executors.newCachedThreadPool());
EventHandler<MyEvent> handler1 = new EventHandler<MyEvent>() { ... };
EventHandler<MyEvent> handler2 = new EventHandler<MyEvent>() { ... };
disruptor.handleEventsWith(handler1);
disruptor.after(handler1).handleEventsWith(handler2);
RingBuffer ringBuffer = disruptor.start();