RabbitMQ的幂等性、优先级队列和惰性队列

news2024/11/26 16:45:44

文章目录

  • 前言
  • 一、幂等性
    • 1、概念
    • 2、消息重复消费
    • 3、解决思路
    • 4、消费端的幂等性保障
    • 5、唯一 ID+指纹码机制
    • 6、Redis 原子性
  • 二、优先级队列
    • 1、使用场景
    • 2、如何添加
    • 3、实战
  • 三、惰性队列
    • 1、使用场景
    • 2、两种模式
    • 3、内存开销对比
  • 总结


前言

一、幂等性
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 如果设置太高比较吃内存和 CPU
 		Map<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的幂等性、优先级队列和惰性队列的相关知识点,希望对你有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1625851.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

金职在线 央企国企 跟私企都有哪些区别

一、性质不同 央企国企是国家的全资子公司&#xff0c;属于国有企业。私企就是由自然人投资设立或由自然人控股&#xff0c;以雇佣劳动为基础的营利性经济组织。 二、管理不同 央企国企有完整的审批程序和监管机制&#xff0c;而私企的决策相对简单。国企是政府管理的&#…

李彦宏:程序员将不复存在! 周鸿祎回怼!网友:先把百度程序员都开除了!

近日&#xff0c;百度创始人、董事长兼首席执行官李彦宏在央视《对话》•开年说的访谈中指出&#xff1a;“基本上说以后其实不会存在“程序员”这种职业了&#xff0c;因为只要会说话&#xff0c;人人都会具备程序员的能力”。 “未来的编程语言只会剩下两种&#xff0c;一种…

.net EntityFramework EF

创建EF 方法1 方法二 安装的 版本是 中间没有弹出让选框架的界面&#xff0c; EF三种开发方式 1》》 db first 先设计数据库→然后在代码通过EF与数据库建立映射关系&#xff0c;是EF最早的一种使用方式,使用广泛.以数据库为驱动&#xff0c;生成实体模型&#xff0c;从而驱…

------分割线之 WebSecurityConfigrerAdapter弃用问题------

WebSecurityConfigurerAdapter 被弃用的原因是 Spring Security 项目的维护者希望将项目的主要开发工作集中在新的配置方式上&#xff0c;即基于 Java 的配置&#xff08;Java Configuration&#xff09;和基于 Lambda 的表达式。这主要是因为 Spring 5.0 引入了重量级的 Java …

k8s pod 无法启动一直ContainerCreating

情况如下&#xff0c;更新 pod 时&#xff0c;一直在ContainerCreating 查看详细信息如下 Failed to create pod sandbox: rpc error: code Unknown desc [failed to set up sandbox container “334d991a478b9640c66c67b46305122d7f0eefc98b2b4e671301f1981d9b9bc6” networ…

精益思想赋能数字化转型:落地策略与实践路径

当下&#xff0c;数字化转型已不再是选择题&#xff0c;而是关乎企业生存与发展的必答题。然而&#xff0c;转型过程中如何确保效率、降低成本并快速实现价值创造&#xff0c;成为了摆在众多企业面前的难题。精益思想作为一种追求精益求精、持续改进的管理思维&#xff0c;为数…

一般神经网络的微分与网络参数的初始化

(文章的主要内容来自电科的顾亦奇老师的 Mathematical Foundation of Deep Learning, 有部分个人理解) 一般深度神经网络的微分 上周讨论的前向和反向传播算法可以推广到任意深度神经网络的微分。 对于一般的网络来说&#xff0c;可能无法逐层分割&#xff0c;但仍然可以用流…

顺序表经典算法:头脑风暴来袭

✨✨小新课堂开课了&#xff0c;欢迎欢迎~✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;http://t.csdnimg.cn/XSLtz&#xff08;经典算法题&#xff09; 小新的主页&#xff1a;编程版小新-CSDN博客 前言…

利用Landsat遥感卫星数据反演地表温度的方法与应用

随着遥感技术的快速发展&#xff0c;Landsat系列卫星数据成为了地表温度监测和研究的重要数据源之一。本文将介绍如何利用Landsat数据反演地表温度的方法以及在环境监测、气候变化、水文循环和农业生产等领域的应用。 1. Landsat数据概述 Landsat卫星是美国国家航空航天局&…

NVM和NodeJS安装教程

