一 Confirm模式
生产者将信道设置成confirm模式,一旦信道进入confirm模式,所有在该信道上面发布的消息都会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列之后,broker就会发送一个确认给生产者(包含消息的唯一ID),这就使得生产者知道消息已经正确到达目的队列了,如果消息和队列是可持久化的,那么确认消息会将消息写入磁盘之后发出,broker回传给生产者的确认消息中deliver-tag域包含了确认消息的序列号,此外broker也可以设置basic.ack的multiple域,表示到这个序列号之前的所有消息都已经得到了处理。
confirm模式最大的好处在于他是异步的,一旦发布一条消息,生产者应用程序就可以在等信道返回确认的同时继续发送下一条消息,当消息最终得到确认之后,生产者应用便可以通过回调方法来处理该确认消息,如果RabbitMQ因为自身内部错误导致消息丢失,就会发送一条nack消息,生产者应用程序同样可以在回调方法中处理该nack消息。
在channel 被设置成 confirm 模式之后,所有被 publish 的后续消息都将被 confirm(即 ack) 或者被nack一次。但是没有对消息被 confirm 的快慢做任何保证,并且同一条消息不会既被 confirm又被nack 。
二 编程模式
客户端实现生产者confirm有三种编程方式:
1 普通confirm模式:每发送一条消息后,调用waitForConfirms()方法,等待服务器端confirm。实际上是一种串行confirm了。
2 批量confirm模式:每发送一批消息后,调用waitForConfirms()方法,等待服务器端confirm。
3 异步confirm模式:提供一个回调方法,服务端confirm了一条或者多条消息后Client端会回调这个方法。
三 生产端代码
1 普通confirm模式
/**
* Copyright (C), 2020-2020, 软件公司
* FileName: ConfirmSend
* Author: cakin
* Date: 2020/4/25
* Description: 生产者:普通confirm模式
*/
package com.rabbitmq.productconfirm;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.util.ConnectionUtils;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* @ClassName: ConfirmSend
* @Description: 生产者:普通confirm模式
* @Date: 2020/4/25
* @Author: cakin
*/
@Slf4j
public class ConfirmSend {
/**
* 队列名称
*/
private static final String QUEUE_NAME = "test_queue_confirm1";
public static void main( String[] args ) throws IOException, TimeoutException, InterruptedException {
// 获取连接
Connection connection = ConnectionUtils.getConnection();
// 从连接开一个通道
Channel channel = connection.createChannel();
// 声明一个队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
channel.confirmSelect(); // 开始confirm模式
// 发送消息
String message = "hello, confirm message";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
if (channel.waitForConfirms()) {
log.info(" [x] Sent message : '" + message + "' ok ");
} else {
log.info(" [x] Sent message : '" + message + "' fail ");
}
channel.close();
connection.close();
}
}
2 批量confirm模式
/**
* Copyright (C), 2020-2020, 软件公司
* FileName: ConfirmSend2
* Author