当我们的一个EventHandler崩溃时,我们遇到了高CPU使用率的情况。
假设我们有几个消费者(EventHanlders
),它们被配置为在缓冲区上顺序运行。如果第一个EventHandler抛出异常,是否有办法停止(并稍后唤醒它们)所有其他EventHandler。
我们正在做的是将失败的线程置于睡眠状态,并在我们尝试再次使用相同的事件之后。但我们注意到其他线程继续运行并尝试从RingBuffer
读取,即使没有要读取的事件,也会将CPU提高到可接受的水平。
目前我因为WaitStrategy
的{{1}}而放弃了这种情况,因为在正常情况下正在按预期工作。我们在那里使用disruptor
。
为了示例而进行了一些解释
BlockingWaitStrategy
其中INPUT是从INPUT -> [A*] -> [B] -> [C] -> [D]
轮询的事件,而A,B,C和D是顺序执行的不同EventHandler。 A *是消费者抛出异常。
我们想要实现的是当消费者A不能消费事件时(例如,在异常发生之后),该消费者的OnEvent(...)方法不会退出但会保持在循环中并且经常尝试睡眠当它醒来时再次消耗相同的事件。与此同时,所有其他消费者应该停放或睡觉,直到A成功。
我们正在使用disruptor版本3.3.0。
我一直在谷歌搜索,但没有找到一个有效的解决方案。
提前致谢。
萨尔瓦。
答案 0 :(得分: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抛出异常时。
我们仍在调查这是否是一个有效的解决方案,或者它是否会产生一些不良副作用。
任何关于它的欢迎。