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

RabbitMQ的应用问题

一、幂等性保障

幂等性是数学和计算机科学中某些运算的性质, 它们可以被多次应⽤, ⽽不会改变初始应⽤的结果

数学上的幂等性:

f(x)=f(f(x))   |x|

数据库操作幂等性:

       数据库的 select 操作. 不同时间两次查询的结果可能不同, 但是这个操作是符合幂等性的. 幂等性指的是对资源的影响, ⽽不是返回结果. 查询操作对数据资源本⾝不会产⽣影响, 之所以结果不同, 可能是因为两次查询之间有其他操作对资源进⾏了修改. 

应用上的幂等性:

       在应⽤程序中, 幂等性就是指对⼀个系统进⾏重复调⽤(相同参数), 不论请求多少次, 这些请求对系统的影响都是相同的效果

非幂等性:⽐如  i++ 这个操作, 就是⾮幂等性的. 如果调⽤⽅没有控制好逻辑, ⼀次流程重复调⽤好⼏次, 结果就会不同.

MQ的幂等性:

       对于MQ⽽⾔, 幂等性是指同⼀条消息, 多次消费, 对系统的影响是相同的.⼀般消息中间件的消息传输保障分为三个层级.
1. At most once:最多⼀次. 消息可能会丢失,但绝不会重复传输.
2. At least once:最少⼀次. 消息绝不会丢失,但可能会重复传输.
3. Exactly once:恰好⼀次. 每条消息肯定会被传输⼀次且仅传输⼀次.
RabbitMQ⽀持"最多⼀次"和"最少⼀次".
对于"恰好⼀次", ⽬前RabbitMQ还做不到, 不仅是RabbitMQ, ⽬前市⾯上主流的消息中间件, 都做不到这⼀点.

对于可靠性要求⽐较⾼的场景, 建议使⽤"最少⼀次", 以防⽌消息丢失. "最多⼀次" 会因为消息发送过程中, ⽹络问题, 消费出现异常等种种原因, 导致消息丢失.
以下场景可能会导致消息发送重复(包含但不限于)
 ①发送时消息重复: 当⼀条消息已被成功发送到服务端并完成持久化, 此时出现了⽹络闪断或者客⼾端宕机, 导致服务端对客⼾端应答失败. 如果此时Producer意识到消息发送失败并尝试再次发送消息, Consumer后续会收到两条内容相同并且Message ID也相同的消息.
② 投递时消息重复: 消息消费的场景下, 消息已投递到Consumer并完成业务处理, 当客⼾端给服务端反馈应答的时候⽹络闪断. 为了保证消息⾄少被消费⼀次, 云消息队列 RabbitMQ 版的服务端在将⽹络恢复后再次尝试投递之前已被处理过的消息, Consumer后续会收到两条内容相同并且Message ID也相同的消息.

但是"最少⼀次", 就会造成⼀个问题, 消费端会收到重复的消息, 也会造成对同⼀条消息进⾏多次处理. ⼀些不重要的业务还好⼀点, 对于重要的业务, 如果不对重复的消息进⾏处理, 会造成严重事故

MQ消费者的幂等性的解决⽅法, ⼀般有以下⼏种:

全局唯⼀ID
1. 为每条消息分配⼀个唯⼀标识符, ⽐如UUID或者MQ消息中的唯⼀ID,但是⼀定要保证唯⼀性.
2. 消费者收到消息后, 先⽤该id判断该消息是否已经消费过, 如果已经消费过, 则放弃处理.
3. 如果未消费过, 消费者开始消费消息, 业务处理成功后, 把唯⼀ID保存起来(数据库或Redis等)
可以使⽤Redis 的原⼦性操作setnx来保证幂等性, 将唯⼀ID作为key放到redis中 (SETNX
messageID 1) . 返回1, 说明之前没有消费过, 正常消费. 返回0, 说明这条消息之前已消费过, 抛
弃.

业务逻辑判断
在业务逻辑层⾯实现消息处理的幂等性.
例如: 通过检查数据库中是否已存在相关数据记录, 或者使⽤乐观锁机制来避免更新已被其他事务更改的数据, 再或者在处理消息之前, 先检查相关业务的状态, 确保消息对应的操作尚未执⾏, 然后才进⾏处理, 具体根据业务场景来处理

二、顺序性保障

消息的顺序性是指消费者消费的消息和⽣产者发送消息的顺序是⼀致的.(⽐如⽣产者发送的消息分别是msg1, msg2, msg3, 那么消费者也是按照msg1, msg2, msg3的顺序进⾏消费的.)

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

