现象:
短信发送业务发现部分客户不能按时收到短信通知,发现Rocketmq 消息消费有延迟。
定位步骤:
查看Rocketmq 控制台,发现topic消费有部分延迟,同一个Client 部分队列能正常消费,但是部分队列消费延迟或者长期不消费。
控制台截图如下:
看到这个现象后就怀疑是客户端某个逻辑出现了死循环或者长时间的Block,于是去打印了线上环境的线程栈。
命令: jstack pid >> 打印到某个文件
根据关键字ConsumeMessageThread 在线程栈里检索MQ消费线程,发现有两个线程长期处于Runnale 状态
最终定位到时邮件发送API transport 默认没有超时时间导致的
at javax.mail.Transport.send0(Transport.java:168)
at javax.mail.Transport.send(Transport.java:98)
解决办法:
邮件发送服务器设置超时时间,不要一直占用线程不释放
总结:
当遇到Rocketmq 部分队列不消费的情况,第一时间应该考虑是不是有线程被死循环占用或者被IO等待一直处于Runnable状态。 可以通过打印当前应用线程栈的方式查看线程信息。