当前位置: 首页 > article >正文

消息队列5-RabbitMQ的高级特性和MQ的应用问题与解决方案-事务、消息分发的应用、幂等性保证、顺序性保证、消息积压的解决

文章目录一. 事务1. 模版开启事务功能2. 配置事务管理器3. 声明队列4. 生产者5. 运行图二. 消息分发1. 限流(1) yml配置文件(2) 声明队列与交换机及绑定关系(3) 生产者(4) 消费者(5) 运行图2. 负载均衡(1) yml配置(2) 消费者代码(3) 运行图三. MQ的幂等性保证1. MQ中存在的问题2. 解决方案四. 顺序性保证方案1. 出现顺序性问题的场景2. 解决方案(1) 单队列单消费者(2) 分区消费(3) 消息(消费者)确认机制(4) 业务逻辑管理五. 消息积压1. 产生原因2. 解决方案一. 事务事务指将一系列操作打包为一块执行, 具有原子性, 要不全部成功, 要不全部失败, 且在执行过程中不会被其他操作插入, 而在AMQP的协议中实现了事务机制, 因此RabbitMQ也支持事务下面使用Spring-AMQP来使用事务功能, 交换机是默认交换机1. 模版开启事务功能// 事务Bean(transactionRabbitTemplate)publicRabbitTemplatetransactionRabbitTemplate(ConnectionFactoryconnectionFactory){RabbitTemplaterabbitTemplatenewRabbitTemplate(connectionFactory);rabbitTemplate.setChannelTransacted(true);// 开启事务功能returnrabbitTemplate;}2. 配置事务管理器// 创建事务管理器, 必须和上面开启事务功能配合使用BeanpublicRabbitTransactionManagerrabbitTransactionManager(ConnectionFactoryconnectionFactory){returnnewRabbitTransactionManager(connectionFactory);}3. 声明队列这里使用默认交换机, 不用声明Bean(transQueue)publicQueuetransQueue(){returnQueueBuilder.durable(Constants.TRANS_QUEUE).build();}4. 生产者这里我们在生产者发送两条消息之间, 代码逻辑产生异常Transactional// 事务管理的注解RequestMapping(/trans)publicStringtrans(){System.out.println(trans test...);transactionRabbitTemplate.convertAndSend(,Constants.TRANS_QUEUE,trans 1 ...);intnum1/0;transactionRabbitTemplate.convertAndSend(,Constants.TRANS_QUEUE,trans 2 ...);return发送成功;}5. 运行图正常情况下, 消息1是可以发送成功的, 但在这里可以看到队列中一条消息也没有, 说明事务进行了回滚二. 消息分发RabbitMQ处于工作模式时, 如果有多个消费者, 每个消息只会发送给其中一个订阅者, 消息不会被重复消费, 默认情况下, RabbitMQ以轮询方式发送消息, 不考虑每个消费者的处理能力, 这在一些请求量暴增特定场景下, 会导致消费者处理不过来, 消息越积越多, 即消息积压为解决上面的情况, 可以使用channel.basicQos(int prefetchCount)方法 — 在Spring-AMQP中采用的是配置yml文件, 来限制一个消费者上最大的未确认消息数, 从而控制流量, 防止宕机下面介绍消息分发的应用场景1. 限流如在一些特定时间的秒杀场景, 流量会剧增, 如果不对这些流量加以限制的话, 会直接导致订单系统压力过大宕机下面介绍在Spring-AMQP中如何使用限流(1) yml配置文件在使用限流前, 必须开启消费者对于消息的手动确认模式spring:application:name:Spring-extension-demo rabbitmq:host:localhost port:5672username:admin password:admin virtual-host:extension listener:simple:acknowledge-mode:manual # 消息确认机制 手动确认 prefetch:5(2) 声明队列与交换机及绑定关系packagecom.ran.extension.config;importcom.ran.extension.constant.Constants;importorg.springframework.amqp.core.*;importorg.springframework.beans.factory.annotation.Qualifier;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;/** * Created with IntelliJ IDEA. * Description: * User: ran * Date: 2026-04-02 * Time: 20:26 */ConfigurationpublicclassQosConfig{Bean(QosExchange)publicExchangeQosExchange(){returnExchangeBuilder.directExchange(Constants.QOS_EXCHANGE).build();}Bean(QosQueue)publicQueueQosQueue(){returnQueueBuilder.durable(Constants.QOS_QUEUE).build();}Bean(QosBinding)publicBindingQosBinding(Qualifier(QosQueue)Queuequeue,Qualifier(QosExchange)Exchangeexchange){returnBindingBuilder.bind(queue).to(exchange).with(qos).noargs();// noargs()方法表示,交换机没有其他参数}}(3) 生产者这里发送20条消息RequestMapping(/qos)publicStringqos(){for(inti0;i20;i){rabbitTemplate.convertAndSend(Constants.QOS_EXCHANGE,qos,qos...i);}return发送成功;}(4) 消费者这里我们消费之后, 不进行确认, 这样的话消费者就不会继续从队列获取消息, 因此队列中还剩15条待发消息, 有5条未确认消息packagecom.ran.extension.listener;importcom.rabbitmq.client.Channel;importcom.ran.extension.constant.Constants;importorg.springframework.amqp.core.Message;importorg.springframework.amqp.rabbit.annotation.RabbitListener;importorg.springframework.stereotype.Component;importjava.io.IOException;importjava.util.Date;/** * Created with IntelliJ IDEA. * Description: * User: ran * Date: 2026-03-31 * Time: 18:24 */ComponentpublicclassQosListeners{RabbitListener(queuesConstants.QOS_QUEUE)publicvoidhandlerQos(Messagemessage,Channelchannel)throwsIOException{longdeliveryTagmessage.getMessageProperties().getDeliveryTag();try{System.out.println(队列[Constants.QOS_QUEUE]接收到消息: newString(message.getBody()), deliveryTag: deliveryTag);}catch(Exceptione){channel.basicNack(deliveryTag,false,true);}}}(5) 运行图队列中还剩15条待发消息, 有5条未确认消息, 共20条2. 负载均衡多个消费者中, 可能有处理能力差的, 也有处理能力强的, 负载均衡就是强者多处理一些, 弱者少处理一点, 根据每个消费者的具体情况来分发流量(1) yml配置对于负载均衡来说, prefetch一般配置为1, 消费者确认一条消息后, 再从队列获取一条消息, 能者多劳spring:application:name:Spring-extension-demo rabbitmq:host:localhost port:5672username:admin password:admin virtual-host:extension listener:simple:acknowledge-mode:manual # 消息确认机制 手动确认 prefetch:1# 负载均衡一般配置为1(2) 消费者代码消费者1处理完一条消息后睡眠200ms, 消费者2睡眠400msComponentpublicclassQosListeners{RabbitListener(queuesConstants.QOS_QUEUE)publicvoidhandlerQos1(Messagemessage,Channelchannel)throwsIOException{longdeliveryTagmessage.getMessageProperties().getDeliveryTag();try{System.out.println(消费者1接收到消息: newString(message.getBody()), deliveryTag: deliveryTag);Thread.sleep(200);channel.basicAck(deliveryTag,false);}catch(Exceptione){channel.basicNack(deliveryTag,false,true);}}RabbitListener(queuesConstants.QOS_QUEUE)publicvoidhandlerQos2(Messagemessage,Channelchannel)throwsIOException{longdeliveryTagmessage.getMessageProperties().getDeliveryTag();try{System.out.println(消费者2接收到消息: newString(message.getBody()), deliveryTag: deliveryTag);Thread.sleep(400);channel.basicAck(deliveryTag,false);}catch(Exceptione){channel.basicNack(deliveryTag,false,true);}}}(3) 运行图三. MQ的幂等性保证幂等性是从数学中引入的概念, 指的是重复调用同一函数, 传入相同的参数, 最终结果是不变的, 例如取绝对值abs(x)在程序中, 指的是同一个系统多次执行同一指令, 不论执行多少次, 最终对系统造成的影响是一致的, 例如数据库中的select操作, 多次查询数据库, 都得到的是同一查询结果, 接下我们介绍的幂等性是所有MQ都要面临的问题, 不只是RabbitMQ1. MQ中存在的问题在上面的订单-MQ-支付组成的系统中, 已知在金融服务, 消息丢失是不可容忍的, 因此为保证消息可靠性, 发布方确认机制, 消费确认机制等等会全部开启, 下面就是可能会出现重复订单的情况情况一: 订单系统(生产者)发送订单消息, 可能会因为网络波动原因, 导致消息已经到达了MQ, 却没有收到MQ的ACK, 这时订单系统会再次发送同一份订单消息, 这就会导致支付系统会收到重复的订单情况二: MQ在向支付系统发送订单消息后, 因为网络波动, 可能会导致支付系统处理完订单后, MQ却没有接收到ACK, 这时MQ会再次重复发送这个订单消息2. 解决方案上面的情况, 如果对用户进行了两次扣款, 就是一个巨大的漏洞, 因此必须要保证MQ消息的幂等性, 即对于重复订单, 只需要支付一次即可最常用的解决方式为:1. 生产者(订单系统)给每条消息添加一个唯一ID, 必须确保是唯一的2. 消费者(支付系统)在收到消息后, 先判断ID是否已经被消费过, 如果被消费过, 直接丢弃即可3. 如果没有被消费过, 开始进行业务处理, 处理成功后, 将ID用数据库(MySQL)或者缓存(Redis)保存起来, 方便为重复消息做判断例如用Redis的 SETNX 命令来存储ID, 返回1代表保存成功, 返回0说明被消费过, 直接丢弃四. 顺序性保证方案在有些业务场景中, 对于消息的顺序有着严格的要求, 例如订单-MQ-支付系统1. 出现顺序性问题的场景因为多个生产者同时发送消息到MQ上, 是无法确定顺序性的, 这里就默认是一个生产者的前提1. 一个队列对应多个消费者, 消息可能会被多个消费者并行处理, 无法保证顺序性2. 网络原因导致ACK确认丢失, 消息重新入队后, 顺序性发生问题3. 在复杂路由中, 一系列消息由于RoutingKey的原因, 路由到了不同队列, 这就无法保证顺序性2. 解决方案顺序性保证又分为局部和全局的, 局部指的是单个队列间的消息顺序, 全局指的是多个队列或者多个消费者之间的消息顺序, 这里需要注意, 确保顺序性是多个方案相互配合使用来保证的, 单一方案并不能保证顺序性(1) 单队列单消费者在单个队列对应单个消费者中, 消息满足FIFO(先进先出)的特性, 天然满足顺序性(2) 分区消费一个队列只对应一个消费者, 吞吐量确实太低, 需要高性能的场景时, 进行分区消费未进行分区时, 拿订单系统-MQ-支付系统来举例, MQ中可能同一时间有多条消息等待消费, 分别有订单的创建, 支付成功, 发货等等, 在下面图片中, 如果消费者1先处理了订单1的支付成功, 消费者2因为网络原因后处理的订单1创建, 就会导致消费者1去数据库中查询不到订单信息, 从而丢弃消息我们可以使用分区消费的方式, 把MQ中的消息分割成多个分区, 每个订单对应一个分区, 每个分区对应一个队列(RabbitMQ通过使用一致性哈希器的方式来路由到每个队列上), 每个队列由一个消费者处理, 每个队列内的消息又天然满足顺序性(3) 消息(消费者)确认机制通过手动确认方式, 消费者每处理成功一条消息, 再继续进行下一条消息的处理拉取(4) 业务逻辑管理通过为消息嵌入序列号, 然后在消费端进行排序, 最后再按顺序处理消息五. 消息积压当消息队列中, 消息的生成速度大于消费者的处理速度时, 就会导致消息再队列中不断积压, 成为消息积压1. 产生原因1. 生产端: 在一些高流量的特定场景, 生产者的发送消息的速率极高, 超过了消费者处理能力2. 消费端: 生产者发送消息速率正常, 但是消费者的处理速度跟不上生成速度, 也会导致积压, 那么消费者为什么会跟不上速度呢? 下面是原因① 业务逻辑较复杂, 耗时长② 屎山代码累计, 性能较低③ 系统资源的限制, 消费端的硬件配置较低④ 消费端发生异常时, 处理不当, 例如不断频繁重试发送同一消息, 导致消息积压3. 网络问题, 消费者无法及时接收消息4. MQ服务器硬件配置较低2. 解决方案1. 限制生产者(不常用)① 通过流量控制逻辑, 根据消费者的处理能力动态发送消息② 这是过期时间, 到达过期时间丢入私信队列, 以此来减少主队列的压力2. 提升消费者① 增加消费者实例② 优化业务代码, 使用多线程③ 设置prefetchCount, 一个消费者达到数量时, 即使转发到其他队列④ 消费端代码逻辑异常时, 采用合适重试机制, 不再频繁重试, 也可以存到死信队列

