Disruptor 框架源码分析

Disruptor 是一个高性能异步处理框架,也可以认为是一个消息通信框架,它本质上为生产者-消费者模型。

Disruptor消息处理流程

https://i-blog.csdnimg.cn/blog_migrate/29ebcb205c89daa8c02162f6d178ec37.png

Disruptor核心类和接口

  • EventHandler:用户提供具体的实现,在里面实现事件的处理逻辑。
  • Sequence:代表事件序号或一个指向缓存某个位置的序号。
  • WaitStrategy:功能包括:当没有可消费的事件时,根据特定的实现进行等待,有可消费事件时返回可事件序号;有新事件发布时通知等待的SequenceBarrier
  • Sequencer:生产者用于访问缓存的控制器,它持有消费者序号的引用;新事件发布后通过 WaitStrategy 通知正在等待的SequenceBarrier
  • SequenceBarrier:消费者关卡。消费者用于访问缓存的控制器,每个访问控制器还持有前置访问控制器的引用,用于维持正确的事件处理顺序;通过WaitStrategy获取可消费事件序号。
  • EventProcessor:事件处理器,是可执行单元,运行在指定的Executor里;它会不断地通过SequenceBarrier获取可消费事件,当有可消费事件时调用用户提供的EventHandler实现处理事件。
  • EventTranslator:事件转换器,由于Disruptor只会覆盖缓存,需要通过此接口的实现来更新缓存里的事件来覆盖旧事件。
  • RingBuffer:基于数组的缓存实现,它内部持有对ExecutorWaitStrategy、生产者和消费者访问控制器的引用。
  • Disruptor:提供了对 RingBuffer 的封装,并提供了一些DSL风格的方法,方便使用。

Disruptor门面类

  1. public class Disruptor<T>  
  2. {  
  3.     private final RingBuffer<T> ringBuffer;  
  4.     private final Executor executor;  
  5.     private final ConsumerRepository<T> consumerRepository = new ConsumerRepository<T>();  
  6.     private final AtomicBoolean started = new AtomicBoolean(false);  
  7.     private ExceptionHandler exceptionHandler;  
  8. }  
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

  1. public interface EventHandler<T>  
  2. {  
  3.     /** 
  4.      * Called when a publisher has published an event to the {@link RingBuffer} 
  5.      * 
  6.      * @param event published to the {@link RingBuffer} 
  7.      * @param sequence of the event being processed 
  8.      * @param endOfBatch flag to indicate if this is the last event in a batch from the {@link RingBuffer} 
  9.      * @throws Exception if the EventHandler would like the exception handled further up the chain. 
  10.      */  
  11.     void onEvent(T event, long sequence, boolean endOfBatch) throws Exception;  
  12. }  
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

  1. public interface EventProcessor extends Runnable  
  2. {  
  3.     /** 
  4.      * Get a reference to the {@link Sequence} being used by this {@link EventProcessor}. 
  5.      * 
  6.      * @return reference to the {@link Sequence} for this {@link EventProcessor} 
  7.      */  
  8.     Sequence getSequence();  
  9.   
  10.     /** 
  11.      * Signal that this EventProcessor should stop when it has finished consuming at the next clean break. 
  12.      * It will call {@link SequenceBarrier#alert()} to notify the thread to check status. 
  13.      */  
  14.     void halt();  
  15.   
  16.     boolean isRunning();  
  17. }  
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

  1. public final class RingBuffer<E> implements Cursored, DataProvider<E>  
  2. {  
  3.     public static final long INITIAL_CURSOR_VALUE = Sequence.INITIAL_VALUE;  
  4.   
  5.     private final int indexMask;  
  6.     private final Object[] entries;  
  7.     private final int bufferSize;  
  8.     private final Sequencer sequencer;  
  9. }  
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;
}
  1. RingBuffer(EventFactory<E> eventFactory,  
  2.            Sequencer       sequencer)  
  3. {  
  4.     this.sequencer    = sequencer;  
  5.     this.bufferSize   = sequencer.getBufferSize();  
  6.   
  7.     if (bufferSize < 1)  
  8.     {  
  9.         throw new IllegalArgumentException(“bufferSize must not be less than 1”);  
  10.     }  
  11.     if (Integer.bitCount(bufferSize) != 1)  
  12.     {  
  13.         throw new IllegalArgumentException(“bufferSize must be a power of 2”);  
  14.     }  
  15.   
  16.     this.indexMask = bufferSize - 1;  
  17.     this.entries   = new Object[sequencer.getBufferSize()];  
  18.     fill(eventFactory);  
  19. }  
    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简单使用示例

  1. Disruptor<MyEvent> disruptor = new Disruptor<MyEvent>(MyEvent.FACTORY, 32, Executors.newCachedThreadPool());  
  2. EventHandler<MyEvent> handler1 = new EventHandler<MyEvent>() { … };  
  3. EventHandler<MyEvent> handler2 = new EventHandler<MyEvent>() { … };  
  4. disruptor.handleEventsWith(handler1);  
  5. disruptor.after(handler1).handleEventsWith(handler2);  
  6.   
  7. RingBuffer ringBuffer = disruptor.start();  
 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();




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值