RabbitMQ学习----------------------ack消息确认机制

       为了保证消息从队列可靠的到达消费者,RabbitMQ提供了消息 确认机制,消费者在订阅队列的时候,可以指定autoAck参数,当autoACK等于false时,RabbitMQ会等待显示的恢复确认信号之后才从内存或者磁盘中移除消息(实质上是先打上删除标记,之后再删除)

       当autoAck属性为true的时候,RabbitMQ会自动把发送出去的消息标记为确认,然后从内存或者磁盘中移除,而不管消费者有没有收到消息。

      采用了这个机制后不用担心消费者接受不到消息的问题因为,消费者就算是挂了,消息会一直存在,消费者服务启动的时候消息就会自动的进行推送,因为RabbitMQ会一直等待持有消息直到消费者显示的调用Basic.ack命令为止。

       当开启消息确认机制以后,对于rabbitmq服务端而言,队列中的消息分成了两个部分,一部分是等待投递给消费者的消息;一部分是已经投递给消费者的消息。如果RabbitMQ一直没有收到消费者的确认信号,并且消费者此消息的消费者已经断开连接,则RabbitMQ会安排重新入队列,等待投递给下一个消费者,当然也有可能是原来的消费者。

     RabbitMQ除了提供了消息确认机制以外,在2.0以后的版本引入了Basic.Reject这个命令,意思是明确拒绝当前消息而不是确认。

单独的给一个消息接收者设置ack。

在springboot中的整合如下:

消费者代码:

在生产者一方提供消息回调机制

package com.gysoft.rabbitmqsoft.ack;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @Description  确认消息后回调
 * @Author DJZ-WWS
 * @Date 2019/7/1 11:22
 */
@Component
public class MsgSendConfirmCallBack  implements RabbitTemplate.ConfirmCallback {
    //ConfirmCallback这个接口是当消息成功到达exchange的时候触发ack回调。
    //ReturnCallback 这个接口当消息成功到达exchange,但是没有队列与之绑定的时候触发ack回调。发生网络分区会出现这种情况
    //生产者端使用ConfirmCallBackHereturnCallBanck回调机制,最大限度的保证消息不丢失,对原有CorrelationData类进行扩展,来实现消息的重发
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init(){
        rabbitTemplate.setConfirmCallback(this);            //指定 ConfirmCallback
    }
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        System.out.println("消息唯一标识:"+correlationData);
        System.out.println("确认结果:"+ack);
        System.out.println("失败原因:"+cause);
    }

}

交换机到队列入队出现错误回调

package com.gysoft.rabbitmqsoft.ack;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

/**
 * @Description  失败后return 回调
 * @Author DJZ-WWS
 * @Date 2019/7/1 11:22
 */
@Component
public class MsgSendReturnCallback  implements RabbitTemplate.ReturnCallback {
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        System.out.println("失败后回调"+message.getBody()+"replyCode:"+replyCode+"replyText :"+replyText
        +"exchange :"+exchange +"routingKey:"+routingKey);
    }
}

 

这里有两个回调,第一个回调是消息到达交换机,会触发 消息回调,

CorrelationData correlationData, boolean ack, String caus

如果消息没有到exchange,则confirm回调,ack=false

如果消息到达exchange,则confirm回调,ack=true

另外一个回调ReturnCallback 这个接口当消息成功到达exchange,但是没有队列与之绑定的时候触发ack回调。发生网络分区会出现这种情况

exchange到queue成功,则不回调return

exchange到queue失败,则回调return(需设置mandatory=true,否则不回回调,消息就丢了)

#交换机到queue成功,则不回调return,交换机到queue失败,则回调return(需要设置mandatory=true,否则不回调,消息就丢失了)
spring.rabbitmq.template.mandatory=true

这两个接口需要增加如下配置:

#开启发送确认  对应ConfirmCallback接口
spring.rabbitmq.publisher-confirms=true
#开启消息返回  对应ReturnCallback接口
spring.rabbitmq.publisher-returns=true

ack一般都会设置为手动的,当业务出现异常了,做一些其他的处理。
参考自《RabbitMQ实战指南》,博客https://blog.csdn.net/qq315737546/article/details/54176560

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值