相关文章:

消息队列5-RabbitMQ的高级特性和MQ的应用问题与解决方案-事务、消息分发的应用、幂等性保证、顺序性保证、消息积压的解决

文章目录一. 事务1. 模版开启事务功能2. 配置事务管理器3. 声明队列4. 生产者5. 运行图二. 消息分发1. 限流(1) yml配置文件(2) 声明队列与交换机及绑定关系(3) 生产者(4) 消费者(5) 运行图2. 负载均衡(1) yml配置(2) 消费者代码(3) 运行图三. MQ的幂等性保证1. MQ中存在的问题…...

3步解锁高效采集:让小红书素材获取效率提升80%的XHS-Downloader开源工具

3步解锁高效采集:让小红书素材获取效率提升80%的XHS-Downloader开源工具 【免费下载链接】XHS-Downloader 小红书(XiaoHongShu、RedNote)链接提取/作品采集工具:提取账号发布、收藏、点赞、专辑作品链接;提取搜索结果作…...

《YOLOv11 实战:从入门到深度优化》002、环境搭建:从零配置YOLOv11开发与训练环境

002、环境搭建:从零配置YOLOv11开发与训练环境 昨天深夜调试一个边缘设备上的推理异常,问题最终定位到CUDA版本和torch不匹配——这种环境配置埋下的坑,往往比算法本身更难排查。今天咱们就老老实实把YOLOv11的环境从头搭一遍,这份…...

