解决LMAX Disruptor模式中的消费者(eventProcessor)问题

时间:2012-07-23 03:25:14

标签: consumer disruptor-pattern

在使用破坏者时,可能会有一个落后的消费者,并且由于消费者的速度缓慢,整个应用程序都会受到影响。

请记住,每个生产者(发布者)和消费者(EventProcessor)都在单个线程上运行,可以解决缓慢的消费者问题?

我们可以在单个消费者中使用多个线程吗?如果没有,什么是更好的选择?

3 个答案:

答案 0 :(得分:6)

一般来说,使用WorkerPool允许多个池化工作线程在单个消费者上工作,如果您具有独立且可能具有可变持续时间的任务(例如:一些短任务,一些更长),这是很好的。

另一个选择是让多个独立工作者对事件进行并行处理,但每个工作者只处理模N个工作者(例如2个线程,一个线程处理奇数,一个线程处理甚至事件ID)。如果您具有一致的持续时间处理任务,并且允许批处理也能非常有效地工作,那么这非常有用。

要考虑的另一件事是消费者可以进行“批处理”,这在审计中尤其有用。如果您的消费者有10个事件在等待,而不是独立地向审计日志写入10个事件,您可以收集所有10个事件并同时写入它们。根据我的经验,这不仅仅包括运行多个线程的需要。

答案 1 :(得分:3)

尝试将慢速部件分离到其他螺纹(I / O,而不是O(1)或O(日志)计算等),或在消费者超载时施加某种背压(通过屈服或临时停车)生产者,使用503或429状态代码重播等): http://mechanical-sympathy.blogspot.com/2012/05/apply-back-pressure-when-overloaded.html

答案 2 :(得分:0)

使用一组相同的eventHandlers。为了避免单个事件作用于多个eventHandler,我使用以下方法。

创建大小为系统内核数的线程池

Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); // a thread pool to which we can assign tasks

然后创建一个处理程序数组

 HttpEventHandler [] handlers = new HttpEventHandler[Runtime.getRuntime().availableProcessors()];

for(int i = 0; i<Runtime.getRuntime().availableProcessors();i++){
    handlers[i] = new HttpEventHandler(i);
}

disruptor.handleEventsWith(handlers);

在EventHandler中

public void onEvent(HttpEvent event, long sequence, boolean endOfBatch) throws InterruptedException
{
    if( sequence % Runtime.getRuntime().availableProcessors()==id){

        System.out.println("-----On event Triggered on thread "+Thread.currentThread().getName()+" on sequence "+sequence+" -----");
        //your event handler logic
}