RabbitMQ消费者为何会突然神秘消失,排查方法有哪些?

摘要:开心一刻 今天好哥们找我借钱哥们:兄弟,我最近手头紧,能不能借我点...我:我手头也不宽裕,要不你试试银行贷款或者花呗?哥们:不行,那个借了要还的我:... 问题回顾 某天下午,生产监控告警:消息积压,队列 xxx 消息数超过 100;我第
开心一刻 今天好哥们找我借钱 哥们:兄弟,我最近手头紧,能不能借我点... 我:我手头也不宽裕,要不你试试银行贷款或者花呗? 哥们:不行,那个借了要还的 我:... 问题回顾 某天下午,生产监控告警:消息积压,队列 xxx 消息数超过 100;我第一时间想到的是应用服务是不是停了,但应用服务存活监控又没有告警,但我还是找值班运维同事帮忙确认了下,确认结果是服务的 6 个节点都是存活的,然后我又让运维确认了下队列的消费者情况,结果发现消费者列表中只有 2 个节点的消费者,其他 4 个节点的消费者不见了,所以消息消费不过来,导致了消息积压! 所以问题来了 那 4 个节点的注册的消费者为何消失? 但当务之急是解决消息积压的问题,所以让运维重启那 4 个节点的服务,消费者重新注册上,消息得以快速消费,消息积压告警得以恢复 生产问题虽暂时得以解决,但未找到根因,还是存在复发风险;下面就请大家跟随我的脚步,来看看我是如何排查的 问题排查 直接查 ERROR 级别的日志,很容易就能就找到了关键日志 Consumer thread error, thread abort. 以及异常堆栈 java.lang.OutOfMemoryError: Requested array size exceeds VM limit at java.lang.StringCoding$StringEncoder.encode(StringCoding.java:300) at java.lang.StringCoding.encode(StringCoding.java:344) at java.lang.String.getBytes(String.java:918) ... Consumer thread error, thread abort 大家能看懂吧,就是字面意思 消费者线程错误,线程终止 消费者线程就是我们前面提到的队列消费者,一个队列消费者就是一个消费者线程,消费者线程终止那就意味着队列消费者终止,也就对应文章标题中的 消费者消失;是不是离真相越来越近了? OutOfMemoryError 是不是很熟悉,内存溢出嘛 OutOfMemoryError 表示 Java 虚拟机在堆内存中没有足够的空间来分配对象 问你们一个问题:OOM 一定会导致 JVM 退出吗,这个问题你们先思考,后面答案会揭晓 回到正题,从关键日志以及异常堆栈,我们是不是可以得出以下推测 OOM 会导致消费者线程终止 有了推测,那就去验证呗;我先给大家模拟下案例,基于 SpringBoot,pom.xml 关键依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> 配置文件 application.yml server: port: 8088 spring: rabbitmq: host: 192.168.2.118 port: 5672 username: admin password: admin virtual-host: / listener: simple: acknowledge-mode: manual #设置确认模式手工确认 concurrency: 3 #消费者个数,线程个数 prefetch: 1 RabbitMQ 配置 TaskRabbitConfig.java package com.qsl.rabbit.config; import com.qsl.rabbit.constant.Constant; import com.qsl.rabbit.listener.TaskMessageListener; import org.springframework.am
阅读全文