RabbitMQ---重新投递到不存在的exchange 导致MQ无法提供服务

4 篇文章 0 订阅

本文环境:springboot 1.5.8.RELEASE + amqp-client 4.0.3.jar

记一个很神奇的bug。

场景:开启生产者确认模式,指定了自定义ConfirmCallback实现类。

尝试投递到不存在的exchange,成功回调confim接口,随后再次重发该信息。

但意外的是,不止没有回调confirm接口。还导致整个rabbitMQ卡死,发送消息到其他交换机一样无作用。

原因:

上述操作:“尝试投递到不存在的exchange”,会产生一个ERROR:

ERROR org.springframework.amqp.rabbit.connection.CachingConnectionFactory - Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'noexist' in vhost '/', class-id=60, method-id=40)

这个error,不管是否开启了生产者确认模式,都是会触发的。

但在实现了生产者确认模式后,会在confirm接口回调完毕之后再触发

但因为在confirm回调中,又进行了重发消息的操作。

这样就形成了一个死循环

  • confirm不完成,error就不触发
  • error不触发,RabbitMQ就不能提供服务
  • RabbitMQ不提供服务,重发消息就无法完成,阻塞在那里
  • 重发消息不完成,confirm就不能完成

禁止套娃

因此即使是发送到其他存在的交换机的信息,也会因为RabbitMQ无法提供服务,而阻塞。

但需要注意的是,其他任务是可以正常进行的(CPU没资源之类的除外)。辅助跑了个定时任务,是可以正常输出的。


解决办法:
很简单。就是不要在confirm里面重新发送,交给延迟队列或者定时任务完成,就解决了


直观的感受一下:

代码:

rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println("---------触发confirm-----------");
                mqSender.reSendMiaoshaMessage(miaoshaMessage, 
                System.out.println("----------confirm触发完成----------");
            }
        });
public void reSendMiaoshaMessage(MiaoshaMessage mm,CorrelationData correlationData) {
        System.out.println("重发消息");
        String msg = RedisService.beanToString(mm);
        rabbitTemplate.convertAndSend("notExist", MQConfig.MIAOSHA_ROUTING_KEY, msg, correlationData);
        System.out.println("重发消息完成");
    }

控制台输出:

在这里插入图片描述


这么神奇的bug,估计没几个人遇到,所以网上找过一轮都没有蛛丝马迹。

mark一下,能遇上这个bug的,感觉都是有缘人……


本文完,有误欢迎指出

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值