【问题标题】:Disruptor park/halt several EventHandlers when exception occurs发生异常时,Disruptor 停放/停止几个 EventHandler
【发布时间】:2015-03-11 13:00:38
【问题描述】:

当我们的一个 EventHandler 发生故障时,我们遇到了 CPU 使用率过高的情况。

假设我们有几个消费者 (EventHanlders),它们被配置为在缓冲区上按顺序运行。如果第一个 EventHandler 抛出异常,是否有办法停止(并稍后唤醒它们)所有其他 EventHandler。

我们正在做的是让失败的线程进入睡眠状态,然后我们再次尝试使用相同的事件。但我们注意到,即使没有要读取的事件,其他线程仍在继续运行并尝试从 RingBuffer 读取,从而将 CPU 提高到可接受的水平。

目前我放弃了这种情况,因为WaitStrategydisruptor,因为在正常情况下按预期工作。我们在那里使用BlockingWaitStrategy

为了这个例子,还有一些解释

INPUT -> [A*] -> [B] -> [C] -> [D] 

其中 INPUT 是从RingBuffer 轮询的事件,A、B、C 和 D 是按顺序执行的不同 EventHandler。 A* 是消费者抛出异常。

我们想要实现的是,当消费者 A 无法消费事件时(例如,发生异常后),该消费者的 OnEvent(...) 方法不会退出,而是会保持在循环中并定期尝试睡眠唤醒时再次消费相同的事件。与此同时,所有其他消费者都应该停车或睡觉,直到 A 成功。

我们正在使用破坏者版本 3.3.0。

我一直在谷歌搜索,但没有找到可行的解决方案。

提前致谢。

萨尔瓦。

【问题讨论】:

    标签: multithreading event-handling disruptor-pattern lmax


    【解决方案1】:

    一所大学发现此问题可能与 BlockingWaitStrategy 中的 waitFor 方法中的 while 循环有关。

        long availableSequence;
        while((availableSequence = dependentSequence.get()) < sequence) {
            barrier.checkAlert();
        }
    

    经过多次测试,我们发现了这个可能的解决方案:

    var availableSequence: Long = dependentSequence.get()
    
    while(availableSequence < sequence) {
      this.lock.lock()
      this.lock.unlock()
      availableSequence = dependentSequence.get()
    }
    
    availableSequence
    

    基本上,它使一个线程锁定资源,并且我们暂时停放所有其他消费者,避免 CPU 的高使用率。

    这里的第二点是while条件。仅当可用序列(即相关线程的序列)低于当前序列号时才会发生这种情况。这只发生在一个线程持有锁时,例如当 A 抛出异常时。

    我们仍在调查这是否是一个有效的解决方案,或者它是否会产生一些不希望的副作用。

    欢迎任何关于它的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-13
      • 1970-01-01
      • 1970-01-01
      • 2011-04-21
      • 1970-01-01
      相关资源
      最近更新 更多