Disruptor中遇到的坑

经朋友推荐,我在项目采用lmax的disruptor无锁队列框架来实现异步记录监控统计信息。disruptor体积很小,功能强大,一路配置下来,很容易上手,而且经过测试发现确实吞吐量比blockqueue性能提升了好几个数量级。可是直到有一天突然发现好久没收到监控的统计数据了,于是检查服务,发现服务状态是正常的,而且监控的定时任务也在后台定时收集,但数据库确实没更新;于是分几个方面来排查问题

1 检查db环境是否正常,其他服务也共用同一个db 但业务都正常运行,排除是db层的问题

2 通过jstack命令查看堆栈情况,一查看发现好多线程都在disruptor的produce进行nextsequence的时候在等待,问题基本定位了就是disruptor出现了死锁,网上也找到了几篇关于disruptor死锁的文章看了下 说是disruptor3.3.2的bug

Affects AAffects Version:3.3.2  Fix version:3.3.6
JDK 1.8
Cause: Nope this is not resolved by dropping the events. Ring Buffer Works on Producer and Consumer Thread Model.This issue actually happened due to signal missed by consumer. As per LMAX disruptor signal miss should not happen. 
这不是通过删除事件来解决。 环形缓冲区在生产者和消费者线程模型上工作。这个问题实际上是由于消费者错过信号而发生的。 根据LMAX中断器信号缺失不应该发生。 

If it detects that the ring buffer is full it will re-signal the wait strategy, this should unstick the consumer if it happened to miss a signal.
 如果它检测到环形缓冲区已满,它将重发信号的等待策略,如果它碰巧错过一个信号,这应该解锁消费者。
也可以改用Add LiteTimeoutBlockingWaitStrategy 

于是换成了disruptor3.3.6 并且也使用了LiteTimeoutBlockingWaitStrategy

可是过了2个月又出现了死锁的问题了,没办法 ,只能硬着头皮看disruptor看看有没有什么新发现,

disruptor的事件发布是通过rightbuffer环形队列来生产和消费消息的, 为了避免未消费事件的写入覆盖,Sequencer需要监听所有消费者的消息处理进度,也就是gatingSequences。RingBuffer通过这种方式实现了事件缓存的无锁设计。 通过看源码发现是生产者速度大于消费者,导致生产一直在等待消费者消费完毕。

可是消费者执行不应该这么慢啊,怎么会消费很低呢,无意中看到了

com.lmax.disruptor.FatalExceptionHandler handleEventException
严重: Exception processing: 7490 com.tmri.cc.soa.disruptor.MonitiorEvent@75dc8e5b

于是有重点看下异常处理的源码


public void handleEventException(Throwable ex, long sequence, Object event) {
    this.logger.log(Level.SEVERE, "Exception processing: " + sequence + " " + event, ex);
    throw new RuntimeException(ex);
}

和BatchEventProcess的源码

catch (final Throwable ex)
{
    exceptionHandler.handleEventException(ex, nextSequence, event);
    sequence.set(nextSequence);
    nextSequence++;
}
原理是消费的过程中出现了异常,但没处理,被disruptor的workprocesser cath到了然后由默认FatalExceptionHandler处理,本意是FatalExceptionHandler 处理完之后 设置sequence,结果throw了异常 没处理导致。于是自定义了exceptionHandler 处理掉了异常,问题解决



你可能感兴趣的:(Disruptor中遇到的坑)