RabbitMQ的幂等性、优先级队列和惰性队列
文章目录
- 一、幂等性
- 1、概念
- 2、消息重复消费
- 3、解决思路
- 4、消费端的幂等性保障
- 5、唯一 ID+指纹码机制
- 6、Redis 原子性
- 二、优先级队列
- 1、使用场景
- 2、如何添加
- 3、实战
- 三、惰性队列
- 1、使用场景
- 2、两种模式
- 3、内存开销对比
- 总结
一、幂等性
1、概念
用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。举个最简单的例子,那就是支付,用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额发现多扣钱了,流水记录也变成了两条。在以前的单应用系统中,我们只需要把数据操作放入事务中即可,发生错误立即回滚,但是再响应客户端的时候也有可能出现网络中断或者异常等等
2、消息重复消费
消费者在消费 MQ 中的消息时,MQ 已把消息发送给消费者,消费者在给 MQ 返回 ack 时网络中断,故 MQ 未收到确认信息,该条消息会重新发给其他的消费者,或者在网络重连后再次发送给该消费者,但实际上该消费者已成功消费了该条消息,造成消费者消费了重复的消息。
3、解决思路
MQ 消费者的幂等性的解决一般使用全局 ID 或者写个唯一标识比如时间戳 或者 UUID 或者订单消费者消费 MQ 中的消息也可利用 MQ 的该 id 来判断,或者可按自己的规则生成一个全局唯一 id,每次消费消息时用该 id 先判断该消息是否已消费过。
4、消费端的幂等性保障
在海量订单生成的业务高峰期,生产端有可能就会重复发生了消息,这时候消费端就要实现幂等性,这就意味着我们的消息永远不会被消费多次,即使我们收到了一样的消息。业界主流的幂等性有两种操作:a.唯一 ID+指纹码机制,利用数据库主键去重, b.利用 redis 的原子性去实现。
5、唯一 ID+指纹码机制
指纹码:我们的一些规则或者时间戳加别的服务给到的唯一信息码,它并不一定是我们系统生成的,基本都是由我们的业务规则拼接而来,但是一定要保证唯一性,然后就利用查询语句进行判断这个 id 是否存在数据库中,优势就是实现简单就一个拼接,然后查询判断是否重复;劣势就是在高并发时,如果是单个数据库就会有写入性能瓶颈当然也可以采用分库分表提升性能,但也不是我们最推荐的方式。
6、Redis 原子性
利用 redis 执行 setnx 命令,天然具有幂等性。从而实现不重复消费。
二、优先级队列
1、使用场景
在我们系统中有一个订单催付的场景,我们的客户在天猫下的订单,淘宝会及时将订单推送给我们,如果在用户设定的时间内未付款那么就会给用户推送一条短信提醒,很简单的一个功能对吧,但是,tmall商家对我们来说,肯定是要分大客户和小客户的对吧,比如像苹果,小米这样大商家一年起码能给我们创造很大的利润,所以理应当然,他们的订单必须得到优先处理,而曾经我们的后端系统是使用 redis 来存放的定时轮询,大家都知道 redis 只能用 List 做一个简简单单的消息队列,并不能实现一个优先级的场景,所以订单量大了后采用 RabbitMQ 进行改造和优化,如果发现是大客户的订单给一个相对比较高的优先级,否则就是默认优先级。
2、如何添加
- a.控制台页面添加

- b.队列中代码添加优先级
Map<String, Object> params = new HashMap();
params.put("x-max-priority", 10);
channel.queueDeclare("hello", true, false, false, params);

