Rabbit MQ知识总结
1.什么是Rabbit MQ?
Rabbit MQ是一个开源的消息代理软件,它实现了高级消息队列协议(AMQP);
基本概念
- 消息:消息是在应用程序之间传递的数据单元。可以是简单的文本信息,可以是复杂的对象。
- 队列:队列是消息的容器,用于存储消息。他就像一个等待处理的任务列表,消息以先进先出的方式在队列中被处理。
- 生产者消费者:生产者是创建和发送消息的应用程序或组件。消费者则是接收和处理消息的应用程序。
功能特点
- 可靠性高:Rabbit MQ使用持久化机制来确保消息不会丢失。消息可以被标记为持久化,这样Rabbit MQ服务器重启后,消息仍然可以被恢复。
- 灵活的消息分发策略:它支持多种消息分发模式。比如轮询模式,多个消费者可以轮流从队列种获取消息,确保每个消费者都能公平的处理消息;还有直接分发模式,根据消息特定的路由键(routing key)将消息发送到指定的队列,被对应的消费者处理。
- 支持多种协议:除了AMQP,Rabbit MQ还支持其他消息协议,比如STOMP,MQTT。使得它能够与多种不同类型的客户端和应用程序集成。
- 集群和高扩展性:Rabbit MQ可以构建集群来提供高可用和横向扩展性.通过在多个节点上部署Rabbit MQ,可以实现故障转移。比如一个节点出现故障,其他节点可以接管其工作,确保消息系统的持续运行。
应用场景
- 异步处理:在一些耗时的操作中,比如文件上传后的数据处理等,可以将任务消息发送到Rabbit MQ队列。消费者可以在后台异步处理这些任务,而不会影响用户其他操作,提高系统的响应速度。例如:用户在一个社交平台上传了一张照片,系统将照片转码任务放入 RabbitMQ 队列,用户可以继续浏览其他内容,同时转码任务在后台慢慢处理。
- 流量削峰:在高流量场景下,比如电商系统促销期间,订单量可能会突然暴增。通过将订单消息放入Rabbit MQ队列,后端系统可以按照自己的处理能力从队列种获取消息进行处理,避免后端系统被大量请求压垮。
- 解耦系统组件:当一个大型系统包含多个相互关联的子系统时,RabbitMQ 可以用于解耦这些子系统。例如,在电商系统中,订单系统、库存系统、支付系统等之间通过消息队列进行通信。订单系统产生订单消息后发送到队列,库存系统和支付系统作为消费者从队列中获取消息并进行相应的处理。这样,各个子系统之间不需要直接相互调用,降低了系统的耦合度,便于系统的维护和扩展。
2.RabbitMQ的七种工作模式
RabbitMQ的七种工作模式
3.如何保证RabbitMQ的消息顺序性?
-
单队列单消费者模式
- 原理:将需要保证顺序的消息发送到同一个队列中,并且让这个队列只有一个消费者进行消费。这样消息按照进入队列的顺序被消费者获取,自然就保证了消息的顺序性。
- 示例:假设有一个订单处理系统,订单的创建、支付、发货等消息是有严格顺序要求的。可以将这些和同一个订单相关的消息发送到名为 “订单队列” 的队列中,并且只启动一个消费者来处理这个队列中的消息。
- 缺点:这种方式的性能和可用性相对较低,因为单个消费者可能会成为性能瓶颈,而且如果消费者出现故障,消息处理就会中断。
-
拆分多个队列并保证顺序消费
- 原理:根据业务规则,将消息划分到不同的队列中,每个队列中的消息都有顺序要求,并且在每个队列上只配置一个消费者来保证顺序。
- 示例:在一个电商系统中,对于不同类型的商品(如电子产品、服装、食品)的订单消息,可以分别发送到 “电子产品队列;衣服队列;食物队列” 等不同的队列中。每个队列都有自己单独的消费者,这样就可以在不同的商品类型内部保证订单消息的顺序。
- 局限性:需要对业务有很好的理解,合理地划分队列,并且当业务规则发生变化时,可能需要重新调整队列的划分。
-
消息分组和局部顺序性保证
- 原理:在消息中添加分组标识,消费者根据分组标识来处理消息,保证同一组内的消息顺序。在 RabbitMQ 中,可以通过消息的属性或者消息体中的自定义字段来添加分组标识。
- 示例:假设有一个消息包含用户的操作记录,如登录、浏览商品、添加购物车等。可以在消息体中添加一个用户 ID 作为分组标识。消费者接收到消息后,先按照用户 ID 对消息进行分组,然后在每个用户组内按照消息的顺序进行处理,这样就可以保证每个用户的操作记录是按照顺序处理的。
- 注意点:消费者需要有额外的逻辑来进行分组和顺序控制,增加了消费者的复杂性。同时,在高并发情况下,需要注意分组消息的存储和排序效率。
-
使用事务和消息确认机制结合
- 原理:在生产者端,使用事务来确保消息按照顺序发送到队列。在消费者端,结合消息确认机制,只有当一条消息处理完成并且符合顺序要求后,才确认该消息,然后再处理下一条消息。
- 示例:在生产者发送消息时,开启一个事务,将多条有顺序要求的消息依次发送到队列中。如果发送过程中出现问题,事务可以回滚,保证消息不会乱序发送。消费者在接收到消息后,只有在正确处理完当前消息并且下一条消息符合顺序要求时,才发送消息确认,这样可以防止消息的无序消费。
- 缺点:使用事务会增加系统的开销,影响性能,并且需要仔细处理事务的边界和异常情况。
-
通过消息优先级辅助保证顺序性(在一定程度上)
- 原理:RabbitMQ 支持消息优先级。如果消息有顺序要求,可以为消息设置优先级,按照优先级顺序发送和消费消息。不过这种方法不能完全保证顺序性,只是在一定程度上辅助保证顺序。
- 示例:在一个新闻发布系统中,对于重要新闻的更新消息(如头条新闻)可以设置较高的优先级,其他普通新闻更新消息设置较低的优先级。在消费者端,优先处理高优先级的消息,并且在优先级相同的消息之间,按照发送顺序进行处理,这样可以在一定程度上保证重要新闻更新的顺序性。
4.如何保证消息消费时的幂等性(消息不被重复消费)?
-
什么是消息的幂等性
- 幂等性是指对同一个操作的一次请求和多次重复请求对系统资源的影响是一致的。在消息消费场景中,就是指无论消息被消费多少次,对系统产生的最终效果和只消费一次是相同的。
-
利用数据库的唯一约束保证幂等性
- 原理:当消息被消费时,需要将消息的关键信息(如消息 ID、业务唯一标识等)插入到数据库中。如果数据库表中该字段设置了唯一约束,那么当重复消息消费导致插入相同的标识时,数据库会抛出异常,通过捕获这个异常就可以避免重复消费。
- 示例:在一个用户注册系统中,当接收到用户注册的消息时,将用户的手机号码作为唯一标识插入到 “user_registration” 表中。如果消息重复消费,第二次插入相同手机号码时会违反唯一约束,此时就可以识别出这是重复消息,不再进行实际的注册操作。
- 注意点:这种方法可能会影响数据库性能,因为每次消息消费都涉及数据库操作。同时,需要合理设计数据库表结构和唯一约束字段,确保能够准确识别重复消息。
-
使用状态机实现幂等性
- 原理:为业务流程设计一个状态机,每个消息的消费会使业务状态发生变化。在消费消息时,先检查当前业务状态是否符合消息消费的预期状态,如果不符合则说明消息可能已经被消费过,不再进行处理。
- 示例:在一个订单处理系统中,订单有 “已创建”“已支付”“已发货”“已完成” 等状态。当消费支付消息时,先检查订单状态是否为 “已创建”,如果是,则进行支付处理并将订单状态更新为 “已支付”;如果订单状态不是 “已创建”,则说明支付消息可能已经被处理过,不再进行重复支付操作。
- 局限性:需要准确地设计和维护状态机,状态转换规则复杂时可能会出现错误。并且当业务状态被其他因素(如人工干预)修改时,可能会影响状态机的正常判断。
-
基于消息的唯一标识进行去重
- 原理:消息本身通常有一个唯一的消息 ID,或者可以在消息体中添加自定义的唯一标识。在消息消费者端,维护一个已消费消息 ID 的集合(可以是内存中的集合、缓存或者数据库存储),当接收到消息时,先检查消息 ID 是否在已消费集合中,如果在则忽略该消息,不在则进行消费并将消息 ID 添加到集合中。
- 示例:使用 Redis 的 Set 数据结构来存储已消费的消息 ID。在消息消费者中,每次接收到消息时,使用 Redis 的 SISMEMBER 命令检查消息 ID 是否在集合中。如果不在,进行消息消费并使用 SADD 命令将消息 ID 添加到集合中。
- 注意点:需要考虑存储已消费消息 ID 的存储介质的性能和可靠性。如果使用内存存储,当消费者重启时可能会丢失数据;如果使用数据库存储,会增加数据库的读写操作。同时,对于高并发的场景,需要注意存储和查询操作的效率。
-
通过消息确认机制实现幂等性(结合消息中间件特性)
- 原理:在消息中间件(如 RabbitMQ)中,消息消费成功后需要向中间件发送确认消息。如果消息没有被正确确认,中间件可能会重新发送消息。在消费者端,可以通过记录消息的消费状态和确认状态来避免重复消费。
- 示例:在消费者内部维护一个消息消费状态表,记录消息 ID、消费状态(未消费、已消费未确认、已确认)等信息。当接收到消息时,先检查消费状态,如果是 “已确认” 则忽略该消息;如果是 “未消费” 则进行消费并将状态更新为 “已消费未确认”,在成功消费后发送确认消息给中间件,并将状态更新为 “已确认”。
- 复杂性:这种方法需要消费者自己维护消息消费状态,增加了消费者的复杂性。并且需要确保消息确认机制和消费状态更新的原子性,避免出现不一致的情况。
5.如何保证RabbitMQ消息的可靠传输?
- 生产者可靠发送
- 使用发送方确认模式(publisher confirm)
- 原理:发送方确认模式是一种更高效的方式来确保消息发送的可靠性。当生产者开启这个模式后,每发送一条消息,RabbitMQ 服务器会返回一个确认(ack)消息给生产者。如果生产者没有收到确认消息,就可以认为消息发送失败,从而进行重试或其他错误处理。
- 注意点:虽然发送方确认模式比事务机制性能更好,但在高并发场景下,生产者需要合理处理确认消息,避免因为等待确认而导致性能瓶颈。
- 开启事务机制
- 原理:在 RabbitMQ 中,生产者可以使用事务来确保消息的可靠发送。开启事务后,生产者发送消息的操作会被包含在一个事务块中。如果消息成功发送到队列,事务就可以提交;如果发送过程中出现任何问题,如网络故障、队列不存在等,事务可以回滚,保证消息不会丢失。
- 缺点:事务机制会带来较大的性能开销,因为它涉及到与 RabbitMQ 服务器的多次交互,包括开启事务、提交或回滚事务等操作。
- 使用发送方确认模式(publisher confirm)
2.消息持久化
- 队列持久化
- 原理:在 RabbitMQ 中,可以将队列设置为持久化。持久化的队列会在 RabbitMQ 服务器重启后依然存在,确保消息不会因为队列的丢失而丢失。当创建队列时,将队列的属性设置为持久化(durable = true)即可。
- 消息持久化
- 原理:除了队列持久化,还需要将消息设置为持久化。这样,当 RabbitMQ 服务器发生意外情况(如断电、重启等)时,消息能够在服务器恢复后依然存在。在发送消息时,将消息的属性设置为持久化(MessageProperties.PERSISTENT_TEXT_PLAIN)。
- 局限性:消息持久化会增加一定的性能开销,因为 RabbitMQ 需要将消息写入磁盘来保证持久化。而且在极端情况下,如磁盘损坏,消息依然可能丢失。
3.消费者可靠接收
- 自动消息确认和手动消息确认
- 原理:RabbitMQ 默认是自动消息确认模式,消费者一旦接收到消息,就会自动向 RabbitMQ 服务器发送确认消息,然后消息就会从队列中删除。但这种方式可能会导致消息丢失,例如消费者在处理消息的过程中出现故障。手动消息确认模式则可以让消费者在成功处理完消息后再发送确认消息,这样可以确保消息不会丢失。
- 消息预取(QoS)
- 原理:通过设置消息预取(Quality of Service,QoS),可以限制消费者一次接收的消息数量。这样可以防止消费者接收过多的消息而无法及时处理,导致消息积压或者丢失。例如,设置 QoS 为 1,消费者一次只会接收一条消息,只有在处理完这条消息并确认后,才会接收下一条消息。
6.RabbitMQ的其他知识
重试机制 死信队列
相关文章:

