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

【RabbitMQ】幂等性、顺序性

幂等性

概述

幂等性是数学和计算机科学中某些运算的性质,他们可以被多次应用,而不会改变初始应用的结果。RabbitMQ的幂等性则是指同一条消息,多次消费,对系统的影响是相同的。

一般消息中间件的消息传输保障分为三个层级:

  • 最少一次(At least once):消息绝对不会丢失,但可能会重复传输。
  • 恰好一次(Exactly once):每条消息肯定会被传输一次且仅传输一次。
  • 最多一次(At most once):消息可能会丢失,但绝对不会重复传输。

RabbitMQ支持最少一次和最多一次。对于恰好一次,RabbitMQ目前做不到,而且很多消息中间件都做不到这一点。

在业务使用中,对于可靠性要求较高的场景,建议使用最少一次,以防消息丢失。最多一次会因为消息发送过程中,网络问题、消费出现异常等种种原因,导致消息丢失。但是最少一次,就会使得消费端可能收到重复的消息,也会造成对同一条消息的多次处理。对于一些比较重要的业务而言,重复处理相同的消息,就会造成严重事故。例如:当用户对一个订单付款之后,因为网络问题,付款成功的结果未返回给订单系统,当用户再次点击付款时,如果系统未做幂等性处理,那就会造成两次扣款。

以下场景可能会导致消息重复发送:

发送时消息重复:当一条消息已被成功发送到Broker并完成持久化,此时出现了网络闪断或者客户端宕机,导致Broker对客户端应答失败,如果此时生产者意识到发送失败并尝试再次发送消息,消费者后续会收到两条内容相同并且MessageID也相同的消息。

投递时消息重复:消息消费的场景下,消息已投递到消费者并完成业务处理,当客户端给服务端反馈应答的时候网络中断。为了保证消息至少被消费一次,消息队列会在网络恢复之后再次尝试投递之前已经被处理过的消息,消费者后续会收到两条内容相同并且MessageID也相同的消息。

解决方案

全局唯一ID

首先,为每条消息分配一个唯一标识符,例如雪花算法、UUID等,只要能保证唯一性即可。

其次,消费者收到消息后,先用唯一标识符判断该消息是否已经消费过,如果消费过就直接放弃。

最后,如果没有消费过,消费者就开始消费信息,业务处理成功之后,把唯一标识符保存起来。

可以使用Redis的原子性操作setnx来保证幂等性,将唯一标识符作为KEY放到Redis中。消费消息之前,先SETNX ID 1。如果返回值为1,表示之前没有消费过,正常消费。返回值为0,则表示这条消息之前已消费过,直接抛弃。

业务逻辑判断

在业务逻辑层面实现消息处理的幂等性。

可以使用数据库来保证幂等性,通过检查数据库是否已经存在相关数据记录;也可以使用锁机制来保证幂等性,通过使用乐观锁机制来避免更新已经被其他事务更改的数据;还可以使用相关业务状态来保证幂等性,在消费者处理消息之前,先检查相关的业务状态,确保消息对应的操作尚未执行,然后才进行处理,具体根据业务场景来做。

顺序性

概述

消息的顺序性是指消费者消费的消息和生产者发送消息的顺序是一致的。例如生产者发送的消息依次是msg1、msg2、msg3,那么消费者消费消息的顺序也必须按照msg1、msg2、msg3的顺序进行。

很多业务场景下,消息的消费是不用保证顺序的,比如使用MQ实现订单超时的处理。但是有些业务场景下,可能存在多个消息顺序处理的情况,比如用户信息修改,对同一个用户的同一个资料进行修改,需要保证消息的顺序。

在实际场景中,如果只有一个生产者,也只有一个消费者,并且不考虑消息丢失、网络故障等异常情况,是可以保证消息的顺序性。但是,如果有多个生产者同时发送消息,无法确定消息到达Broker的前后顺序,也就无法验证消息的顺序性。