三月七小助手:如何用智能自动化工具将星穹铁道日常效率提升300%

三月七小助手:如何用智能自动化工具将星穹铁道日常效率提升300% 【免费下载链接】March7thAssistant 崩坏:星穹铁道全自动 三月七小助手 项目地址: https://gitcode.com/gh_mirrors/ma/March7thAssistant 你是否每天花费大量时间在《崩坏&#xf…...

定义适应度函数,也就是我们要算的总能耗,越小越好

基于粒子群优化算法的地表水源热泵机组优化调度 以水源热泵机组角度对地表水源热泵系统建模, 并采用粒子群优化算法优化算法求解热泵机组每小时最佳制冷量和制热量最近帮朋友做了个小区地表水源热泵的调度优化项目,一开始以为就是调调空调温度&#xff0…...

XHS-Downloader:解决小红书内容采集痛点的开源工具创新方案

XHS-Downloader:解决小红书内容采集痛点的开源工具创新方案 【免费下载链接】XHS-Downloader 小红书(XiaoHongShu、RedNote)链接提取/作品采集工具:提取账号发布、收藏、点赞、专辑作品链接;提取搜索结果作品、用户链接…...

c语言实战:基于快马平台ai生成可部署的tcp聊天室服务器

今天想和大家分享一个用C语言实现的TCP聊天室服务器项目,这个项目完全在InsCode(快马)平台上完成,从代码生成到调试部署一气呵成。作为一个网络编程的经典案例,这个聊天室服务器涵盖了socket编程、多线程处理、IO复用等核心知识点&#xff0c…...

