0

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

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

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

目前我放弃这是因为WaitStrategy,disruptor因为在正常条件下按预期工作。我们正在使用BlockingWaitStrategy那里。

为了示例的更多解释

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

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

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

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

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

提前致谢。

萨尔瓦。

4

1 回答 1

0

某大学发现此问题可能与 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 抛出异常时。

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

任何关于它的内容都是受欢迎的。

于 2015-03-13T16:40:30.923 回答