RabbitMQ入门_12_发布方确认

参考资料:https://www.rabbitmq.com/confirms.html

通过 ack 机制,我们可以确保队列中的消息一定能被消费到。那我们有办法保证消息发布方一定把消息发送到队列了吗?

遵照 AMQP 协议,RabbitMQ 提供了事务机制可以确保发布方消息必达。但是吞吐量会降为越来的 1/250,这个性能损耗是无法接受的。

好在 RabbitMQ 提供了类似于消费方 ack 的机制,用于确保发布方消息必达。

gordon.study.rabbitmq.features.TestPublisherConfirm.java

public class TestPublisherConfirm {
 
    private static final String QUEUE_NAME = "publisherConfirm";
 
    public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        Connection connection = factory.newConnection();
        Channel senderChannel = connection.createChannel();
 
        senderChannel.queueDeclare(QUEUE_NAME, false, false, true, null);
        senderChannel.confirmSelect();
        senderChannel.addConfirmListener(new ConfirmListener() {
 
            @Override
            public void handleNack(long deliveryTag, boolean multiple) throws IOException {
                System.out.printf("nack: %s %s\n", deliveryTag, multiple);
            }
 
            @Override
            public void handleAck(long deliveryTag, boolean multiple) throws IOException {
                System.out.printf("ack: %s %s\n", deliveryTag, multiple);
            }
        });
 
        for (int i = 0; i < 10;) {
            String message = "NO. " + ++i;
            senderChannel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));
        }
        boolean isConfirm = senderChannel.waitForConfirms();
        System.out.println("isConfirm: " + isConfirm);
        connection.close();
    }
}

代码第12行 confirmSelect 方法将当前信道设置为确认模式,该信道就启动了发布者确认特性。此时,RabbitMQ 会在消息被所有目标队列接收后,向发布者发送 ack,通知发布者消息已成功送达队列。如果中间出现异常,RabbitMQ 会发送 nack 通知发布者,发布者即可选择重新发送消息。

第30行 waitForConfirms 方法会阻塞住,直到两次 waitForConfirms 方法之间发送的所有消息都由 RabbitMQ 返回 ack 或 nack 通知。

除了官方文档中提到的 waitForConfirms 方法,还可以通过 ConfirmListener 来实现更高效的确认(无阻塞)。代码第13行开始创建了一个 ConfirmListener 并注册到信道中,之后, RabbitMQ 发回的 ack / nack 消息会触发相应的 handle 回调函数。

posted @ 2017-06-10 17:05  首夜盲毒预言家  阅读(653)  评论(1编辑  收藏  举报