disruptor消息丢失问题排查


背景

  • 学生考试上交的场景,我们先将学生数据持久化存储到mongodb中,就告知学生上交成功。然后通过disruptor消息队列去处理后续业务逻辑。这里的上交场景会存在高并发的情况。
  • 选型disruptor框架的原因是 其强大的单机消息处理能力,我们线上尝试使用。如果消息处理失败,则有相应的补偿措施。
  • 上线之初,对该框架研究不深,已经隐约感觉会有bug在路上。。。

线上问题1-消息丢失

  • 学生反馈作业上交提示成功,但老师端没有收到学生的作业。

排查过程

  • 首先通过kibana日志系统,找到了 handler有error日志。那为什么一个学生处理失败,会导致很多学生作业都消息丢失呢?
    最后看到有帖子指出:消费者的handler处理器没有捕获异常,导致sequence赋值不对。BatchEventProcessor:151

  • handler增加try/catch异常捕获,之后上线运行。一切正常。

  • 看似完美解决,然又一个bug悄然在路上。

线上问题2-同样的问题-消息丢失,学生上交作业未成功

  • kibana中未发现 异常日志。

  • 本地单测压测也没有复现。- 普通的junit模式

  • 这个时候应该想到仔细的去看下源码了。贴一段当时的配置文件的代码

  • producerType:SINGLE,当时的配置。也没有深入研究过 SINGLE 和 MULTI 的区别。

  • 偶然看到一篇帖子写到:producerType = SINGLE,在多线程环境中,会导致消息丢失。立马看到了曙光。

  • 通过jemter 压测50个线程,问题就复现了,消息丢失。

  • 此刻感觉找到问题的原因了。通过阅读 disruptor 源码:SingleProducerSequencer 和 MultiProducerSequencer 发送消息的区别:MULTI通过CAS操作保证了线程安全。MultiProducerSequencer:112

总结

* 通过以上2个问题,完全是使用方式上的问题:handler异常要捕获或者设置自定义异常处理器,以及 producerType设置的不对。
* disruptor是典型的 生产者/消费者模型,观察者模式。每个handler消费者都会由一个线程去消费消息。通过轮询的方式。核心的处理类是 BatchEventProcessor。
* 接下来要去撸源码了。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM