前言:上篇文章说了发送端消息确认机制,该篇介绍消费端消息确认机制。

消费端确认(在确保每个消息被正确消费的情况,此时才可以将broker 删除这个消息)

消费端消息机制默认是自动确认的,只要消息接收到,客户端会自动确认,服务端就会移除这个消息,但是该情况下存在问题:

当服务器突然宕机的情况下,此时的消费者接收到消息,但是并没有签收确认,这个时候这条消息就会丢失

所以我们这时候可以将自动消费设置成手动签收消息

spring:

  rabbitmq:

    listener:

      simple:

        acknowledge-mode: manual

acknowledge-mode: none 自动模式(默认开启)

acknowledge-mode: manual  手动模式

acknowledge-mode: auto 自动模式 (根据侦听器检测是正常返回、还是抛出异常来发出 ack/nack)

手动模式可以确保我们在没有签收的情况下保证消息的不丢失。即使服务器宕机的情况下,只要没有手动ack,都是unacked状态,这时候会将这条消息重新放回队列,变成ready状态。

    @RabbitHandler

    public void receiveMessage(Message message,MessageUtil messageUtil, Channel channel){

        //channel内按顺序自增

        long deliveryTag = message.getMessageProperties().getDeliveryTag();

        try {

             /**

             * 签收货物   false为非批量签收

             *

             */

            channel.basicAck(deliveryTag,false);

        } catch (IOException e) {

            System.out.println(e);

        }

        System.out.println("接受到的消息为:"+messageUtil);

    }

我们打开RabbitMQ的channel源码,basicAck两个参数分别为:

void basicAck(long deliveryTag, boolean multiple) throws IOException;

 我们可以手动退货,相关参数

             *  1. channel内顺序自增ID

             *  2. multiple false为不是批量退货

             *  3. requeue 为是否返回队列 true 返回 ,false 丢弃

代码示例为:

            /**

             * 退货

             *  1. channel内顺序自增ID

             *  2. multiple false为不是批量退货

             *  3. requeue 为是否返回队列 true 返回 ,false 丢弃

             */

            channel.basicNack(deliveryTag,false,true);

好了,消息确认机制就写到这了。

原文链接:https://blog.csdn.net/qq_40438883/article/details/120885123