一、背景
软件定制开发供应商遇到一个现场问题,多个地区(软件定制开发供应商多地独立部署)软件定制开发供应商在某个时间节点之后的软件定制开发供应商消息都不消费了,重启服务之后会消费一部分,过不了多久又会不消费
二、排查过程
2.1查看mq看板
- 看具体的某个消息,都是not_consumer,点击重新发送,可以被正常消费;但是服务不会自动消费
- 未消费的消息进入重试队列,并堆积
2.2查看服务日志
重启之后看日志,从开始消费到不消费,有消费的过程中异常的;捕获异常并不再抛出,重新部署后不再有异常,但是还是会出现不消费的情况
2.3排查结论
从2.1可以看到消息手动是可以消费的,但是不会自动消费了,2.2看服务日志,没有明显报错,那还有什么情况下会出现消息不消费的情况呢?
- 百度:没有得到有价值的问题
- mq的配置问题会不会是有消息消费失败之后就不会继续消费了:从解决异常之后还是会出现这个问题来看并不是配置问题
问题陷入困境,向上求助,提示看服务进程信息
三、dump进程信息分析
3.1dump进程信息
使用命令jps
查看进程号,使用 jstack 进程号 >text.txt
把进程信息保存到本地
3.2看进程信息
我使用的是在线的 https://fastthread.io/ 分析工具
其他还有TDA工具,https://github.com/irockel/tda/releases/tag/2.4
上传线程信息到 该网站
看火焰图
我的思路是先看自己的代码;所以找有自己的代码的线程栈信息
最高的这个线程是自己写的代码的,发现有4个线程在运行,并且是mq的消费者
里面有个doPost请求,会不会是这个请求的问题呢?
先访问这个地址,发现访问不了,按理说访问不了应该会超时抛出异常,但是并没有报错,导致线程一直在等待
四、问题解决
给doPost方法加上超时时间,超过30s就抛出异常,这样mq就不会一直等着了;重启后可以好一会儿是因为没有这个消费者的消息;为什么以前没问题,因为这个地址之前一直可以正常访问,最近由于网络不稳定会出现问题
- http请求要加超时时间,不然会导致线程一直等待
- 如果有个消息没有消费完,mq会一直阻塞等待,导致消息积压