实战演练:基于快马平台与OpenClaw实现颜色分拣机器人应用

最近在做一个工厂自动化的小项目,正好用到了OpenClaw机械爪控制库,结合颜色识别实现了一个智能分拣系统。这个实战案例特别适合在InsCode(快马)平台上快速验证,下面分享下我的实现思路和关键要点。 项目整体架构设计 系统主要分为三个核心模块…...

4.4【A】

进程之间不能直接访问对方内存所以必须用 Socket 共享内存 通信每个进程独立运行每个进程自己负责自己的连接网卡模拟器进程:监听 PCIe 连接QEMU 进程:主动连接 PCIe它们通过 Socket 建立连接,交换自我介绍然后用共享内存高速通信底层状态初…...

Nginx性能优化-压缩

但很多开发者在配置nginx时容易混淆两个概念:Gzip动态压缩和Gzip静态压缩。本文将带你彻底搞懂这两者的区别、配置方法以及最佳实践。什么是Gzip动态压缩?原理: 当客户端(浏览器)发起请求时,Nginx接收到请求…...

G-Helper终极指南:开源硬件性能管理工具如何彻底改变华硕设备体验

G-Helper终极指南:开源硬件性能管理工具如何彻底改变华硕设备体验 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF…...

新手零基础入门网络自动化:快马AI带你写出第一个设备信息采集脚本