打破顺序性的场景:

  • 多个消费者:当队列配置了多个消费者时,消息可能会被不同的消费者并行处理,从而导致消息处理的顺序性无法保证。
  • 网络波动或异常:在消息传递的过程中,如果出现网络波动或异常,可能会导致ACK(消息确认)丢失,从而使得消息被重新入队和重新消费,造成顺序性问题。
  • 消息重试:如果消费者在处理消息后未能及时发送确认,或者确认消息在传输过程中丢失,那么MQ可能会认为消息未被成功消费而进行重试,这也可能导致消息处理的顺序性问题。
  • 消息路由问题:在复杂的路由场景中,消息可能会根据路由键被发送到不同的队列,从而无法保证全局的顺序性。
  • 死信队列:消息因为某些原因进入死信队列,死信队列被消费时,无法保证消息的顺序和生产者发送消息的顺序一致。

打破顺序性的场景包括但不限于以上几种,如果要保证消息的顺序性,那就需要对消息进行进一步的处理。

解决方案

消息顺序性保障分为:局部顺序性保障和全局顺序性保障。

局部顺序性保障指的是在单个队列内部保证消息的顺序。全局顺序性保障指的是在多个队列或多个消费者之间保障消息的顺序。

在实际工作中,全局顺序性难以实现,可以考虑使用业务逻辑来保障顺序性。比如在消息中嵌入序列号,并在消费端进行排序处理。相对而言,局部顺序性更常见,也更容易实现。

RabbitMQ作为一个分布式消息队列,主要优化的是吞吐量和可用性,而不是严格的顺序性保障。如果业务场景确实需要严格的消息顺序,可能需要在应用层面进行额外的设计和实现。

单队列单消费者

最简单的实现顺序性保障的方法一定是,使用单个队列,并由单个消费者进行处理。同一个队列中的消息是先进先出的,这就足以实现消息的顺序性。

分区消费

虽然单消费者单队列可以完美保障消息的顺序性,但是其吞吐太低了。当需要多个消费者以提高处理速度时,可以使用分区消费。把一个队列分割成多个分区,每个分区由一个消费者处理,以此保障每个分区内消息的顺序性。例如最开始的修改资料这一业务,我们只需要保障每个用户的消息顺序性即可,因此我们可以使用分区消费来做(可以借助Spring-CLoud-Stream来实现)。

消息确认机制

使用手动消息确认机制,消费者在处理完一条消息后,显式地发送确认,这样RabbitMQ才会移除并继续发送下一条消息。

业务逻辑控制

在某些情况下,即使消息乱序到达,也可以在业务逻辑层面实现顺序控制。比如通过在消息中嵌入序列号,并在消费时根据这些信息来处理。

RabbitMQ本身并不能保证全局的严格顺序性。在实际开发中,根据具体的业务需求,可能需要结合多种策略来实现所需要的顺序保证。

 

相关文章:

【RabbitMQ】幂等性、顺序性

幂等性 概述 幂等性是数学和计算机科学中某些运算的性质,他们可以被多次应用,而不会改变初始应用的结果。RabbitMQ的幂等性则是指同一条消息,多次消费,对系统的影响是相同的。 一般消息中间件的消息传输保障分为三个层级&#…...

FFmpeg源码:avio_skip函数分析

AVIOContext结构体和其相关的函数分析: FFmpeg源码:avio_r8、avio_rl16、avio_rl24、avio_rl32、avio_rl64函数分析 FFmpeg源码:read_packet_wrapper、fill_buffer函数分析 FFmpeg源码:avio_read函数分析 FFmpeg源码&#xff…...

Llama 3.1 技术研究报告-6

6 推理 我们研究了两种主要技术,以使 Llama 3 405B 模型的推理⾼效:(1) 流⽔线并⾏和 (2) FP8 量化。我们已经公开发布了我们的 FP8 量化实现。 6.1 流⽔线并⾏ 当使⽤ BF16 数字表⽰模型参数时,Llama 3 405B 不适合在装有 8 个 Nvidia H1…...

更新日志-Python OS

这么久没更新全是因为这段时间的事情很多,只能一点一点的更新代码,不过好在,也是成功更新出来啦! 更新日志(2024/9/29) 代码全文更新,将所有的绝对路径替换为相对路径,这样在各位大…...

Chrome浏览器的C++内存管理技术揭秘

