重启rabbitmq后,队列中没有消费者的原因

编程入门 行业动态 更新时间:2024-10-07 22:24:02

重启rabbitmq后,<a href=https://www.elefans.com/category/jswz/34/1771257.html style=队列中没有消费者的原因"/>

重启rabbitmq后,队列中没有消费者的原因

问题:

      上次生产服务器出问题,导致上面的rabbitmq主节点和一系列应用服务宕机。运维先重启应用服务(消费者)后再启动MQ主节点后发现,主节点队列上堆积的消息没有被消费,点进队列一看,没有消费者!

场景复现:

        在开发环境搭建mq集群,模拟生产场景。

场景重现:

        启动消费者应用,可以发现日志报错信息如下:

解释一下意思就是: 消费者发现没有要监听的 queue 时,默认会进行三次重试监听 queue,三次都失败后就无法重试了(三次时间很短,默认10s一次)

此时就算你重启了MQ,但是消费者不会再去监听mq对应队列了,所以MQ的队列上就不会有消费者信息了。

解决办法:

spring通过发布事件的方式,可以通知观察者(即事件监听器)消费者的一些行为,消费者相关的事件如下所示。

  • AsyncConsumerStartedEvent:An event that is published whenever a new consumer is started.
  • AsyncConsumerStoppedEvent:An event that is published whenever a consumer is stopped (and not restarted).
  • AsyncConsumerRestartedEvent:An event that is published whenever a consumer is restarted.
  • ListenerContainerConsumerFailedEvent:Published when a listener consumer fails.

基于事件机制,可以通过监听事件ListenerContainerConsumerFailedEvent,当有消费者发生致命错误时,重新创建消费者消费消息,并发送告警信息给相关责任人。具体实现如下:

import java.util.Arrays;import org.springframework.amqp.rabbit.listener.ListenerContainerConsumerFailedEvent;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;import lombok.extern.slf4j.Slf4j;/*** MQ消费者失败事件监听器* @author wxyh* @date 2018/04/02*/
@Slf4j
@Component
public class ListenerContainerConsumerFailedEventListener implements ApplicationListener<ListenerContainerConsumerFailedEvent> {@Overridepublic void onApplicationEvent(ListenerContainerConsumerFailedEvent event) {log.error("消费者失败事件发生:{}", event);if (event.isFatal()) {log.error(String.format("Stopping container from aborted consumer. Reason::%s.",event.getReason()), event.getThrowable());SimpleMessageListenerContainer container = (SimpleMessageListenerContainer) event.getSource();String queueNames = Arrays.toString(container.getQueueNames());// 重启try {restart(container);log.info("重启队列%s的监听成功!", queueNames);} catch (Exception e) {log.error(String.format("重启队列%s的监听失败!", queueNames), e);}// TODO 告警,包含队列信息,监听断开原因,断开时异常信息,重启是否成功等...}}/*** 重启监听* @param container* @return*/private void restart(SimpleMessageListenerContainer container) {// 暂停30stry {Thread.sleep(30000);} catch (Exception e) {log.error(e.getMessage());}Assert.state(!container.isRunning(), String.format("监听容器%s正在运行!", container));container.start();}}

参考:一文教你如何解决RabbitMQ队列无消费者

        RabbitMQ异常监控及动态控制队列消费的解决方案

更多推荐

重启rabbitmq后,队列中没有消费者的原因

本文发布于:2024-02-13 21:14:22,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1760549.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:队列   重启   消费者   原因   rabbitmq

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!