⼀些资料显⽰RabbitMQ的消息能够保障顺序性, 这是不严谨的. 在不考虑消息丢失, ⽹络故障等异常的情况下, 如果只有⼀个消费者, 最好也只有⼀个⽣产者的情况下, 是可以保证消息的顺序性. 如果有多个⽣产者同时发送消息, ⽆法确定消息到达RabbitMQ Broker的前后顺序, 也就⽆法验证消息的顺序性.哪些情况可能会打破RabbitMQ的顺序性呢? 下⾯介绍⼏种常⻅的场景:
1. 多个消费者: 当队列配置了多个消费者时, 消息可能会被不同的消费者并⾏处理, 从⽽导致消息处理的顺序性⽆法保证.
2. ⽹络波动或异常: 在消息传递过程中, 如果出现⽹络波动或异常, 可能会导致消息确认(ACK) 丢失, 从⽽使得消息被重新⼊队和重新消费, 造成顺序性问题.
3. 消息重试:如果消费者在处理消息后未能及时发送确认, 或者确认消息在传输过程中丢失, 那么MQ可能会认为消息未被成功消费⽽进⾏重试, 这也可能导致消息处理的顺序性问题.
4. 消息路由问题: 在复杂的路由场景中, 消息可能会根据路由键被发送到不同的队列, 从⽽⽆法保证全局的顺序性.
5. 死信队列: 消息因为某些原因(如消费端拒绝消息)被放⼊死信队列, 死信队列被消费时, ⽆法保证消息的顺序和⽣产者发送消息的顺序⼀致

顺序保障方案:

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

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

注:①在实际应⽤中, 全局顺序性很难实现, 可以考虑使⽤业务逻辑来保证顺序性, ⽐如在消息中嵌⼊序列号,并在消费端进⾏排序处理. 相对⽽⾔, 局部顺序性更常⻅, 也更容易实现.
②RabbitMQ作为⼀个分布式消息队列, 主要优化的是吞吐量和可⽤性, ⽽不是严格的顺序性保证.如 果业务场景确实需要严格的消息顺序, 可能需要在应⽤层⾯进⾏额外的设计和实现

顺序性保证的常⻅策略

1. 单队列单消费者
最简单的⽅法是使⽤单个队列, 并由单个消费者进⾏处理. 同⼀个队列中的消息是先进先出的, 这是
RabbitMQ来帮助我们保证的.
2. 分区消费
单个消费者的吞吐太低了, 当需要多个消费者以提⾼处理速度时, 可以使⽤分区消费. 把⼀个队列分割成多个分区, 每个分区由⼀个消费者处理, 以此来保持每个分区内消息的顺序性(⽐如⽤⼾修改资料后, 发送⼀条⽤⼾资料消息. 消费者在处理时, 需要保证消息发送的先后顺序,但这种场合并不需要保证全局顺序. 只需要保证同⼀个⽤⼾的消息顺序消费就可以. 这时候就可以采⽤把消费按照⼀定的规则, 分为多个区, 每个分区由⼀个消费者处理
RabbitMQ本⾝并不⽀持分区消费, 需要业务逻辑去实现, 或者借助spring-cloud-stream来实现)    3. 消息确认机制
使⽤⼿动消息确认机制, 消费者在处理完⼀条消息后, 显式地发送确认, 这样RabbitMQ才会移除并继续发送下⼀条消息.
4. 业务逻辑控制
在某些情况下, 即使消息乱序到达, 也可以在业务逻辑层⾯实现顺序控制. ⽐如通过在消息中嵌⼊序列号, 并在消费时根据这些信息来处理

三、消息挤压问题

原因分析
消息积压是指在消息队列(如RabbitMQ)中, 待处理的消息数量超过了消费者处理能⼒, 导致消息在队列中不断堆积的现象.

通常有以下⼏种原因:
1. 消息⽣产过快: 在⾼流量或者⾼负载的情况下, ⽣产者以极⾼的速率发送消息, 超过了消费者的处理能⼒.
2. 消费者处理能⼒不⾜: 消费者处理处理消息的速度跟不上消息⽣产的速度, 也会导致消息在队列中积压.
可能原因有:
1) 消费端业务逻辑复杂, 耗时⻓
2) 消费端代码性能低
3) 系统资源限制, 如CPU、内存、磁盘I/O等也会限制消费者处理消息的效率.
4) 异常处理处理不当. 消费者在处理消息时出现异常, 导致消息⽆法被正确处理和确认.
3. ⽹络问题: 因为⽹络延迟或不稳定, 消费者⽆法及时接收或确认消息, 最终导致消息积压
4. RabbitMQ 服务器配置偏低
消息积压可能会导致系统性能下降, 影响⽤⼾体验, 甚⾄导致系统崩溃. 因此, 及时发现消息积压并解决对于维护系统稳定性⾄关重要.