- c.消息中代码添加优先级
AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().priority(5).build();
- d.注意事项
要让队列实现优先级需要做的事情有如下事情:队列需要设置为优先级队列,消息需要设置消息的优先级,消费者需要等待消息已经发送到队列中才去消费因为,这样才有机会对消息进行排序。
3、实战
- a.消息生产者
public class Producer {private static final String QUEUE_NAME="hello";public static void main(String[] args) throws Exception {try (Channel channel = RabbitMqUtils.getChannel();) {//给消息赋予一个 priority 属性AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().priority(5).build();for (int i = 1; i <11; i++) {String message = "info"+i;if(i==5){channel.basicPublish("", QUEUE_NAME, properties, message.getBytes());}else{channel.basicPublish("", QUEUE_NAME, null, message.getBytes());}System.out.println("发送消息完成:" + message);}}}
}
- b.消息消费者
public class Consumer {private static final String QUEUE_NAME="hello";public static void main(String[] args) throws Exception {Channel channel = RabbitMqUtils.getChannel();//设置队列的最大优先级 最大可以设置到 255 官网推荐 1-10 如果设置太高比较吃内存和 CPUMap<String, Object> params = new HashMap();params.put("x-max-priority", 10);channel.queueDeclare(QUEUE_NAME, true, false, false, params);System.out.println("消费者启动等待消费......");DeliverCallback deliverCallback=(consumerTag, delivery)->{String receivedMessage = new String(delivery.getBody());System.out.println("接收到消息:"+receivedMessage);};channel.basicConsume(QUEUE_NAME,true,deliverCallback,(consumerTag)->{System.out.println("消费者无法消费消息时调用,如队列被删除");});}
}
三、惰性队列
1、使用场景
RabbitMQ 从 3.6.0 版本开始引入了惰性队列的概念。惰性队列会尽可能的将消息存入磁盘中,而在消费者消费到相应的消息时才会被加载到内存中,它的一个重要的设计目标是能够支持更长的队列,即支持更多的消息存储。当消费者由于各种各样的原因(比如消费者下线、宕机亦或者是由于维护而关闭等)而致使长时间内不能消费消息造成堆积时,惰性队列就很有必要了。
默认情况下,当生产者将消息发送到 RabbitMQ 的时候,队列中的消息会尽可能的存储在内存之中,这样可以更加快速的将消息发送给消费者。即使是持久化的消息,在被写入磁盘的同时也会在内存中驻留一份备份。当 RabbitMQ 需要释放内存的时候,会将内存中的消息换页至磁盘中,这个操作会耗费较长的时间,也会阻塞队列的操作,进而无法接收新的消息。虽然 RabbitMQ 的开发者们一直在升级相关的算法,但是效果始终不太理想,尤其是在消息量特别大的时候。
2、两种模式
队列具备两种模式:default 和 lazy。默认的为 default 模式,在 3.6.0 之前的版本无需做任何变更。lazy模式即为惰性队列的模式,可以通过调用 channel.queueDeclare 方法的时候在参数中设置,也可以通过Policy 的方式设置,如果一个队列同时使用这两种方式设置的话,那么 Policy 的方式具备更高的优先级。如果要通过声明的方式改变已有队列的模式的话,那么只能先删除队列,然后再重新声明一个新的。
在队列声明的时候可以通过“x-queue-mode”参数来设置队列的模式,取值为“default”和“lazy”。下面示例中演示了一个惰性队列的声明细节:
Map<String, Object> args = new HashMap<String, Object>();
args.put(“x-queue-mode”, “lazy”);
channel.queueDeclare(“myqueue”, false, false, false, args);
3、内存开销对比

在发送 1 百万条消息,每条消息大概占 1KB 的情况下,普通队列占用内存是 1.2GB,而惰性队列仅仅占用 1.5MB
总结
以上就是RabbitMQ的幂等性、优先级队列和惰性队列的相关知识点,希望对你有所帮助。
相关文章:
RabbitMQ的幂等性、优先级队列和惰性队列
文章目录 一、幂等性1、概念2、消息重复消费3、解决思路4、消费端的幂等性保障5、唯一 ID指纹码机制6、Redis 原子性 二、优先级队列1、使用场景2、如何添加3、实战 三、惰性队列1、使用场景2、两种模式3、内存开销对比 总结 一、幂等性 1、概念 用户对于同一操作发起的一次请…...
Uniapp-小程序自定义导航栏
一、项目背景 制作小程序页面时候发现原生导航栏有一定的高度是没有背景渲染的会出现这种情况 但是我们需要的是 二、原因 小程序的原生导航栏存在。一般可以使用 纯色填充顶部栏 可以直接使用navigationBarBackgroundColor完成 在style中添加 "navigationBarBackgrou…...
云课五分钟-08安装Opera成功-仓库中查找对应版本
前篇: 云课五分钟-07安装Opera失败-版本不匹配 视频: 云课五分钟-08安装Opera成功-仓库中查找对应版本 文本: 最佳的途径就是使用系统内置的FireFox。 这么折腾的主要是为了演示安装一个第三方程序可能遇到的问题,并给出一些思…...
设计师的好帮手!在线PS网页版工具让创意无限发挥!
PS已经成为设计师必备的基本技能软件。PS版本的不断更新升级使PS功能更加强大。PS可以完成从简单的艺术家到复杂的设计和插画。但与此同时,PS也有设计师经常批评的痛点:大文件运行时内存卡住,位图放大后清晰度低,无穷无尽的快捷键,…...
Android Glide加载transform CenterCrop, CircleCrop ShapeableImageView圆形图并描边,Kotlin
Android Glide加载transform CenterCrop, CircleCrop ShapeableImageView圆形图并描边,Kotlin import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import com.bumptech.glide.load.resource.bitmap.CenterCrop import com.bumptech.glide.…...
【docker启动的Jenkins时,遇到时区问题处理】
1、查看容器中的时区 [rootlocalhost jenkins]# docker exec -it jenkins cat /etc/timezone Etc/UTC而本地使用的是Asia/shanghai [rootlocalhost jenkins]# timedatectl | grep Time zoneTime zone: n/a (CST, 0800)###查看 [rootlocalhost jenkins]# cd /usr/share/zoneinf…...
MySQL8.0学习笔记
1. CMD命令 1.1 数据库启动与停止 (1) 启动数据库:net start mysql80 (2) 停止数据库:net stop mysql80 1.2 数据库连接与退出 (1) 连接数据库:mysql [-hlocalhost -P3306] -uroot -p[123456] // 本地数据库可省略-h -P (2) 退出数据库…...
初始MySQL(七)(MySQL表类型和存储引擎,MySQL视图,MySQL用户管理)
目录 MySQL表类型和存储引擎 MyISAM MEMORY MySQL视图 我们先说说视图的是啥? 视图的一些使用细节 MySQL用户管理 原因 常见操作 MySQL表类型和存储引擎 -- 查看所有的存储引擎 SHOW ENGINES 我们常见的表有MyISAM InnoDB MEMORY 1.MyISAM不支持事务,也不支持外…...
Redis 配置文件信息中文翻译版
前言 Redis 配置文件信息中文翻译版,方便大家阅读和理解对应参数信息及配置参数信息 # Redis configuration file example# Note on units: when memory size is needed, it is possible to specify # it in the usual form of 1k 5GB 4M and so forth: # 注意:当…...
React项目首页中用canvas实现星空
文章目录 前言代码使用后言 前言 hello world欢迎来到前端的新世界 😜当前文章系列专栏:前端系列文章 🐱👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误,感谢大家…...
flutter ios Exception : No Impeller Context is Available
在模拟器上运行 ios 项目的时候,图片显示不出来。真机可以显示 原因:ios默认启用 impeller(新渲染引擎),不知道为什么项目不能使用。 禁用掉即可, 原因以及解决都在下面的链接里面了 Impeller rendering …...
[PHP]写个简单的分页静态接口用宝塔部署到Nginx
使用get方式传入page和pageSize参数,接口根据参数进行分页处理。 1.创建一个 PHP 文件 例如 city.php,用于定义接口和返回 JSON 数据。 2.在 city.php 文件中编写接口 <?php// 设置响应内容为 JSON 格式 header(Content-Type: application/json);…...
表单提交是
首先,确保你已经安装了Vue 3、Element UI和axios(用于发送HTTP请求)。你可以使用以下命令进行安装: bash复制代码 npm install vuenext element-ui axios --save <template> <el-form :model"form" :rules&q…...
Qt的委托代理机制
委托是Qt中的一种机制,用于在Qt模型/视图架构中处理特定类型的数据。委托提供了一种方便的方法来定制特定类型的数据的显示和编辑。委托可以做以下事情: 编辑特定类型的数据: 通过创建编辑器来编辑特定类型的数据,例如日期,数值等。 渲染特定类型的数据: 通过定制单…...
OpenCV入门5——OpenCV的算术与位运算
文章目录 图像的加法运算图像的减法运算图像的乘除运算图像的融合OpenCV位运算-非操作OpenCV位操作-与运算OpenCV位操作-或与异或为图像添加水印 图像的加法运算 # -*- coding: utf-8 -*- import cv2 import numpy as npimg cv2.imread(E://pic//4.jpg)# 图的加法运算就是矩阵…...
好用的开源项目地址
Sword: SpringBlade前端UI项目,基于react 、ant design、dva、umi,用于快速构建系统中后台业务。 官网:https://bladex.cn Saber: SpringBlade前端UI项目,对现有的avue2.0、element-ui库进行二次封装。基于json驱动的模块配置&am…...
深度学习(五)softmax 回归之:分类算法介绍,如何加载 Fashion-MINIST 数据集
Softmax 回归 基本原理 回归和分类,是两种深度学习常用方法。回归是对连续的预测(比如我预测根据过去开奖列表下次双色球号),分类是预测离散的类别(手写语音识别,图片识别)。 现在我们已经对回…...
单稳态中间继电器\UEG/A-2H/220V 8A导轨安装 JOSEF约瑟
UEG系列中间继电器 UEG/A-2H2D中间继电器UEG/A-4H4D中间继电器UEG/A-2D中间继电器 UEG/A-2H中间继电器UEG/A-4H中间继电器UEG/A-4D中间继电器 UEG/A-6H中间继电器UEG/A-6D中间继电器UEG/A-8H中间继电器 UEG/A-10D中间继电器UEG/A-10H中间继电器UEG/A-2DPDT中间继电器 UEG/A-4DP…...
2311rust到20版本更新
Rust1.9 Rust1.9中最大的变化是稳定了包括停止恐慌启动的展开过程方法的std::panic模块: use std::panic; let result panic::catch_unwind(|| {println!("hello!"); }); assert!(result.is_ok()); let result panic::catch_unwind(|| {panic!("oh no!"…...
基于Spring、SpringMVC、MyBatis的漫画网站
文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于Spring、SpringMVC、MyBatis的漫画网…...
腾讯小龙虾使用指南
腾讯小龙虾使用指南腾讯小龙虾是一款集成了多种实用功能的工具,广泛应用于数据分析、自动化处理和团队协作等领域。以下指南将详细介绍其核心功能、操作方法和最佳实践。安装与配置下载腾讯小龙虾的安装包,支持Windows、Mac和Linux系统。运行安装程序后&…...
Qwen3-32B-Chat中文优化:提升OpenClaw本地任务理解准确率
Qwen3-32B-Chat中文优化:提升OpenClaw本地任务理解准确率 1. 为什么需要优化本地模型的中文理解能力 去年冬天,当我第一次尝试用OpenClaw自动化整理电脑上的文件时,遇到了一个令人哭笑不得的场景。我对它说"把上周下载的PDF文件按日期…...
Windows 11三指拖拽功能完全配置指南:从驱动安装到手势优化
Windows 11三指拖拽功能完全配置指南:从驱动安装到手势优化 【免费下载链接】ThreeFingersDragOnWindows Enables macOS-style three-finger dragging functionality on Windows Precision touchpads. 项目地址: https://gitcode.com/gh_mirrors/th/ThreeFingersD…...
LabVIEW以声卡为数据采集设备开发数据采集处理系统。 具备声卡参数设置,实现文件自动存储、...
LabVIEW以声卡为数据采集设备开发数据采集处理系统。 具备声卡参数设置,实现文件自动存储、以及文件手动存储两种功能,进行采集数据的分析,包括频域分析,滤波处理等功能; 程序实验报告在工业测量和实验室场景中&#x…...
思源宋体TTF:开源中文字体的技术突破与商业价值重构
思源宋体TTF:开源中文字体的技术突破与商业价值重构 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 在数字化内容爆炸的今天,中文字体的选择直接影响信息传递的…...
通义千问1.5-1.8B-Chat-GPTQ-Int4效果实测:对比Claude Code的代码生成能力
通义千问1.5-1.8B-Chat-GPTQ-Int4效果实测:对比Claude Code的代码生成能力 最近在尝试各种轻量级的代码生成模型,想看看在资源有限的情况下,哪个工具能更好地辅助日常开发。通义千问1.5-1.8B-Chat-GPTQ-Int4这个版本,因为做了量化…...
STM32CubeIDE开发环境详解与实战指南
STM32CubeIDE开发环境全解析:从入门到实战1. 开发环境概述1.1 STM32CubeIDE核心特性STM32CubeIDE是基于Eclipse框架的集成开发环境,专为STM32微控制器设计。其主要技术特性包括:集成STM32CubeMX配置工具内置GCC编译工具链支持GDB调试接口跨平…...
OpenClaw性能测试:Qwen3.5-4B-Claude处理百页文档实测
OpenClaw性能测试:Qwen3.5-4B-Claude处理百页文档实测 1. 测试背景与目标 上周我在整理一个开源项目的技术文档时,遇到了一个头疼的问题——这份文档长达137页,包含了代码示例、架构图和版本变更说明。手动梳理关键信息耗费了我整整两天时间…...
GLM-4-9B-Chat-1M惊艳效果:输入50万字小说,精准定位伏笔与人物关系图谱
GLM-4-9B-Chat-1M惊艳效果:输入50万字小说,精准定位伏笔与人物关系图谱 1. 百万长文处理新标杆 想象一下,你手头有一部50万字的网络小说,想要找出所有埋设的伏笔线索,理清复杂的人物关系网。传统方法可能需要花费数天…...
【Polars 2.0数据清洗成本控制白皮书】:20年ETL专家亲授5大降本增效实战模式,92%企业忽略的内存泄漏陷阱
第一章:Polars 2.0数据清洗成本控制全景认知在现代数据工程实践中,数据清洗不再仅关乎逻辑正确性,更深度绑定计算资源消耗、内存占用与执行延迟。Polars 2.0 通过零拷贝语义、惰性执行引擎重构与 Arrow-native 内存布局优化,将清洗…...
