当前位置: 首页 > 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的临床表型信息。这些数据集为科研人员提供了丰富的基因表达数据和相关的临床…...

常用大语言模型简单介绍

LLaMA(Large Language Model Meta AI)和 Qwen是两个不同的大语言模型,它们在开发背景、设计目标和使用场景等方面有所不同。 1. LLaMA: 开发背景: LLaMA 是由Facebook开发的大语言模型,主要针对学术研究和开源领域。它的设计初衷…...

云计算Openstack

OpenStack是一个开源的云计算管理平台项目,由美国国家航空航天局(NASA)和Rackspace公司合作研发并发起,以Apache许可证授权。该项目旨在为公共及私有云的建设与管理提供软件支持,通过一系列相互协作的组件实现云计算服…...

ClickHouse复杂查询单表亿级数据案例(可导出Excel)

通过本篇博客,读者可以了解到如何在 ClickHouse 中高效地创建和管理大规模销售数据。随机数据生成和复杂查询的示例展示了 ClickHouse 的强大性能和灵活性。掌握这些技能后,用户能够更好地进行数据分析和决策支持,提升业务洞察能力。 表结构…...

ST-GCN模型实现花样滑冰动作分类

加入深度实战社区:www.zzgcz.com,免费学习所有深度学习实战项目。 1. 项目简介 本项目实现了A042-ST-GCN模型,用于对花样滑冰动作进行分类。花样滑冰作为一项融合了舞蹈与竞技的运动,其复杂的动作结构和多变的运动轨迹使得动作识别成为一个具…...

计算机网络基础--认识协议

目录 前言 一、IP地址与端口 二、网络协议 1.网络体系结构框架 2.网络字节序 前言 提示:这里可以添加本文要记录的大概内容: 计算机网络涉及非常广泛,这篇文章主要对计算机网络有个认识 提示:以下是本篇文章正文内容&#x…...

基本控制结构2

顺序结构 程序按照语句的书写次序顺序执行。 选择结构 判断选择结构又称条件分支结构,是一种基本的程序结构类型。 在程序设计中,当需要进行选择、判断和处理的时候,就要用到条件分支结构。 条件分支结构的语句一般包括if语句、if–else…...

php 平滑重启 kill -SIGUSR2 <PID> pgrep命令查看进程号

有时候我们使用nginx 大家都知道平滑重启命令: /web/nginx/sbin/nginx -s reload 但大家对php-fpm 重启 可能就是简单暴力的kill 直接搞起了 下面介绍一个sh 文件名保存为start_php.sh 来对php-fpm 进行平滑重启 #!/bin/bash# 检查 PHP-FPM 是否运行 if ! pgrep php-…...

实时美颜功能技术揭秘:视频美颜SDK与API的技术剖析

当下,用户希望在视频直播中呈现出最佳状态,这推动了视频美颜SDK和API的迅速发展。本文将深入剖析这项技术的核心原理、应用场景以及未来趋势。 一、实时美颜技术的基本原理 在实现这些效果的过程中,视频美颜SDK通常会使用以下几种技术&…...

word2vector训练代码详解

目录 1.代码实现 2.知识点 1.代码实现 #导包 import math import torch from torch import nn import dltools #加载PTB数据集 ,需要把PTB数据集的文件夹放在代码上一级目录的data文件中,不用解压 #批次大小、窗口大小、噪声词大小 batch_size, ma…...

Python的风格应该是怎样的?除语法外,有哪些规范?

写代码不那么pythonic风格的,多多少少都会让人有点难受。 什么是pythonic呢?简而言之,这是一种写代码时遵守的规范,主打简洁、清晰、可读性高,符合PEP 8(Python代码样式指南)约定的模式。 Pyth…...

js网站登录怎么做/qq群推广网站

Description 给你一个无向图&#xff0c;N(N<500)个顶点, M(M<5000)条边&#xff0c;每条边有一个权值Vi(Vi<30000)。给你两个顶点S和T&#xff0c;求一条路径&#xff0c;使得路径上最大边和最小边的比值最小。如果S和T之间没有路径&#xff0c;输出”IMPOSSIBLE”&a…...

建网站被封了/百度手机助手app下载官网

第二章 项目初始化和第一个小例子.md初始化项目项目目录介绍自定义爬虫类自定义第一个爬虫录入代码代码解释&#xff1a;运行爬虫运行结果代码逐条分析简易版本经过了上一章的学习&#xff0c;我们已经在开发环境上安装好了scrapy的包&#xff0c;接下来我们就将初始化一个项目…...

网站编辑器介绍/谷歌seo视频教程

目录1、前言2、主从复制好处3、服务器准备4、环境搭建4.1、创建集群工作目录4.2、搭建单机环境4.3、集群配置4.4、复制实例4.5、修改其他实例配置文件4.6、创建批量启动/关闭脚本4.7、创建集群5、整合SpringBoot6、删除、新增节点6.1、删除从节点6.2、新增从节点6.3、删除主节点…...

制作网站 公司/网站优化的主要内容

想要让自己写的一个普通类创建的对象扔到Spring 容器中管理&#xff0c;有以下方法&#xff1a; 使用 常规的注解&#xff0c;Controller Service Repository Component 注解标注该类&#xff0c;然后确保 ComponentScan 扫描路径包含以上的类即可 使用 Bean 注解的方法里面 n…...

建设信用卡官方网站/培训心得体会800字

电大计算机科学与技术c语言各章练习题答案各章练习题答案第1章 C语言概述1.1 简答题1 答&#xff1a;C语言单词分为保留字、标识符、字面常量、运算符和分隔符5类。2 答&#xff1a;首字符必须是英文字母或下划线&#xff1b;其余位置上的字符必须是英文字母、十进制数字符号或…...

网站建设收费标准市场/网站统计数据

原创!ngxtop-监控nginx的利器!!! 无论名称还是界面,ngxtop的灵感均源自大名鼎鼎的top命令.ngxtop的功能就是,分析Nginx访问日志文件&#xff08;以及其他日志文件,比如Apache2日志&#xff09;,并通过类似top的界面,实时显示分析后所得的结果.你可能吹嘘自己的综合监控工具拥有…...