解决⽅案
遇到消息积压时, ⾸先要分析消息积压造成的原因. 根据原因来调整策略.
主要从以下⼏个⽅⾯来解决:
1. 提⾼消费者效率
a. 增加消费者实例数量, ⽐如新增机器
b. 优化业务逻辑, ⽐如使⽤多线程来处理业务
c. 设置prefetchCount, 当⼀个消费者阻塞时, 消息转发到其他未阻塞的消费者.
d. 消息发⽣异常时, 设置合适的重试策略, 或者转⼊到死信队列
2. 限制⽣产者速率. ⽐如流量控制, 限流算法等.
a. 流量控制: 在消息⽣产者中实现流量控制逻辑, 根据消费者处理能⼒动态调整发送速率
b. 限流: 使⽤限流⼯具, 为消息发送速率设置⼀个上限
c. 设置过期时间. 如果消息过期未消费, 可以配置死信队列, 以避免消息丢失, 并减少对主队列的压

3. 资源与配置优化. ⽐如升级RabbitMQ服务器的硬件, 调整RabbitMQ的配置参数等

相关文章:

RabbitMQ的应用问题

一、幂等性保障 幂等性是数学和计算机科学中某些运算的性质, 它们可以被多次应⽤, ⽽不会改变初始应⽤的结果 数学上的幂等性: f(x)f(f(x)) |x| 数据库操作幂等性: 数据库的 select 操作. 不同时间两次查询的结果可能不同, 但是这个操作是符合幂等性…...

C++14:通过make_index_sequence实现将tuple转换为array

如何将vector转换为array呢 #include <iostream> #include <tuple> #include <array> using namespace std;template <typename V, typename... Types, size_t... I> constexpr auto do_tuple_to_array(tuple<V, Types...>&& tuple, in…...

Linux中修改MySQL密码

Linux中MySQL的密码操作 1、给用户设置/更新密码 mysqladmin -u用户名 -p原密码 password "新密码"该命令在终端直接执行&#xff0c;不需要进入mysql视图 该命令适用于以下情况&#xff1a; 用户的密码为空&#xff0c;为用户设置密码用户密码需要更新&#xff0c…...

华为OD真题机试-英文输入法(Java)

华为OD机试真题中的“英文输入法”题目主要考察的是字符串处理、单词提取、以及基于前缀的单词联想功能。以下是对该题目的详细解析&#xff1a; 题目描述 主管期望你来实现英文输入法单词联想功能。具体需求如下&#xff1a; 依据用户输入的单词前缀&#xff0c;从已输入的…...

【React 】入门Day01 —— 从基础概念到实战应用

目录 一、React 概述 二、开发环境创建 三、JSX 基础 四、React 的事件绑定 五、React 组件基础使用 六、组件状态管理 - useState 七、组件的基础样式处理 快速入门 – React 中文文档 一、React 概述 React 是什么 由 Meta 公司开发&#xff0c;是用于构建 Web 和原生…...

2024年9月总结及随笔之丢卡

1. 回头看 日更坚持了639天。 读《软件开发安全之道&#xff1a;概率、设计与实施》更新完成读《软件设计的要素》开更并更新完成读《构建可扩展分布式系统&#xff1a;方法与实践》开更并更新完成读《数据湖仓》开更并持续更新 2023年至2024年9月底累计码字1555996字&#…...

sql语法学习 sql各种语法 sql增删改查 数据库各种操作 数据库指令

sql语法学习 sql各种语法 sql增删改查 数据库各种操作 数据库指令 学习SQL语法时&#xff0c;理解其基本结构和用法是关键。下面是SQL语法的详细学习指南&#xff0c;涵盖了SQL的主要部分&#xff0c;包括查询、插入、更新、删除、表操作等。 1. 基本查询语法 SQL 的查询语句…...

鸡兔同笼,但是线性代数

灵感来自&#xff1a;bilibili&#xff0c;巨佬&#xff01; 我们有 14 14 14 个头&#xff0c; 32 32 32 只脚&#xff0c;所有鸡和兔都没有变异&#xff0c;头和脚都完整&#xff0c;没有数错。还有什么 Bug 吗 小学奥数 假设全是鸡&#xff0c;则有 14 2 28 14 \time…...

01---java面试八股文——springboot---10题

01-你是怎么理解Spring Boot 的约定优于配置 约定优于配置是一种软件设计的范式&#xff0c;它的核心思想是减少软件开发人员对于配置项的维护&#xff0c;从而让开发人员更加聚焦在业务逻辑上。Spring Boot 就是约定优于配置这一理念下的产物&#xff0c;它类似于 Spring 框架…...