Chrome浏览器作为全球最流行的网络浏览器之一,其高效的内存管理技术功不可没。本文将深入探讨Chrome浏览器在C中的内存管理技术,并介绍如何通过调整网页加载时间、优化视频播放体验和解决谷歌浏览器占用CPU过高的问题来提升浏览器性能。 (本…...

Redis --- redis事务和分布式事务锁

redis事务基本实现 Redis 可以通过 MULTI,EXEC,DISCARD 和 WATCH 等命令来实现事务(transaction)功能。 > MULTI OK > SET USER "Guide哥" QUEUED > GET USER QUEUED > EXEC 1) OK 2) "Guide哥"使用 MULTI命令后可以输入…...

SQL,将多对多的关联记录按行输出

数据库的Primary表和Secondary表有相同的结构,其中W、H、D是主键。Primary表:NameWHDPrimary item 1100500300Primary item 2100600300Primary item 3200500300Primary item 4100500300Primary item 5100600300Primary item 6200500300 Secondary表&…...

【SQL】筛选字符串与正则表达式

目录 语法 需求 示例 分析 代码 语法 SELECT column1, column2, ... FROM table_name WHERE condition; WHERE 子句用于指定过滤条件,以限制从数据库表中检索的数据。当你执行一个查询时,WHERE 子句允许你筛选出满足特定条件的记录。如果记录满…...

【Redis入门到精通五】Java如何像使用MySQL一样使用Redis(jedis安装及使用)

目录 Jedis 1.jedis是什么 2.jedis的安装配置 3.jedis的基础命令操作展示 1.set和get操作: 2.exists和del操作: 3.keys和type操作: 4. expire和ttl: Jedis Java 操作 redis 的客⼾端有很多,其中最知名的是 jedi…...

【 微信机器人+ AI 搭建】

摘要: 各种大模型已经出来好久了,各类app也已经玩腻了,接下来,就在考虑,怎么让大模型,利益最大化。 本人没有显著的家世,没有富婆包养,只能自己抽点时间,研究下技术&…...

VGG16网络介绍及代码撰写详解(总结1)

可以从本人以前的文章中可以看出作者以前从事的是嵌入式控制方面相关的工作,是一个机器视觉小白,之所以开始入门机器视觉的学习只要是一个idea,想把机器视觉与控制相融合未来做一点小东西。废话不多说开始正题。 摘要:本文是介绍V…...

多个excel表数据比对操作

多个excel表数据比对操作 本文主要使用两种方法进行比对,分别使用了openpyxl第三方库和pandas第三方库进行数据比对 两种方法优缺点: openpyxy: 优点:主要是处理xlsx的文件,里面方法简单,易懂 缺点:当数据量大的时候,速度很慢,之前我一条一条数据拿出来比较,两百多条…...

golang学习笔记32——哪些是用golang实现的热门框架和工具

推荐学习文档 golang应用级os框架,欢迎stargolang应用级os框架使用案例,欢迎star案例:基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识,这里有免费的golang学习笔…...

ZYNQ:开发环境搭建

资料下载 http://47.111.11.73/docs/boards/fpga/zdyz_qimxing(V2).html Vivado软件是什么? Vivado软件是Xilinx(赛灵思)公司推出的一款集成设计环境(IDE),主要用于FPGA(现场可编程门阵列&am…...

一步一步丰富生成式语言模型系统

以下是这套生成式语言模型解决任务的流程图概述: #mermaid-svg-sRHDSMUMV1utrg2F {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-sRHDSMUMV1utrg2F .error-icon{fill:#552222;}#mermaid-svg-sRHDSMUMV1u…...

Python中元组的常用方法

# 在Python中,元组(tuple)是一种不可变的序列类型,用于存储多个元素。元组的特点包括: # # 不可变性:一旦创建,元组的元素不能改变。这意味着不能添加、删除或修改元组中的元素。 # 可以包含任何…...

新版本Android Studio如何新建Java code工程

新版本Android Studio主推Kotlin,很多同学以为无法新建Java工程了,其实是可以的,如果要新建Java代码的Android工程,在New Project的时候需要选择Empty Views Activity,如图所示,gradle也建议选为build.grad…...

2024年世界职业院校技能大赛:全面升级的国际化职业技能竞赛

近日,中华人民共和国教育部发布了《2024年世界职业院校技能大赛实施方案》,宣布从2024年起将全国职业院校技能大赛升级为世界职业院校技能大赛。这一重大决策不仅标志着我国职业教育竞赛平台的全面国际化,更彰显了中国在全球职业教育领域的引领作用和战略眼光,具体内…...

