rabbitmq消息确认机制-confirm模式

介绍

同步:提交消息后,等待服务端回复后才算确认,概括的简单吧。

异步:使用监听方法,异步等待消息回调。

控制方式

开启confirm模式代码 : channel.confirmSelect();

同步确认,等待结果方法: channel.waitForConfirms() true-发送成功,false-发送失败

异步确认,直接添加一个监听,也能叫做监听模式:
channel.addConfirmListener(new ConfirmListener() {//实现返回处理方法... });

confirm 同步单条模式

提交一条后,直接调用等待回复方法

发送代码如下:

package com.yzcq.rabbitmq.confirm;

import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.MessageProperties; import com.yzcq.rabbitmq.util.ConnectionUtil; import java.io.IOException; import java.util.concurrent.TimeoutException;

/** 生产者-comfirm模式单条发送 **/

public class SendOne { private static final String QUEUE_NAME = "test-confirm_queue";

public static void main(String[] args) throws IOException, TimeoutException {
    //获取连接
    Connection connection = ConnectionUtil.getConnection();
    //创建通道
    Channel channel = connection.createChannel();

    //声明一个持久化的 队列
    channel.queueDeclare(QUEUE_NAME, false, false, false, null);
    //开启confirm模式
    channel.confirmSelect();

    String msg = "我是confirm模式消息";
    channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, msg.getBytes());
    try {
        //          等待回复,如果回复true
        if (channel.waitForConfirms()) {
            System.out.println("发送成功");
        }
        else {
            System.out.println("发送失败");
        }
    }
    catch (InterruptedException e) {
        e.printStackTrace();
        System.out.println("发送失败");
    }
    channel.close();
    connection.close();

}

}

confirm 同步多条条模式

整批处理,成功、失败、回退都是整批的

提交多条后,调用等待回复方法

package com.yzcq.rabbitmq.confirm;

import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.MessageProperties; import com.yzcq.rabbitmq.util.ConnectionUtil; import java.io.IOException; import java.util.concurrent.TimeoutException;

/生产者-comfirm模式单条发送/

public class SendMore {

private static final String QUEUE_NAME = "SendMore-confirm_queue";

public static void main(String[] args) throws IOException, TimeoutException {

    //获取连接
    Connection connection = ConnectionUtil.getConnection();
    
    //创建通道
    Channel channel = connection.createChannel();
    //声明一个持久化的 队列
    channel.queueDeclare(QUEUE_NAME, false, false, false, null);
    //开启confirm模式
    channel.confirmSelect();
    String msg = "我是confirm模式 消息 批量发送";
    //多条一起发送
    for (int i = 0; i < 5; i++) {
        channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, msg.getBytes());
    }
    try {

        //等待回复,如果回复true
        if (channel.waitForConfirms()) {
            System.out.println("发送成功");
        }
        else {
            System.out.println("发送失败");
        }
    }
    catch (InterruptedException e) {
        e.printStackTrace();
        System.out.println("发送失败");
    }
    channel.close();
    connection.close();
}

}

confirm 异步

package com.yzcq.rabbitmq.confirm;

import com.rabbitmq.client.Channel; import com.rabbitmq.client.ConfirmListener; import com.rabbitmq.client.Connection; import com.rabbitmq.client.MessageProperties; import com.yzcq.rabbitmq.util.ConnectionUtil; import java.io.IOException; import java.util.Collections; import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.TimeoutException;

/** 生产者-comfirm模式异步*/

public class SendAsync {

private static final String QUEUE_NAME = "SendAsync-confirm_queue";

public static void main(String[] args) throws IOException, TimeoutException {
    //获取连接
    Connection connection = ConnectionUtil.getConnection();
    //创建通道
    Channel channel = connection.createChannel();
    //声明一个持久化的 队列
    channel.queueDeclare(QUEUE_NAME, false, false, false, null);
    //开启confirm模式
    channel.confirmSelect();

    //存储未确认的消息标识tag
    final SortedSet<Long> confirmSet = Collections.synchronizedNavigableSet(new TreeSet<Long>());

    //开启监听
    channel.addConfirmListener(new ConfirmListener() {
        /**
         * 处理返回确认成功
         * @param deliveryTag 如果是多条,这个就是最后一条消息的tag
         * @param multiple 是否多条
         * @throws IOException
         */
        @Override
        public void handleAck(long deliveryTag, boolean multiple) throws IOException {

            System.out.println("消息发送成功,deliveryTag:" + deliveryTag + "multiple:" + multiple + "");
            if (multiple) {
                confirmSet.headSet(deliveryTag + 1).clear();
            }
            else {
                confirmSet.remove(deliveryTag);
            }
        }

        /**
         * 处理返回确认失败
         * @param deliveryTag
         * @param multiple
         * @throws IOException
         */
        @Override
        public void handleNack(long deliveryTag, boolean multiple) throws IOException {
            System.out.println("失败,deliveryTag:" + deliveryTag + "multiple:" + multiple + "");
            if (multiple) {

                confirmSet.headSet(deliveryTag + 1).clear();
            }
            else {
                confirmSet.remove(deliveryTag);
            }
        }
    });

    for (int i = 0; 1 < 2; i++) {
        String msg = "我是confirm模式 消息 异步【" + i + "】";
        long tag = channel.getNextPublishSeqNo();
        //发送消息
        channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, msg.getBytes());
        System.out.println("tag:" + tag);
        confirmSet.add(tag);
    }
    //上面是无限循环所以这个应该放到finally里
    //        channel.close();
    //        connection.close();
}

}

展开阅读全文

没有更多推荐了,返回首页