rabbitmq高级特性(1):消息确认,持久性,发送方确认和重试机制

目录

1.消息确认机制

1.1.消息确认机制介绍

2.1.Spring-AMQP的三种消息确认(重点)

2.持久性

2.1.交换机持久性

2.2.队列持久性

2.3.消息持久性

3.发送方确认

3.1.confirm确认模式

3.2.return退回模式

4.重试机制

4.1.重试机制定义

4.2.重试机制代码的准备工作

4.3.重试机制演示


1.消息确认机制
1.1.消息确认机制介绍

这里的消息确认机制,指的是消费者对消息的确认,而不是生产者。

(1)背景缘由

当消费者把消息发送出去后,就会把消息删除。如果消费者这边处理消息成功,则相安无事;但是如果处理异常,消息也就会丢失。所以就需要设置消费者的消息确认模式

(2)消息确认的机制

消息确认机制分为两个大类:自动确认和手动确认

手动确认又分为三种模式:肯定确认、否定确认、否定批量确认

对于rabbitmq的操作有两种,我们主要介绍第二种

  1. 直接使用amqb提供的包(RabbitMQ Java Client库)
  2. 使用spring集成进来的

第一种介绍: 

对于第一种主要把autoAck参数设置成false即为手动确认,改成true即为自动确认。收到确认需要调用Channel.basicAck函数

//自动确认,第二个参数为true
channel.basicConsume(Constants.RPC_RESPONSE_QUEUE,true,consumer);
//收到确认,第二个参数为false
DefaultConsumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String request = new String(body,"UTF-8");
                System.out.println("接收到请求:"+ request);
                String response = "针对request:"+ request +", 响应成功";
                AMQP.BasicProperties basicProperties = new AMQP.BasicProperties().builder()
                        .correlationId(properties.getCorrelationId())
                        .build();
                channel.basicPublish("", Constants.RPC_RESPONSE_QUEUE, basicProperties, response.getBytes());//返回响应
                channel.basicAck(envelope.getDeliveryTag(), false);//手动确认
            }
        };
channel.basicConsume(Constants.RPC_REQUEST_QUEUE,false,consumer);//false
  • 自动确认:当autoAck为true时,RabbitMQ会自动把发出去的消息设置为确认,然后从内存(硬盘)删除,而不会去管消费者是否真正的消费到该消息。适用对消息可靠性要求不高的场景
  • 收到确认:当autoAck为false时,RabbiMQ会等待消费者显示地调用Basic.Ack命令,回复确认信号之后才会删除该消息。适用对消息可靠性要求比较高的场景

2.1.Spring-AMQP的三种消息确认(重点)

关于消息确认机制的问题:none自动确认(不管消息是否收到)、auto成功收到删除,异常收到不确认、manual手动确认

none:

(1)成功处理:不考虑

(2)消费异常:队列也会直接将消息删除

auto:

(1)成功处理--不考虑

(2)消费异常:队列不会把消息删除

  • 没有进行异常捕获 --- 会一直尝试消费消息并一直报异常,队列不会把该消息删除,也就是不会确认消息
  • 进行了异常捕获 --- 消费逻辑只会执行一次并,队列会删除消息

manual:手动确认模式(肯定确认和否定确认)

(1)成功处理

  • 进行了肯定确认,队列将消息进行删除
  • 没有进行肯定确认,队列会将消息从ready至为unacked

(2)消费异常

下面的情况是进行了异常的捕获 

  • 进行否定确认,但不重新入队 --- 队列会直接将消息删除
  • 进行了否定确认,并且重新入队 --- 消息会重新入队,也就是队列不会将消息删除

以上是消息确认机制的情况总结。

下面展示代码:

配置文件:除了manual模式,其他模式只需要配置了就会生效

mamual模式的确认机制:

@RabbitListener(queues = Constant.ACK_QUEUE)
public void ackQueue2(Message message, Channel channel) throws IOException {
    long deliveryTag = message.getMessageProperties().getDeliveryTag();
    System.out.println("消息是:"+new String(message.getBody()));
    System.out.println("deliveryTag下标是:"+deliveryTag);
    try {
        System.out.println("消费异常前");
        int a=10/0;
        System.out.println("消费异常后");
        channel.basicAck(deliveryTag, false);
    }catch (Exception e) {
        System.out.println("消费异常");
        channel.basicNack(deliveryTag, false, true);
    }
}

下面这一段写的无需观看,都是一些学习时写的混乱思路


Spring-AMQP提供了三种消息确认机制

public enum AcknowledgeMode {
    NONE ,
    MANUAL ,
    AUTO ;
}
  1. AcknowledgeMode.NONE:这种也就是对应自动确认模式。消息一旦投递给消费者,不关消费者是否成功处理,RabbitMQ都会自动确认消息,就会把消息删除。
  2. AcknowledgeMode.AUTO(默认):这种模式下,消费者处理成功会自动确认消息,但是如果处理失败就会抛出异常,不会确认消息。
  3. AcknowlegeMode.MANUAL:手动确认模式。消费者必须在成处理消息后显示的调用basicAck方法来确认消息。如果消息未被确认,RabbitMQ会认为消息尚未被成功处理,并且会重新投递消息。

(1)收到确认的两个方法

(2)先准备好下面的代码

1)常量类

public class Constant {

    //消息确认机制
    public static final String ACK_QUEUE = "ack_queue";
    public static final String ACK_EXCHANGE = "ack_exchange";
    
}

2)配置类和配置文件

@Configuration
public class AckConfig {

    //消息确认机制
    @Bean("ackQueue")
    public Queue ackQueue() {
        return QueueBuilder.durable(Co
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

代码小娥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值