前言
上周运维将项目的测试环境从k8s中迁出来后,测试发现储能网关一直在上报数据,但是并没有映射到对应的设备上,排查时发现MQ在正常消费,并没有消息挤压,而且日志也没有报错信息,当时就很纳闷,觉得不可思议,通过过滤日志,发现消费了网关的上报的消息,并没有将消息发到设备对应的Topic中,
于是启动本地代码连测试环境,发现我本地并不报错,又只能去测试服务区排查,后面通过arthas拦截处理消息的方法,才看到异常信息,发现是org.redisson.RedissonShutdownException: Redisson is shutdown
,有了异常信息我们就好排查啦。
问题排查
第一步复制异常信息,往百度一贴,看下有没有现成的答案,找了很久只找到一篇使用Redisson实现分布式锁来做秒杀的帖子,链接在这
https://blog.51cto.com/u_15057843/4213532
帖子说是因为主线程关闭了导致Redisson也关闭,子线程还在跑,对我们的帮助不大,我们不是这种情况。继续百度,关于这方面的帖子真的是少的可怜,没办法打开redisson源码的issue,一个个看呗,还真找到了该异常的帖子。
链接如下:https://github.com/redisson/redisson/issues/1030
浏览一下,我把最关键的回复截图出来,人家说了Redisson不会主动调用销毁的方法,肯定是Spring容器调用的,总算是知道原因了,离答案就不远啦。
排查代码
直接在销毁的方法上打了个断点,通过JVM的远程调试功能连上对应的服务,不一会代码就走断点这里停了
然后观察堆栈信息,发现SpringBoot在启动过程中,由于Dubbo服务的端口被占用,启动就报错了,后面换了dubbo的端口,重启后就没有这个问题啦。至于为啥没看到这个端口占用异常日志,是因为我们测试环境在做压测,网关一分钟上报了120w的数据,这日志咔咔咔咔的刷,根本看不到错误日志。
事后
事后真想骂娘,服务都没启动,程序居然还在咔咔咔的消费MQ的消息,至于为啥服务没启动,还一直在消费消息这个问题,肯定是项目中使用了非守护线程,没有关闭。后面发现项目中MQ是自己手写代码启动的,然后容器销毁又没有销毁线程,前人挖坑,后人口吐芬芳。