【RabbitMq】05 RabbitMq 消息确认机制-可靠抵达

一、保证消息不丢失
1、使用事务消息,性能下降250倍
2、消息确认机制

1)publisher confirmCallback 确认模式

2)publisher returnCallback 未投递到queue退回模式

3)consumer ack 机制

二、可靠抵达-ConfirmCallback
1、配置

spring.rabbitmq.publisher-confirms=true

2、说明

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

  1. CorrelationData: 用来表示当前消息唯一性

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

  1. 被broker 接受到只能表示message 已经到达服务器,并不能保证消息一定会被投递到目标queue里。所以需要用到returnCallback
@Autworied
private RabbitTemplate rabbitTemplate;
/**
* 使用JSON 序列化机制,进行消息转换
*/
@Bean
public MessageConverter messageConverter() {
    return new Jackson2JsonMessageConverter();
}

/**
* 定制RabbitTemplate 
* 1、spring.rabbitmq.publisher-confirms=true
* 2、设置确认回调
*/
@PostConstruct //MyRabbitConfig 对象创建完成以后,执行这个方法
public void initRabiitTemplate() {
    // 设置确认回调
    rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
        /**
        * correlationData  当前消息的唯一关联数据(这个是消息的唯一id)
        * ack 消息是否成功收到
        * cause 失败的原因
        */
        @Override
        public void confirm(CorrelationData correlationData, boolean ack, String cause) {
            // 做一些操作
        }
    });
}

三、可靠抵达-ReturnCallback
1、配置

spring.rabbitmq.publisher-returns=true
spring.rabbitmq.template.mandatory=true

2、说明

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

2)如果未能投递目标queue 里将调用returnCallback,可以记录下详细的投递数据,在定期的巡检或者自动纠错使用。

@PostConstruct //MyRabbitConfig 对象创建完成以后,执行这个方法
public void initRabiitTemplate() {
    // 设置确认回调
    rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
        /**
        * 只要消息没有投递给指定的队列,就触发这个失败回调
        * message 投递失败的消息详细信息
        * replayText 回复的状态码
        * replayCode
       * exchange 当这个消息发送给那个交换机
       * routingKey 消息使用的那个routingKey
       */
        @Override
        public void returnMessage(Message message, int replayCode, String replayText, String exchange, String routingKey) {
            // 做一些操作
        }
    });
}

四、可靠抵达-Ack消息确认机制
1、消费者获取到消息,成功处理,可以回复Ack给Broker

  1. basic.ack 用于肯定确认;broker 将移除此消息。

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

3) basic.dreject 用于否定确认;可以指定broker是否丢此消息,不可以批量

2、默认,消息被消费者收到,就会从broker的queue 中移除

3、queue 五消费者,消息依然会被存粗。但是如果无法确定此消息是否被批处理完成,或者成功处理。我们可以开启手动ack模式

1)消息处理成功,ack(),接受下一个消息,此消息broker就会移除

2)queue 无消费者,默认会手动ack。但是如果无法确定此消息是否被处理完成,或者成功处理。可以启动手动ack模式。
a: 消息处理成功,ack,接受一下这个消息,此消息broker就会移除。
b: 消息处理失败,nack()/reject(),重新发送给其他人进行处理,或者容错处理后ack
c: 消息一直没有调用ack/nack方法,broker 认为此消息正在被处理,不会投递给别人,此时客户端断开,消息不会被broker移除,会投递给别人。

# 手动ack消息
spring.rabbitmq.listener.simple.acknowledge-model=manual

byte[] body = message.getBody();
// 消息头属性信息
MessageProperties properties = message.getMessageProperties();
// 处理消息
...
long deliverTag = message.getMessageProperties().getDeliverTag();
try {
  // 接受消息
  channel.basicAck()    
} catch(Exception e) {
    // 异常处理
}

你可能感兴趣的:(RabbitMq)