Rabbit MQ知识总结
1.什么是Rabbit MQ? Rabbit MQ是一个开源的消息代理软件,它实现了高级消息队列协议(AMQP); 基本概念 消息:消息是在应用程序之间传递的数据单元。可以是简单的文本信息,可以是复杂的对象。队列:队列是消息的容器&am…...

未来将要被淘汰的编程语言
COBOL - 这是一种非常古老的语言,主要用于大型企业系统和政府机构。随着老一代IT工作人员的退休,COBOL程序员变得越来越少。Fortran - 最初用于科学和工程计算,Fortran在特定领域仍然有其应用,但随着更现代的语言(如Py…...

GO环境安装和配置
安装go环境 wget https://go.dev/dl/go1.22.4.linux-amd64.tar.gz -P /usr/local或者去官网下载安装包 tar -xzf go1.23.4.linux-amd64.tar.gz sudo mv go /usr/local export GOROOT/usr/local/go export GOPATH$HOME/go export PATH$PATH:/usr/local/go/bin source ~/.bashr…...

面试题整理(四)
1.Max transition,leakage优化,hold time ,setup time violation修复的顺序是? 答:先把max transition修复掉,如果max transition有violation,意味着其超出了查找表范围之外,所以计算得到的delay都不是很准的。 其次是把setup修复了,因为setup相对来说,需要减少cell…...

mathtype中如何在公式和序号之间加点
1,右编号插入公式 2,打开样式面板(ctrlshiftalts) 3,选中MTDisplayEquation样式,右击修改 4,点击格式,弹出下拉列表,点击制表位 5,先选中34.67字符&#…...

【电源专题】电源芯片的PG(Power Good)管脚是什么?
在看电源芯片规格书时,你会发现有一些电源芯片有PG管脚。如下ti.com.cn/product/cn/tps56637?qgpn=tps56637规格书所示: 对应的描述是:Open Drain Power Good Indicator, it is asserted low if output voltage is out of PG threshold due to over-voltage, under…...

C/C++圣诞树
系列文章 序号直达链接1C/C爱心代码2C/C跳动的爱心3C/C李峋同款跳动的爱心代码4C/C满屏飘字表白代码5C/C大雪纷飞代码6C/C烟花代码7C/C黑客帝国同款字母雨8C/C樱花树代码9C/C奥特曼代码10C/C精美圣诞树11C/C俄罗斯方块12C/C贪吃蛇13C/C孤单又灿烂的神-鬼怪14C/C闪烁的爱心15C…...

牛客--求小球落地5次后所经历的路程和第5次反弹的高度,称砝码
求小球落地5次后所经历的路程和第5次反弹的高度 描述 假设有一个小球从 hh 米高度自由落下,我们不考虑真实的物理模型,而是简洁的假定,该小球每次落地后会反弹回原高度的一半;再落下,再反弹;……。 求小球…...

cad学习 day6
平面布置图 文字标注: 材料代码(视口外进行标注) 成品家具(移动家具)、定制家具、洁具、家电电器根据封面设计说明内容进行文字标注sc 缩放代码符号, 打印可以看的清楚 家具尺寸图 家具尺寸标注: 家具尺寸; 过道尺寸; 冰箱、洗衣机、马桶(预览尺寸)D 平面内尺寸置为当前, 视…...

Chrome 浏览器插件获取网页 iframe 中的 window 对象
Chrome 浏览器插件获取网页 iframe 中的 window 对象 前言 之前写了篇《Chrome 浏览器插件获取网页 window 对象》文章,是获取当前页面的 window 对象,但是有些页面是嵌入 iframe 的,特别是系统项目主域一样,那就也需要获取 ifr…...

免费线上签字小程序,开启便捷电子签名
虽如今数字化飞速发展的时代,但线上签名小程序的开发制作却并非易事。需要攻克诸多技术难题,例如确保签名的真实性与唯一性,防止签名被伪造或篡改。 要精准地捕捉用户手写签名的笔迹特征,无论是笔画的粗细、轻重,还是…...

IT运维的365天--021 服务器上的dns设置后不起作用
之前在内网搭建了一个和外网同域名的网站,开发同事今天告诉我,程序调试发现可能服务器不能正常访问自己内网的网站内容。于是,今天的故事开始了。 前面的文章在下面列出,当然不看也问题不大,今天的主题是:…...

深信服企业级数据备份与恢复系统(整机裸机恢复)
概述 深信服企业级数据备份与恢复系统可实现无需搭建目标环境,目标机可以是没有操作系统的物理主机或虚拟机,实现异构环境下的裸机恢复。 深信服企业级数据备份与恢复系统支持的多种连接恢复方式: 1. PXE连接恢复:PXE连接需要做…...

Tool之Excalidraw:Excalidraw(开源的虚拟手绘风格白板)的简介、安装和使用方法、艾米莉应用之详细攻略
Tool之Excalidraw:Excalidraw(开源的虚拟手绘风格白板)的简介、安装和使用方法、艾米莉应用之详细攻略 目录 Excalidraw 简介 1、Excalidraw 的主要特点: Excalidraw 安装和使用方法 1、Excalidraw的安装 T1、使用 npm 安装: T2、使用 …...

OPPO C++面试题及参考答案
五层协议每层包含的协议 在计算机网络的五层协议体系结构(自下而上为物理层、数据链路层、网络层、传输层和应用层)中,各层包含多种协议。 物理层主要负责在物理介质上传输原始的比特流,包括像 RJ - 45 接口标准等物理接口规范&am…...

Unity中LineRenderer使用MeshCollider方法参考
运行时,如果一个物体不添加Collider组件就没有办法被鼠标点击,LineRenderer由于其Mesh会随着摄像机朝向变化,如果要通过添加MeshCollider来使其能够与鼠标交互,就需要不断同步更新其MeshCollider网格。 代码参考如下: …...

BERT模型入门(1)BERT的基本概念
文章目录 BERT是Bidirectional Encoder Representations from Transformers的首字母简写,中文意思是:Transformer的双向编码器表示。它是谷歌发布的最先进的嵌入模型。BERT在许多NLP任务中提供了更好的结果,如问答、文本生成、句子分类等&…...

致命错误: Class ‘ZipArchive‘ not found
银河麒麟V10处理 本人在安装过程遇到的坑,就是不要使用太低版本的 1、安装cmake 确认是否安装 cmake --version 如果没安装的话按照如下步骤处理下(如果想要其他版本点击cmake官网下载) wget https://github.com/Kitware/CMake/release…...

二手车交易平台开发:安全与效率的双重挑战
3.1系统体系结构 系统的体系结构非常重要,往往决定了系统的质量和生命周期。针对不同的系统可以采用不同的系统体系结构。本系统为二手车交易平台系统,属于开放式的平台,所以在体系结构中采用B/s。B/s结构抛弃了固定客户端要求,采…...

vector题目
118. 杨辉三角 - 力扣(LeetCode) 求解题目时候,我们可以将其看作近似的二维数组。 行为vector<vector<int>>,数组的每个数据类型为vector<int>。 列为vector<int>,数组的每个数据类型为int。 通过观察我们可以发现…...

测试测试测试测试测试测试测试测试测试测试
标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主&…...

Cisco WebEx 数据平台:统一 Trino、Pinot、Iceberg 及 Kyuubi,探索 Apache Doris 在 Cisco 的改造实践
导读:Cisco WebEx 早期数据平台采用了多系统架构(包括 Trino、Pinot、Iceberg 、 Kyuubi 等),面临架构复杂、数据冗余存储、运维困难、资源利用率低、数据时效性差等问题。因此,引入 Apache Doris 替换了 Trino、Pinot…...

大恒相机开发(3)—大恒相机工业检测的实际案例
大恒相机工业检测的实际案例 工业检测的实际案例图像采集性能优化技巧工业环境下的稳定性 工业检测的实际案例 以下是一些使用大恒相机进行工业检测的实际案例: 多特征光学成像系统: 在这个案例中,使用大恒相机构建了一个全方位、多特征的图…...

【泛微表单】流程相关信息修改
流程相关信息修改 查询流程对应数据库表名: select b.tablename from workflow_bill b ,workflow_base s,workflow_requestbase t where t.requestid=35389 and t.workflowid = s.id and b...

LeetCode80.删除有序数组的重复项
10多分钟的时间就把一道中等题目做出来了,而且我还没有思考,边写边想。我的思路很简单,就是按照题目意思,从前往后遍历数组并统计相同的个数count,然后一直维护一个左指针,把遍历的数移到左指针上然后左指针…...

rk3568制冷项目驱动开发流程汇总(只适用于部分模块CIF DVP等,自用)
采用fpga输入,3568采集并显示至hdmi RKVICAP 驱动框架说明 RKVICAP驱动主要是基于 v4l2 / media 框架实现硬件的配置、中断处理、控制 buffer 轮转,以及控制 subdevice(如 mipi dphy 及 sensor) 的上下电等功能。 对于RK356X 芯片而言, VICAP…...
费舍尔信息矩阵全面讲述
费舍尔信息矩阵(Fisher Information Matrix) 费舍尔信息矩阵是统计学中一个非常重要的概念,尤其在参数估计、最大似然估计(MLE)和贝叶斯推断中具有广泛的应用。它反映了参数估计的不确定性程度,也可以用来…...

DALFox-一款XSS自动化扫描工具
声明!本文章所有的工具分享仅仅只是供大家学习交流为主,切勿用于非法用途,如有任何触犯法律的行为,均与本人及团队无关!!! 目录标题 一、介绍及使用启动及使用1. 单个扫描2. 多个扫描3. 文件扫描…...

Python 异步协程:从 async/await 到 asyncio 再到 async with
在 Python 3.8 以后的版本中,异步编程变得越来越重要。本文将系统介绍 Python 标准库中的异步编程工具,带领大家掌握 async/await 语法和 asyncio 的使用。 从一个简单的场景开始 假设我们在处理一些耗时的 I/O 操作,比如读取多个文件或处理…...

云原生周刊:利用 eBPF 增强 K8s
开源项目推荐 Slurm-operator Slurm-operator 是一个高效可扩展的框架,用于在 K8s 环境中部署和运行 Slurm 工作负载。 它结合了 Slurm 的可靠性和 Kubernetes 的灵活性,支持快速部署 Slurm 集群、动态扩展 HPC 工作负载,并提供高度灵活的定…...