线上异常信息打印分析"/>
rocketMQ线上异常信息打印分析
前言
- 最近生产环境日志上一直打印一个关于rocketMQ的异常信息:defaultMQProducer send exception
- 然后线上MQ消息是发送成功了,消费端也成功消费。感觉没有影响到其他业务,当时业务挺忙,就没有去检查具体的原因,
- 现在空闲下来了,就根据打印的异常堆栈信息跟踪分析一波。
分析过程
- 首先线上MQ消息都是使用同步方式发送,超时时间使用默认值3秒
- 根据异常打印的信息,可以确认是在发送MQ消息时抛出的异常信息,而且其打印的异常信息还不属于MQ客户端自定义异常
- 根据堆栈异常信息溯源,中间过滤掉一些执行链路,最后抛异常的位置方法invokeSyncImpl()
- 首先调用netty的writeAndFlush()方法,将数据写入socket,然后添加到一个监听器中,发送失败会执行唤醒线程。
- 进入图中圈入的.waitResponse(timeoutMillis)方法,里面有countDownLatch.await(timeoutMillis, TimeUnit.MILLISECONDS)超时阻塞方法,继续深入
- 这里有个tryAcquireSharedNanos()方法
其定义:尝试在共享模式下获取,如果中断将中止,如果给定的超时时间过去,将失败。首先检查中断状态,然后至少调用一次{@link#tryAcquireShared},并在成功时返回。否则,线程将排队,可能会重复阻塞和取消阻塞,调用{@link#tryAcquireShared},直到成功或线程中断或超时。
- 在方法入口处有个检测当前线程是否中断的方法Thread.interrupted(),如果返回true(表示当前线程已经中断,否则返回false),就直接抛出异常
- 根据上诉抛异常的堆栈信息日志中,表明就是这里抛出异常信息,说明当前线程已经中断,所以其不属于MQ客户端自定义异常。
总结
- 分析到这里,说明当前发送MQ消息的线程被中断了,然后MQ里等待获取响应结果时检测到了线程中断抛出该异常信息。所以这里抛出异常信息也没有影响到生产环境的其他业务,因为消息也发送成功了,然后消息也消费了。
如此就反推看看当前发送MQ业务所执行的线程是怎么被中断的
- 线上某业务使用线程池执行,但为了防止其执行太久阻塞了其他业务,就设定过期超时强制关闭线程池任务机制,如果这时发送MQ线程等待其响应时检测当前线程是否中断,结果就是抛出异常信息。
- 因为这里是产品核心业务,也是主要的营收业务,不能对其进行调整,所以就只有过滤掉当前异常信息日志。
最后
- 虚心学习,共同进步 -_-
更多推荐
rocketMQ线上异常信息打印分析
发布评论