rocketMQ线上异常信息打印分析

前言

  • 最近生产环境日志上一直打印一个关于rocketMQ的异常信息:defaultMQProducer send exception

BEDF1FD2-FAD9-41dd-B6E6-D3E6EEE2F581.png

  • 然后线上MQ消息是发送成功了,消费端也成功消费。感觉没有影响到其他业务,当时业务挺忙,就没有去检查具体的原因,
  • 现在空闲下来了,就根据打印的异常堆栈信息跟踪分析一波。

分析过程

  • 首先线上MQ消息都是使用同步方式发送,超时时间使用默认值3秒
  • 根据异常打印的信息,可以确认是在发送MQ消息时抛出的异常信息,而且其打印的异常信息还不属于MQ客户端自定义异常

同步发送方法图.png
抛异常图.png

  • 根据堆栈异常信息溯源,中间过滤掉一些执行链路,最后抛异常的位置方法invokeSyncImpl()
  • 首先调用netty的writeAndFlush()方法,将数据写入socket,然后添加到一个监听器中,发送失败会执行唤醒线程。

2.png

  • 进入图中圈入的.waitResponse(timeoutMillis)方法,里面有countDownLatch.await(timeoutMillis, TimeUnit.MILLISECONDS)超时阻塞方法,继续深入

3.png

  • 这里有个tryAcquireSharedNanos()方法

其定义:尝试在共享模式下获取,如果中断将中止,如果给定的超时时间过去,将失败。首先检查中断状态,然后至少调用一次{@link#tryAcquireShared},并在成功时返回。否则,线程将排队,可能会重复阻塞和取消阻塞,调用{@link#tryAcquireShared},直到成功或线程中断或超时。

  • 在方法入口处有个检测当前线程是否中断的方法Thread.interrupted(),如果返回true(表示当前线程已经中断,否则返回false),就直接抛出异常
  • 根据上诉抛异常的堆栈信息日志中,表明就是这里抛出异常信息,说明当前线程已经中断,所以其不属于MQ客户端自定义异常。

总结

  • 分析到这里,说明当前发送MQ消息的线程被中断了,然后MQ里等待获取响应结果时检测到了线程中断抛出该异常信息。所以这里抛出异常信息也没有影响到生产环境的其他业务,因为消息也发送成功了,然后消息也消费了。
    如此就反推看看当前发送MQ业务所执行的线程是怎么被中断的

4.png

  • 线上某业务使用线程池执行,但为了防止其执行太久阻塞了其他业务,就设定过期超时强制关闭线程池任务机制,如果这时发送MQ线程等待其响应时检测当前线程是否中断,结果就是抛出异常信息。
  • 因为这里是产品核心业务,也是主要的营收业务,不能对其进行调整,所以就只有过滤掉当前异常信息日志。

最后

  • 虚心学习,共同进步 -_-
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值