计算机毕业设计 二手图书交易系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…...

【进阶OpenCV】 (3)--SIFT特征提取

文章目录 sift特征提取一、基本原理二、特点三、代码实现1. 函数方法2. 检测图像中的关键点3. 绘制关键点4. 计算关键点描述符5. 输出特征坐标点 总结 sift特征提取 SIFT&#xff08;Scale-Invariant Feature Transform&#xff0c;尺度不变特征变换&#xff09;特征检测是一种…...

HarmonyOS/OpenHarmony Audio 实现音频录制及播放功能

关键词&#xff1a;audio、音频录制、音频播放、权限申请、文件管理 在app的开发过程中时常会遇见一些需要播放一段音频或进行语音录制的场景&#xff0c;那么本期将介绍如何利用鸿蒙 audio 模块实现音频写入和播放的功能。本次依赖的是 ohos.multimedia.audio 音频管理模块&am…...

css 中 ~ 符号、text-indent、ellipsis、ellipsis-2、text-overflow: ellipsis、::before的使用

1、~的使用直接看代码 <script setup> </script><template><div class"container"><p><a href"javascript:;">纪检委</a><a href"javascript:;">中介为</a><a href"javascript:…...

Activiti 工作流大致了解

一、什么是 Activiti 简而言之&#xff0c;就是系统的流程图&#xff0c;如&#xff1a;请假审批流程、账单审批流程等。 二、mysql与pom配置 mysql要使用jdbc:mysql://localhost:3306/activiti?autoReconnecttrue pom文件要添加关键依赖 <!--activiti核心依赖--> &…...

速盾:高防 CDN,网站安全的有力保障

在当今数字化时代&#xff0c;网站安全已成为企业和个人关注的焦点。随着网络攻击手段的不断升级&#xff0c;传统的安全防护措施已经难以满足需求。而高防 CDN&#xff08;Content Delivery Network&#xff0c;内容分发网络&#xff09;的出现&#xff0c;为网站安全提供了有…...

宝塔搭建nextcould 30docker搭建onlyoffic8.0

宝塔搭建nextcould 宝塔搭建nextcould可以参考这两个博文 我搭建的是30版本的nextcould&#xff0c;服务组件用的是下面这些&#xff0c;步骤是一样的&#xff0c;只是版本不一样而已 nginx 1.24.0 建议选择nginx&#xff0c;apache没成功。 MySQL 8.0以上都可以 php 8.2.…...

【源码+文档+调试讲解】交通信息管理系统

摘 要 智能交通信息管理系统是一种基于计算机技术的软件系统&#xff0c;旨在提高交通管理的效率和服务质量。通过该系统可以实现智能交通管理的全面管理和优化。智能交通信息管理系统具备集成管理功能。它能够整合智能交通管理的各个业务环节&#xff0c;包括个人中心、用户管…...

小阿轩yx-案例:Ansible剧本文件实践

小阿轩yx-案例&#xff1a;Ansible剧本文件实践 Playbook 介绍 什么是 playbook playbook 顾名思义&#xff0c;即剧本&#xff0c;现实生活中演员按照剧本表演在 ansible 中&#xff0c;由被控计算机表演&#xff0c;进行安装&#xff0c;部署应用&#xff0c;提供对外的服…...

【ShuQiHere】深入理解微架构(Microarchitecture):LC-3 的底层实现 ️

【ShuQiHere】&#x1f5a5;️ 微架构&#xff08;Microarchitecture&#xff09; 是计算机体系结构中的重要概念&#xff0c;它定义了如何将 指令集架构&#xff08;Instruction Set Architecture, ISA&#xff09; 转化为实际硬件。通过微架构&#xff0c;我们可以理解计算机…...

Ubuntu24.04.1系统下VideoMamba环境配置

文章目录 前言第一步&#xff1a;基本的环境创建第二步&#xff1a;causal-conv1d和mamba_ssm库的安装第三步&#xff1a;安装requirements.txt 前言 VideoMamba环境的配置折磨了我三天&#xff0c;由于Mamba对Cuda的版本有要求&#xff0c;因此配置环境的时候Cuda版本以及各种…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)

旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据&#xff01;该数据集源自2025年4月发表于《地理学报》的论文成果…...

LangChain【6】之输出解析器:结构化LLM响应的关键工具

文章目录 一 LangChain输出解析器概述1.1 什么是输出解析器&#xff1f;1.2 主要功能与工作原理1.3 常用解析器类型 二 主要输出解析器类型2.1 Pydantic/Json输出解析器2.2 结构化输出解析器2.3 列表解析器2.4 日期解析器2.5 Json输出解析器2.6 xml输出解析器 三 高级使用技巧3…...