RabbitMQ消息确认机制

1、可靠抵达

        为保证消息不丢失,可靠抵达,可以使用事务消息,性能下载250倍(官网说明)。为此引入确认机制

 

publisher confirmCallback 确认模式

 

在配置文件设置

 spring.rabbitmq.publisher-confirms=true

1)、在创建connectionFactory的时候设置publisherConfirms(true) 选项,开启confirmcallback.

 

  //设置确认回调
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /**
             *   1、只要消息抵达Broker就ack=true
             * @param correlationData  当前消息的唯一关联数据(这个是消息的唯一id)
             * @param ack 消息是否成功收到
             * @param cause 失败的原因
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println("confirm...correlationData["+correlationData+"]==>ack["+ack+"]==>cause["+cause+"]");
            }
        });

2)、CorrelationData:用来表示当前消息唯一性

3)、消息只要被broker接收到就会执行confirmCallback ,如果是cluster(集群)模式,需要所有broker接收到才会调用confirmCallback

4)、被broker接收到只能表示message已经到达服务器,并不能保证消息一定会被投递目标queue里。所有需要用到接下来的returnCallback. 

 

         

publisher returnCallback 未投递到queue 退回模式

        

#开启发送端消息抵达队列的确认
spring.rabbitmq.publisher-returns=true
#只要抵达队列,以异步发送优先回调我们这个returnconfirm
spring.rabbitmq.template.mandatory=true

 

rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            /**
             * 只要消息没有投递给指定的队列,就触发这个失败的回调
             * @param message  投递失败的消息详细信息
             * @param replyCode 回复的状态码
             * @param replyText 回复的文本内容
             * @param exchange  当时这个消息发给那个交换机
             * @param routingKey 当时这个消息用那个路由键
             */
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                System.out.println("Fail Message["+message+"]==>replyCode["+replyCode+"]====>replyText["+replyText+"]===>exchange["+exchange+"]==>routingKey["+routingKey+"]");
            }
        });

 

        1)、confirm模式只能保证消息到达broker,不能保证消息准确投递到目标queue里。在有些业务场景下,我们需要保证消息一定要投递到目标queue里,此时就需要用到return退回模式。 

        2)、这样如果未能投递到目标queue里将调用returnCallback,可以记录下详细到投递数据,定期的巡检或者自动纠错都需要这些数据。

 

consumer ack机制

(启用手动ack机制,就不会出现宕机后消息丢失)

(也可以启动拒收,然后重新放回队列,或者丢弃)

#手动ack消息
spring.rabbitmq.listener.simple.acknowledge-mode=manual
  //签收货物,非批量模式
        try {
            if(deliveryTag%2==0){
                //收货
                channel.basicAck(deliveryTag,false);
                System.out.println("签收了。。"+deliveryTag);
            }else{
                //退货 requeue=false 丢弃,requeue=true 发回服务器,服务器重新入队。
                channel.basicNack(deliveryTag,false,false);
                System.out.println("没有签收。。");
            }

        } catch (Exception e) {
            //网络终端

        }

 

1)、消费者获取到消息,成功处理,可以回复Ack给Broker 

        basic.ack用户肯定确认;broker将移除次消息

        basic.nack用户否定确认;可以指定broker是否丢弃此消息,可以批量

        basic.reject用户否定确认;同上,但不能批量

2)、默认自动ack,消息被消费者收到,就会从broker(代理服务器)的queue中移除

3)、queue无消费,消息依然会被存储,直到消费者消费

4)、消费者收到消息。默认会自动ack。如果无法确认消息是否被处理完成或者成功处理。我们可以开启手动ack模式

        消息处理成,ack(),接受下一个消息,此消息broker(代理服务器)就会移除

        消息处理失败,nack()/reject(),重新发送给其他人处理,或者容错后ack

        消息一直没有调用ack/nack方法,broker(代理服务器)认为此消息正在被处理,不会投递给别人,此时客户端断开,消息不会被broker移除,会投递给别人

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐路上的小人物

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值