作为一名刚接触网络自动化运维的新手,我最近在InsCode(快马)平台上尝试了第一个设备信息采集脚本的编写。整个过程比我预想的要简单很多,尤其是平台提供的AI辅助功能,让我这个零基础用户也能快速上手。下面分享我的学习笔记和实际操作心得。 …...

如何快速解锁WeMod Pro功能:Wand-Enhancer完整免费指南

如何快速解锁WeMod Pro功能:Wand-Enhancer完整免费指南 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer Wand-Enhancer是一款强大的开源工具&…...

从SolidWorks到Simulink动画:手把手教你用URDF和Simscape搭建六轴机械臂仿真模型

六轴机械臂仿真全流程:从SolidWorks建模到Simulink动画生成实战指南 当我在实验室第一次看到自己设计的机械臂在Simulink中流畅地完成抓取动作时,那种成就感至今难忘。许多机器人工程师都曾面临这样的困境:在SolidWorks中精心设计的机械臂模型…...

SSN在LiDAR目标检测环境配置、SSN在LiDAR目标检测模型代跑训练、SSN在LiDAR目标检测模型改进创新SSN在LiDAR目标检测环境配置:Windows、Ubuntu、Centos、

SSN在LiDAR目标检测环境配置、 SSN在LiDAR目标检测模型代跑训练、 SSN在LiDAR目标检测模型改进创新 SSN在LiDAR目标检测环境配置:Windows、Ubuntu、Centos、Macos等系统环境,如果电脑拥有显卡,可配置GPU版本的SSN在LiDAR环境。 SSN在LiDAR目标…...

Fooocus:让AI图像创作触手可及的革新工具

Fooocus:让AI图像创作触手可及的革新工具 【免费下载链接】Fooocus Focus on prompting and generating 项目地址: https://gitcode.com/GitHub_Trending/fo/Fooocus 价值定位:AI绘画的民主化革命 🚀 在数字创作领域,专业…...

如何绕过iOS 15-16激活锁:AppleRa1n工具实战指南

如何绕过iOS 15-16激活锁:AppleRa1n工具实战指南 【免费下载链接】applera1n icloud bypass for ios 15-16 项目地址: https://gitcode.com/gh_mirrors/ap/applera1n 当你的iPhone或iPad因遗忘Apple ID密码、二手交易或维修后无法激活时,设备瞬间…...

OpenClaw+Phi-3-mini-128k-instruct:技术博客自动生成与Hexo部署

OpenClawPhi-3-mini-128k-instruct:技术博客自动生成与Hexo部署 1. 为什么需要自动化技术博客写作 作为一名技术博主,我长期面临一个困境:代码写得多,文章写得少。每次完成一个项目后,明明有很多值得分享的技术细节&…...

COMSOL 6.1版本皮秒多脉冲激光烧蚀模型:双温模型、变形几何与烧蚀模拟

COMSOL 6.1版本 皮秒多脉冲激光烧蚀模型 模型内容:涉及双温模型,变形几何,烧蚀,皮秒脉冲热源,电子、晶格温度 优势:模型注释清晰明了,各个情况都有涉及可参考性极强,可以修改&#x…...

