【java】RabbitMQ-RabbitMQ消息确认机制

问题产生背景: 

生产者发送消息出去之后,不知道到底有没有发送到RabbitMQ服务器, 默认是不知道的。而且有的时候我们在发送消息之后,后面的逻辑出问题了,我们不想要发送之前的消息了,需要撤回该怎么做。  

解决方案:  

1.AMQP 事务机制  

2.Confirm 模式

事务模式:  

txSelect  将当前channel设置为transaction模式  

txCommit  提交当前事务  

txRollback  事务回滚

 

生产者代码:

package com.rabbitmqdemo.Producer;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmqdemo.Utils.MQConnectionUtils;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class AMQPProducer {
    // 队列名称
    private static final String QUEUE_NAME = "AMQPtest";

    public static void main(String[] args) throws IOException, TimeoutException {
        // 1.创建一个新的连接
        Connection connection = MQConnectionUtils.newConnection();
        // 2.创建通道
        Channel channel = connection.createChannel();
        // 3.创建一个队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        channel.basicQos(1);// 保证一次只分发一次 限制发送给同一个消费者 不得超过一条消息
        try{
            channel.txSelect();
            String msg = "博主长得非常帅,比金城武还帅!";
            // 5.生产者发送消息者
            channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
            int i=1/0;
            channel.txCommit();
        }
        catch (Exception e){
            System.out.println("生产者出现异常,回滚!");
            channel.txRollback();
        }
        finally {
            // 关闭通道和连接
            channel.close();
            connection.close();
        }
    }
}

 

消费者代码:

package com.rabbitmqdemo.consumer;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import javax.swing.DefaultBoundedRangeModel;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmqdemo.Utils.MQConnectionUtils;

public class Consumer {
    // 队列名称
    private static final String QUEUE_NAME = "AMQPtest";

    public static void main(String[] args) throws IOException, TimeoutException {
        System.out.println("消费者启动....01");
        // 1.创建一个新的连接
        Connection connection = MQConnectionUtils.newConnection();
        // 2.创建通道
        final Channel channel = connection.createChannel();
        // 3.消费者关联队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        channel.basicQos(1);
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {

            // 监听获取消息
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body)
                    throws IOException {
                String msg = new String(body, "UTF-8");
                System.out.println("消费者获取生产者消息:" + msg);
                try {
                    Thread.sleep(1000);
                } catch (Exception e) {

                } finally {
                    // 手动回执消息
                    channel.basicAck(envelope.getDeliveryTag(), false);
                }
            }

        };
        // 4.设置应答模式 如果为true情况下 表示为自动应答模式 false 表示为手动应答
        channel.basicConsume(QUEUE_NAME, false, defaultConsumer);
        // 关闭通道和连接
//        channel.close();
//        connection.close();
    }
}

 

生产者运行结果:

遇到错误,生产者回滚之前之外的执行。

【java】RabbitMQ-RabbitMQ消息确认机制_第1张图片

 

消费者运行结果:

由于生产者出现错误,进行了回滚,可见消费者没有消息。

 

 

 

你可能感兴趣的:(java,RabbitMQ)