RabbitMQ消息应答机制

消费者接收消息时突然挂掉,为了保证数据不丢失。引入消息应答机制

1.消费者接收消息时手动应答,不进行批处理,批处理时,处理多个消息,而消息是否被处理完成并不知晓,所以关闭批处理。

2.消息自动重新入队:消息未发送ack确认,RabbitMQ了解消息未处理,对消息进行重新排队处理,某个挂掉的消费者处理得任务重新交给其他工作完成的消费者处理。

生产者

package com.zhaoye.three;

import com.rabbitmq.client.Channel;
import com.zhaoye.utils.RabbitMqUtils;

import java.util.Scanner;

/**
 * @author feng
 * @Date 2021/11/3 15:37
 * 消息应答机制:消息不丢失,消息丢失时放入队列重新进行消费
 */
public class Task2 {

    public static final String TASK_QUEUE_NAME = "ack_queue";

    public static void main(String[] args) throws Exception {

        Channel channel = RabbitMqUtils.getChannel();

        channel.queueDeclare(TASK_QUEUE_NAME, false, false, false, null);

        Scanner scanner = new Scanner(System.in);

        while (scanner.hasNext()) {
            String message = scanner.next();
            channel.basicPublish("", TASK_QUEUE_NAME, null, message.getBytes("UTF-8"));
            System.out.println("消息发送完成" + message);
        }


    }
}

消费者c1

package com.zhaoye.three;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.rabbitmq.client.Delivery;
import com.zhaoye.utils.RabbitMqUtils;
import com.zhaoye.utils.SleepUtils;

/**
 * @author feng
 * @Date 2021/11/3 15:48
 */
public class work03 {

    public static final String TASK_QUEUE_NAME = "ack_queue";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();

        System.out.println("c1接收消息时间较短");

        DeliverCallback deliverCallback = (consumerTag,message)->{
            //沉睡1s
            SleepUtils.sleep(1);
            System.out.println("接收到的消息" + new String(message.getBody(),"UTF-8"));
            //接收到消息后,手动应答确认
            /** 1.@tag 消息的标记
             *  2.不进行批量应答
             */
            channel.basicAck(message.getEnvelope().getDeliveryTag(),false);

        };

        CancelCallback cancelCallback = (consumerTag)->{
            System.out.println("消费者取消消息接口逻辑");
        };


        //关闭自动应答
        boolean actoAck = false;
        channel.basicConsume(TASK_QUEUE_NAME,actoAck,deliverCallback,cancelCallback);



    }


}

消费者c2

package com.zhaoye.three;

import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;
import com.zhaoye.utils.RabbitMqUtils;
import com.zhaoye.utils.SleepUtils;

/**
 * @author feng
 * @Date 2021/11/3 15:48
 */
public class work04 {

    public static final String TASK_QUEUE_NAME = "ack_queue";

    public static void main(String[] args) throws Exception {
        Channel channel = RabbitMqUtils.getChannel();

        System.out.println("c2接收消息时间较长");

        DeliverCallback deliverCallback = (consumerTag,message)->{
            //沉睡30s
            SleepUtils.sleep(30);
            System.out.println("接收到的消息" + new String(message.getBody(),"UTF-8"));
            //接收到消息后,手动应答确认
            /** 1.@tag 消息的标记
             *  2.不进行批量应答
             */
            channel.basicAck(message.getEnvelope().getDeliveryTag(),false);

        };

        CancelCallback cancelCallback = (consumerTag)->{
            System.out.println("消费者取消消息接口逻辑");
        };


        //关闭自动应答
        boolean actoAck = false;
        channel.basicConsume(TASK_QUEUE_NAME,actoAck,deliverCallback,cancelCallback);



    }


}

c2在处理dd时突然挂掉,挂掉之后,消息重新回到队列,c1处理消息

c1接收消息时间较短
接收到的消息aa
接收到的消息cc
接收到的消息dd

c2

c2接收消息时间较长
接收到的消息bb

你可能感兴趣的:(rabbitmq,分布式,java)