实时控制循环示例

LCC-S无线电能传输pi移相控制输出电压,效果很棒 SS结构,与其他低阶高阶拓扑也可以做 SS拓扑最近在捣鼓无线电能传输系统时,意外发现LCC-S拓扑搭配π型移相控制,输出效果堪比美颜相机里的磨皮功能。这货不仅能把输出电压纹波压得比…...

百度网盘macOS客户端下载速度技术优化方案:基于开源工具的本地部署实践

百度网盘macOS客户端下载速度技术优化方案:基于开源工具的本地部署实践 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 问题诊断&#xff1…...

Ubuntu服务器部署AI模型:Phi-4-mini-reasoning一站式安装配置指南

Ubuntu服务器部署AI模型:Phi-4-mini-reasoning一站式安装配置指南 1. 前言:为什么选择Phi-4-mini-reasoning 如果你正在寻找一个轻量级但性能不俗的AI推理模型,Phi-4-mini-reasoning是个不错的选择。这个模型特别适合部署在Ubuntu服务器上&…...

3种多平台直播效率提升方案:obs-multi-rtmp插件技术实践指南

3种多平台直播效率提升方案:obs-multi-rtmp插件技术实践指南 【免费下载链接】obs-multi-rtmp OBS複数サイト同時配信プラグイン 项目地址: https://gitcode.com/gh_mirrors/ob/obs-multi-rtmp 核心摘要 多平台直播已成为内容创作者扩大影响力的必要手段&am…...

Agent落地方法论入门到精通(非常详细),帮你避坑收藏这篇就够了!

涉及到智能体应用的开发时,agent相关知识不可能绕过,不管是基于langchain还是autogen,都要系统性了解agent,才能对agent开发有全面充分的理解。 Agent 到底是什么 如果从工程角度定义: Agent 以大模型为核心决策器&a…...

告别浏览器!3分钟快速掌握Transmission Remote GUI远程下载管理终极方案

告别浏览器!3分钟快速掌握Transmission Remote GUI远程下载管理终极方案 【免费下载链接】transgui 🧲 A feature rich cross platform Transmission BitTorrent client. Faster and has more functionality than the built-in web GUI. 项目地址: htt…...

VS2022下载与全面使用指南

Visual Studio 2022(简称VS2022)是微软推出的最新一代集成开发环境(IDE),于2021年11月正式发布,相比上一代VS2019,在性能优化、功能迭代、兼容性提升等方面实现了全方位升级,被誉为“…...

别再死记硬背了!用Python+Matplotlib动态可视化5G NR的帧结构与RB资源分配

用Python动态解析5G NR帧结构:从理论到可视化实战 在通信技术快速迭代的今天,5G NR(新空口)作为第五代移动通信的核心技术,其灵活的帧结构设计一直是工程师和研究者关注的焦点。传统学习方式往往依赖静态图表和文字描述,让许多初学…...

宝塔面板安全加固全攻略:从密码重置到IP白名单配置(附常见问题解决)

宝塔面板安全加固全攻略:从密码重置到IP白名单配置(附常见问题解决) 在公网环境下,服务器安全防护是每个运维人员的必修课。作为国内最受欢迎的服务器管理面板之一,宝塔面板的便捷性与其潜在的安全风险并存。本文将系统…...

风廓线雷达:大气垂直探测的 “高空哨兵” 与数据体系解析/一文秒懂

一、风廓线雷达:精准捕捉高空风场的遥感利器 风廓线雷达是气象探测领域中用于 连续、实时、遥感探测大气垂直风场结构 的核心装备,被誉为大气监测的 “高空哨兵” 与 “捕风神器” 。它依托大气湍流散射理论与多普勒雷达技术,无需携带探空仪…...

如何优化多表查询性能_利用SQL视图与索引视图提升速度

SQL Server索引视图未生效主因是查询未精确匹配视图定义,须显式引用视图名或启用ANSI_WARNINGS/ARITHABORT;MySQL视图无加速作用;PostgreSQL物化视图刷新卡顿需用CONCURRENTLY并建唯一索引。SQL Server 里索引视图为什么没生效?多…...