RabbitMQ 发布确认模式

ops/2024/10/20 8:45:43/

RabbitMQ 发布确认模式


一、原理

RabbitMQ 的发布确认模式(Publisher Confirms)是一种机制,用于确保消息在被 RabbitMQ 服务器成功接收后,发布者能够获得确认。这一机制在高可用性和可靠性场景下尤为重要,能够有效防止消息丢失。

在发布消息时,RabbitMQ 会向发布者返回确认信号,指示该消息已成功处理。这一过程可以大大提高消息传递的可靠性,尤其是在系统出现故障时。通过实现发布确认模式,发布者可以确保所有发送的消息都已被服务器接收并存储,从而维护数据一致性。

二、三种方式比较

1. 单个确认

单个确认模式是指每发送一条消息,发布者都会等待 RabbitMQ 发送确认信号。这种方式简单易懂,但在高负载场景下,性能表现可能较差,因为每条消息都需要等待确认,造成延迟。

优点:

  • 实现简单,易于理解和使用。
  • 适合消息量较小的场景。

缺点:

  • 性能较低,确认过程中的延迟会影响整体吞吐量。
public static void publishMessageIndividually() throws Exception {Channel channel = RabbitMqUtils.getChannel();String queue_name = UUID.randomUUID().toString();channel.queueDeclare(queue_name,false,false,false,null);//开始时间long begin = System.currentTimeMillis();channel.confirmSelect();for (int i = 0; i < message_count; i++) {String message = i+"";channel.basicPublish("",queue_name,null,message.getBytes());//单个消息马上确认boolean flag = channel.waitForConfirms();if(flag == true){System.out.println("消息发送成功");}}//结束时间long end = System.currentTimeMillis();System.out.println("发布"+message_count+"条用时:"+(end - begin)+"mills");}

2. 批量确认

批量确认模式允许发布者在发送多条消息后,一次性等待 RabbitMQ 的确认信号。通过将多条消息组合在一起进行确认,可以显著提高消息发布的效率。

优点:

  • 显著提高吞吐量,减少网络延迟。
  • 适合需要高性能的场景。

缺点:

  • 需要管理确认逻辑,稍微复杂。

  • 一旦发生错误,可能需要重新发送整个批次的消息。

//批量发布确认public static void publishMessageBatch() throws Exception {Channel channel = RabbitMqUtils.getChannel();String queue_name = UUID.randomUUID().toString();channel.queueDeclare(queue_name,false,false,false,null);channel.confirmSelect();//开始时间long begin = System.currentTimeMillis();//批量确认的长度int basicSize = 100;for (int i = 1; i <= message_count; i++) {String message = i+"";channel.basicPublish("",queue_name,null,message.getBytes());if(i%basicSize == 0){System.out.println("消息发送成功");channel.confirmSelect();}}//结束时间long end = System.currentTimeMillis();System.out.println("批量发布"+message_count+"条用时:"+(end - begin)+"mills");}

3. 异步批量确认

异步批量确认模式更进一步,发布者在发送批量消息后,不必等待 RabbitMQ 的确认信号,而是可以继续发送更多消息。RabbitMQ 在后台处理确认,这样可以进一步提高效率。

优点:

  • 最高的性能和吞吐量,几乎没有延迟。
  • 发布者可以充分利用 CPU 和网络资源。

缺点:

  • 实现复杂度增加,需要处理可能出现的消息丢失。
  • 需要额外的逻辑来确保消息的可靠性。
//异步发布确认public static void publishMessageAsync() throws Exception {Channel channel = RabbitMqUtils.getChannel();String queue_name = UUID.randomUUID().toString();channel.queueDeclare(queue_name,false,false,false,null);//开启发布确认channel.confirmSelect();/*** 线程安全有序的哈希表 适用于高并发* 1、将序号和消息关联* 2、轻松删除条目,主要给到序号* 3、支持高并发*/ConcurrentSkipListMap<Long, String> outstandingConfirms = new ConcurrentSkipListMap<>();//开始时间long begin = System.currentTimeMillis();//消息确认成功的回调ConfirmCallback ackCallBack = (deliveryTag, multiple)->{//2:删除确认的消息if(multiple){ConcurrentNavigableMap<Long,String> confirmed =outstandingConfirms.headMap(deliveryTag);confirmed.clear();}else {outstandingConfirms.remove(deliveryTag);}System.out.println("确认消息:"+deliveryTag);};/*** 1、消息类型* 2、是否批量*/ConfirmCallback NackCallBack = (deliveryTag, multiple)->{//3:打印未确认的String message = outstandingConfirms.get(deliveryTag);System.out.println("发布的消息"+message+"未被确认,序列号"+deliveryTag);};//准备消息的监听器//1.监听成功的//2.监听失败的channel.addConfirmListener(ackCallBack,NackCallBack);for (int i = 1; i <= message_count; i++) {String message = i+"";channel.basicPublish("",queue_name,null,message.getBytes());//1:此处记录所有要发送的消息outstandingConfirms.put(channel.getNextPublishSeqNo(),message);}//结束时间long end = System.currentTimeMillis();System.out.println("批量发布"+message_count+"条用时:"+(end - begin)+"mills");}

三、速度对比

三种时间对比:

image-20241019194007060

image-20241019194035423

image-20241019194101582

在速度和吞吐量方面,三种模式各有优势。一般来说,单个确认模式的速度最慢,而异步批量确认模式则能提供最佳性能。在实际应用中,选择合适的确认模式应根据业务需求、消息量以及系统的可承受负载来综合考虑。

发布确认模式为 RabbitMQ 提供了灵活的消息发布保障机制。根据具体需求选择合适的确认方式,将有助于实现高效、可靠的消息传递系统。


http://www.ppmy.cn/ops/126933.html

相关文章

南昌近视手术医生排名更新,速速围观!

在南昌&#xff0c;哪些医生做近视手术好呢&#xff1f;小编已经为大家整理出来啦&#xff01;下文的这些医生均是小编根据多年的从业经验、口碑评价&#xff0c;筛选和整理出来的TOP级医生们&#xff01;南昌近视手术医生排名已更新&#xff0c;赶紧来看看都有谁吧&#xff01…

Python项目Docker服务器部署

Python项目Docker服务器部署 Python项目Docker服务器部署准备工作部署其他问题 Python项目Docker服务器部署 准备工作 1.准备基础镜像 # 指定拉取arm架构镜像 docker pull --platform linux/arm64 python:3.11 # 指定拉取amd架构镜像 docker pull --platform linux/amd64 py…

联系拯救者Y9000P2022笔记本电脑进入BIOS快捷键

联系拯救者Y9000P2022笔记本电脑进入BIOS快捷键 文章目录 联系拯救者Y9000P2022笔记本电脑进入BIOS快捷键1. 进入BIOS快捷键2. 快速进入BIOS设置界面3. 快速进入启动项选择界面 1. 进入BIOS快捷键 进入BIOS设置界面的快捷键为F2快速进入启动项选择界面的快捷键为F12 2. 快速进…

【数据分享】全国科技-高技术产业新产品开发情况(2011-2021年)

数据介绍 一级标题指标名称单位科技高技术产业新产品开发项目数个科技医药制造业高技术产业新产品开发项目数个科技化学药品制造高技术产业新产品开发项目数个科技中成药制造高技术产业新产品开发项目数个科技生物、生化制品的制造高技术产业新产品开发项目数个科技航空航天器…

Java基于SSM微信小程序物流仓库管理系统设计与实现(源码+lw+数据库+讲解等)

选题背景 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和mysql数据库来完成对系统的设计。整个…

沈阳乐晟睿浩科技有限公司抖音小店新篇章

在数字经济浪潮席卷全球的今天&#xff0c;电子商务行业迎来了前所未有的发展机遇。尤其是以抖音为代表的短视频直播平台&#xff0c;更是开辟了电商营销的新蓝海。在这场变革中&#xff0c;沈阳乐晟睿浩科技有限公司凭借其敏锐的市场洞察力、强大的技术实力和深厚的行业积累&a…

使用 Docker 升级 MySQL 的优化步骤与说明

在升级 MySQL 之前&#xff0c;进行系统化的准备和实施能够显著降低数据丢失的风险&#xff0c;并确保顺利过渡。以下是优化后的详细步骤及分析。 一、备份原数据库所有数据 重要性分析 在任何数据库操作中&#xff0c;备份都是最重要的一步。确保备份包含所有数据库、表及其…

在 Python 语言中,元组(tuple)、字符串(str)、列表(list)和集合(set)是常见的数据结构,它们有以下区别:

在 Python 语言中&#xff0c;元组&#xff08;tuple&#xff09;、字符串&#xff08;str&#xff09;、列表&#xff08;list&#xff09;和集合&#xff08;set&#xff09;是常见的数据结构&#xff0c;它们有以下区别&#xff1a; 1. 定义与表示 元组 定义&#xff1a;元组…