/**
* @ClassName ConfirmMessage
* @Description:发布确认模式:
* 1.单个确认模式 使用的时间比较那种确认方式是最好的
* 2.批量确认模式
* 3.异步批量确认
* @Author tunan
* @Date 2022/07/13/13:47
*/
public class ConfirmMessage {
//批量发消息的个数
public static final int MESSAGE_COUNT = 1000;
public static void main(String[] args) throws Exception {
// 1.单个确认
/**
* 简单,吞吐量有限
*/
// ConfirmMessage.publishMessageIndividually();//发布1000个单独确认消息,耗时796ms
// 2.批量确认模式
/**
* 简单,合理的吞吐量,一旦出现问题很难推断出是那条消息出现问题
*/
// ConfirmMessage.publishMessageBatch();//发布1000个批量确认消息,耗时98ms
// 3.批量
/**
* 最佳性能和资源使用,在出现错误的情况下可以很好地控制,但是实现起来困难
*/
ConfirmMessage.publishMessageAsync();//发布1000个异步发布确认消息,耗时39ms
}
public static void publishMessageIndividually() throws Exception {
Channel channel = RabbitMqUtils.getChannel();
String queueName = UUID.randomUUID().toString();
channel.queueDeclare(queueName,true,false,false,null);
// 开启发布确认
channel.confirmSelect();
// 开始时间
long begin = System.currentTimeMillis();
for (int i = 0; i < MESSAGE_COUNT; i++) {
String message = i+"";
channel.basicPublish("",queueName,null,message.getBytes());
// 单个消息就马上进行发布确认
boolean flag = channel.waitForConfirms();
if (flag) {
System.out.println("消息发送成功");
}
}
long end = System.currentTimeMillis();
System.out.println("发布"+MESSAGE_COUNT+"个单独确认消息,耗时"+(end-begin)+"ms");
}
// 批量发布确认
public static void publishMessageBatch() throws Exception {
Channel channel = RabbitMqUtils.getChannel();
String queueName = UUID.randomUUID().toString();
channel.queueDeclare(queueName,true,false,false,null);
// 开启发布确认
channel.confirmSelect();
// 开始时间
long begin = System.currentTimeMillis();
//批量确认消息大小
int batchSize = 100;
for (int i = 0; i < MESSAGE_COUNT; i++) {
String message = i+"";
channel.basicPublish("",queueName,null,message.getBytes());
if (i % batchSize == 0) {
channel.waitForConfirms();
}
}
long end = System.currentTimeMillis();
System.out.println("发布"+MESSAGE_COUNT+"个批量确认消息,耗时"+(end-begin)+"ms");
}
// 异步发布确认
public static void publishMessageAsync() throws Exception {
Channel channel = RabbitMqUtils.getChannel();
String queueName = UUID.randomUUID().toString();
channel.queueDeclare(queueName,true,false,false,null);
// 开启发布确认
channel.confirmSelect();
/**
* 线程安全有序的一个哈希表,适用于高并发的情况下
*1.轻松的将序号与消息进行关联
*2.轻松批量删除条目 只要给到序号
*3.支持高并发(多线程)
*/
ConcurrentSkipListMap<Long,String> outstandingConfirms = new ConcurrentSkipListMap<>();
//准备消息的监听器,监听那些消息成功了,那些消息失败了
//消息确认成功,回调函数
ConfirmCallback ackCallback = (long deliveryTag, boolean multiple)->{
if (multiple) {
//2.删除掉已经确认的消息,剩下的就是未确认的消息
ConcurrentNavigableMap<Long, String> confirmed = outstandingConfirms.headMap(deliveryTag);
}else {
outstandingConfirms.remove(deliveryTag);
}
System.out.println("确认的消息"+deliveryTag);
};
//消息确认失败 回调函数
/**
* 1.消息的标记
* 2.是否为批量
*/
ConfirmCallback nackCallback = (long deliveryTag, boolean multiple)->{
//3.打印下未确认的消息有哪些
String message = outstandingConfirms.get(deliveryTag);
System.out.println("未确认的消息"+message+"..............为确认消息的tag"+deliveryTag);
};
/**
* 1.成功
* 2.失败
*/
channel.addConfirmListener(ackCallback,nackCallback);//异步通知
// 开始时间
long begin = 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-begin)+"ms");
}
}
RabbitMQ发布确认模式
最新推荐文章于 2023-02-28 08:32:05 发布