前端vue相关常见面试题,包含MVVM、双向绑定原理、性能优化、vue2和vue3性能对比等

vue面试题 MVVM 概念 model view viewModel 本质上是mvc(程序分层开发思想) 将viewModel的状态和行为抽象化,viewmodel将视图ui和业务逻辑分开,去除model的数据,同时处理view中需要展示的内容和业务逻辑 view视图层 …...

生信初学者教程(十二):数据汇总

文章目录 介绍加载R包导入数据汇总表格输出结果总结介绍 在本教程中,汇总了三个肝细胞癌(HCC)的转录组数据集,分别是LIRI-JP,LIHC-US/TCGA-LIHC和GSE14520,以及一个HCC的单细胞数据集GSE149614的临床表型信息。这些数据集为科研人员提供了丰富的基因表达数据和相关的临床…...

Hirschmann RS20-0800M4M4SDAE工业以太网交换机

Hirschmann RS20-0800M4M4SDAE 工业以太网交换机产品特点:端口配置:共8个端口,含6个RJ45电口和2个ST光纤接口。端口速率:所有端口均为100Mbps快速以太网。光纤类型:2个光纤端口为多模、ST接头。管理类型:二…...

Taotoken如何帮助教育科技产品实现个性化学习辅导

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 Taotoken如何帮助教育科技产品实现个性化学习辅导 1. 场景与挑战 教育科技公司在开发个性化学习助手时,常常面临一个核…...

基于雷达与光敏传感器的低功耗智能窗防设备设计与实现

1. 项目概述:一个基于雷达与光敏的智能窗防设备几年前,我因为一次短暂的出差,家里空置了几天,回来后就一直琢磨着怎么给家里的窗户加点“动静”。市面上的智能安防摄像头固然好,但要么需要复杂的布线,要么云…...

特定任务需求场景下的过约束并联机构构型设计与控制方法【附代码】

✨ 长期致力于曲面加工、构型综合、运动学和动力学建模、性能评价、多目标优化、滑模控制、鲁棒控制、视觉传感技术研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流,点击《获取方式》 (…...

GEO优化可以覆盖哪些搜索平台

这是一个非常现实的问题。企业投放资源做GEO,当然希望覆盖面越广越好。那么GEO优化到底能覆盖哪些平台?覆盖到什么程度?不同平台的GEO逻辑有什么差异?GEO平台覆盖的三个层级第一层级:通用大模型AI平台(核心…...

机器学习赋能矩方法:破解稀薄气体强非平衡流动模拟难题

1. 项目概述:当矩方法遇见机器学习在计算流体力学领域,模拟稀薄气体动力学和强非平衡流动,一直是个让工程师和科学家们头疼的“硬骨头”。想象一下,你正在设计一架高超音速飞行器,当它以数倍音速在大气层边缘飞行时&am…...

D3KeyHelper终极指南:5分钟掌握暗黑3最强自动化工具

D3KeyHelper终极指南:5分钟掌握暗黑3最强自动化工具 【免费下载链接】D3keyHelper D3KeyHelper是一个有图形界面,可自定义配置的暗黑3鼠标宏工具。 项目地址: https://gitcode.com/gh_mirrors/d3/D3keyHelper D3KeyHelper是一款专为《暗黑破坏神3…...

体验低延迟与高稳定性的大模型 API 聚合服务调用感受

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 体验低延迟与高稳定性的大模型 API 聚合服务调用感受 在集成大模型能力到实际应用的过程中,开发者最关心的往往是两个核…...

不止是移动:用UE5.1蓝图优化你的MetaHuman性能(头发渲染、LOD设置避坑指南)

不止是移动:用UE5.1蓝图优化你的MetaHuman性能(头发渲染、LOD设置避坑指南)在虚幻引擎5.1中,MetaHuman已经成为了数字人创作的重要工具。然而,许多开发者在实现了基础移动控制后,往往会忽视对MetaHuman资产…...

VLC for Unity:工业级高性能视频渲染替代方案

1. 这不是“又一个视频插件”——VLC for Unity 解决的是 Unity 视频管线里最顽固的硬伤 你有没有在 Unity 项目里,把一段 4K H.265 的监控流拖进 VideoPlayer 组件,结果帧率直接掉到 8 FPS,GPU 占用飙到 95%,而 CPU 却只用了 30%…...