NVM和NodeJS安装教程 NVM和NodeJS安装教程 NVM和NodeJS安装教程一、下载 NVM二、安装 NVM三、安装 NodeJS1. 安装指令2. 查看下载的所有node版本3. 使用版本4. 检查是否安装成功 四、配置 NVM 和 NodeJS1. 配置环境变量2. 配置node_global和node_cache 用的 NVM 下载&#xff0…

学习随手记ComboBoxEx选定项的值value和text值获取方法

代码&#xff1a;dotNetBar2中的ComboxBoxEx的使用方法 //获取选定项的value值 string _v ((DevComponents.Editors.ComboItem)cbo_cmdType.SelectedItem).Value.ToString(); //获取选定项的text值 string _t ((DevComponents.Editors.ComboItem)cbo_cmdType.SelectedItem)…

论文解读:(CAVPT)Dual Modality Prompt Tuning for Vision-Language Pre-Trained Model

v1文章名字&#xff1a;Dual Modality Prompt Tuning for Vision-Language Pre-Trained Model v2文章名字&#xff1a;Class-Aware Visual Prompt Tuning for Vision-Language Pre-Trained Model 文章汇总 对该文的改进&#xff1a;论文解读&#xff1a;(VPT)Visual Prompt …

更新!!!Unity移动端游戏性能优化简谱

UWA官方出品&#xff0c;结合多年优化经验撰写了《Unity移动端游戏性能优化简谱》&#xff0c;文章从Unity移动端游戏优化的一些基础讨论出发&#xff0c;例举和分析了近几年基于Unity开发的移动端游戏项目中最为常见的部分性能问题&#xff0c;并展示了如何使用UWA的性能检测工…

Golang特殊init函数

介绍 init()函数是一个特殊的函数&#xff0c;存在一下特性 不能被其它函数调用&#xff0c;而是子main()函数之前自动调用不能作为参数传入不能有传入参数和返回值 作用&#xff1a; 对变量进行初始化检查/修复程序状态注册运行一次计算 以下是<<the way to go>>…

环保设备产线智能工厂数字孪生可视化平台,推进制造业数字化转型

环保设备产线智能工厂数字孪生可视化平台&#xff0c;推进制造业数字化转型。数字化转型已成为制造业发展的重要趋势&#xff0c;而环保设备产线智能工厂数字孪生可视化平台则是推进制造业数字化转型的关键之一。环保设备产线智能工厂数字孪生可视化平台是一种基于数字孪生技术…

JS实现对用户名、密码进行正则表达式判断,按钮绑定多个事件,网页跳转

目标&#xff1a;使用JS实现对用户名和密码进行正则表达式判断&#xff0c;用户名和密码正确时&#xff0c;进行网页跳转。 用户名、密码的正则表达式检验 HTML代码&#xff1a; <button type"submit" id"login-btn" /*onclick"login();alidate…

Lombok插件 注解(有参无参getset方法)

Java神奇工具——Lombok[最全]_java lombok-CSDN博客 在普通的java项目 1直接导入lombok 的jar包 2配置文件路径 配置正确的lombok路径&#xff0c;需要添加lombok插件实现 找到全局设置 查看是否安装lombok插件 &#xff08;idea一般自带有lombok插件&#xff09; 在Maven中 …

贪吃蛇详解

Win32 API介绍&#xff1a; 在写贪吃蛇这款游戏时需要用到一些有关Win32 API的知识&#xff0c; 接下来我会将设计到的知识点列举并讲解&#xff1a; 首先我们先了解一下Win32 API是什么&#xff0c;Windows这个多作业系统除了协调应⽤程序的执⾏、分配内存、管理资源之外&am…

基于灰狼优化器GWO与小龙虾优化算法COA的无人机航迹规划

一、灰狼优化器算法 灰狼优化算法&#xff08;Grey Wolf Optimizer&#xff0c;GWO&#xff09;由澳大利亚格里菲斯大学学者 Mirjalili 等人于2014年提出来的一种群智能优化算法。该算法受到了灰狼捕食猎物活动的启发而开发的一种优化搜索方法&#xff0c;它具有较强的收敛性能…

使用 Dify 和 MoonShot API 做一个懒人 AI 阅读工具(二):轻量 RAG 应用

这篇文章&#xff0c;我们继续聊聊&#xff0c;如何折腾 AI 应用&#xff0c;把不 AI 的东西&#xff0c;“AI 起来”。 在不折腾复杂的检索系统的前提下&#xff0c;做一些轻量的 RAG 实践。 写在前面 我从“机器之心会员通讯”上线以来就在订阅&#xff0c;相比较即时的行…