生产者可以大量发消息,消息的确认异步处理。最佳性能和资源使用,在出现错误的情况下可以很好地控制,但是实现起来稍微难些
引入maven依赖
<dependencies>
<!--rabbitmq 依赖客户端-->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.8.0</version>
</dependency>
<!--操作文件流的一个依赖-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
//异步确认
public static void publishAsync() throws Exception {
Channel channel = RabbitMqUtils.getChannel();
//开启确认发布
channel.confirmSelect();
String queuename = UUID.randomUUID().toString();
//声明队列
channel.queueDeclare(queuename, false, false, false, null);
// 线程:适用于高并发的情况下,处理未确认的消息
// 轻松将序号与消息进行关联
// 轻松删除批量条目,只要给到序号
ConcurrentSkipListMap<Long, String> outstandingConfirms = new ConcurrentSkipListMap<>();
ConfirmCallback ackCallback = (deliveryTag, multiple) -> {
// 2.删除已经确认的消息,剩下的就是未确认的消息
if (multiple) {
ConcurrentNavigableMap<Long, String> confirmed = outstandingConfirms.headMap(deliveryTag);
confirmed.clear();
} else {
outstandingConfirms.remove(deliveryTag);
}
System.out.println("确认的消息" + deliveryTag);
};
ConfirmCallback nackCallback = (deliveryTag, multiple) -> {
// 打印未确认的消息
String message = outstandingConfirms.get(deliveryTag);
System.out.println("未确认的消息是" + message + "---》未确认消息的编号" + deliveryTag);
};
//设置异步确认监听器
channel.addConfirmListener(ackCallback, nackCallback);
// 开始时间
long l = System.currentTimeMillis();
for (int i = 0; i < MESSAGE_COUNT; i++) {
String message = i + "";
channel.basicPublish("", queuename, null, message.getBytes());
// 1. 记录一下消息的发布总量
outstandingConfirms.put(channel.getNextPublishSeqNo(), message);
}
long end = System.currentTimeMillis();
System.out.println("批量确认" + MESSAGE_COUNT + "条耗时" + (end - l) + "ms");
}