介绍
同步:提交消息后,等待服务端回复后才算确认,概括的简单吧。
异步:使用监听方法,异步等待消息回调。
控制方式
开启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();
}
}