RabbitMQ 第二天 高级 8 RabbitMQ 应用问题

news2024/11/15 23:47:38

RabbitMQ

【黑马程序员RabbitMQ全套教程,rabbitmq消息中间件到实战】

文章目录

      • RabbitMQ
      • 第二天 高级
      • 8 RabbitMQ 应用问题
        • 8.1 消息可靠性保障
          • 8.1.1 消息补偿
        • 8.2 消息幂等性保障
          • 8.2.1 乐观锁机制

第二天 高级

8 RabbitMQ 应用问题

8.1 消息可靠性保障

在RabbitMQ的使用过程中我们如何保证消息百分百从生产端发送到服务端呢,在淘宝,银行等系统中是不允许任何错误的,任何消息的不可达都可能会造成巨大的损失。

我们通过发送端消息确认机制confirm机制和return机制确保消息能发送出去,通过接收端的Acknowledge (ACK)确保队列中的消息被处理了,但是如果保证发送的完整链上的消息被处理了,比如服务端发送成功后,接收端尚未接收,队列重启了,消息丢失。

8.1.1 消息补偿

【一个需求】100%确保消息发送成功

示意图

在这里插入图片描述

这个图看起来好像很复杂,其实只做到了三件事情:

发消息
收到消息确认
检查比对是不是收到消息了

  1. 当发生业务操作的时候,业务数据写入数据库

  2. 生产者将消息发送给MQ的队列Q1

  3. 发送了一条与step2中一摸一样的延迟消息给Q3

  4. Consumer监听Q1,获取到了step2中发送的业务消息

  5. 消费者在收到生产者的业务消息后,发送了一条确认消息(记录收到的消息信息)到Q2

  6. 回调检查服务监听了Q2,获取到了消费者发送的确认消息

  7. 回调检查服务将这条确认消息写入数据库等待之后的比对

  8. Q3中的延迟消息延迟时间已到,被回调检查服务接收到,之后就拿着这条延迟消息在数据库中比对,如果比对成功,证明消费者接收到了生产者的业务消息并处理成功(如果不处理成功谁会傻了吧唧发送确认消息呢);如果比对失败,证明消费者没有接收到生产者的业务消息,或者说消费者接收到了业务消息之后始终没有处理成功相关的业务并发送确认消息。这时回调检查服务就会调用生产者的相关业务接口,让生产者再次发送这条失败的消息

  9. 有一种最极端的情况,step2和step3的消息都发送失败了或者说在消息传递过程中发生意外丢失了!定时检查服务会一直轮询保存确认消息的数据库中的消息数据,并于生产者的业务数据库中的业务数据进行比对,如果两者比对数量一致,则代表业务执行没有问题;如果比对不一致,确认消息数据库的数据量小于生产者业务数据量的话,就证明消费者没有接收到生产者发送的消息。这时定时检查服务会通知生产者再次发送消息到MQ的队列Q1

核心思想是定时任务进行核对

  1. 业务数据入库
    • 在发送消息前,先将消息入库
  2. 发送消息
    • 发送消息m到消息队列Q1,Consumer监听到Q1的消息m后,消费消息m,并将消息m入库。然后发送确认消息给Q2,回调检查服务监听到Consumer反馈的确认消息后,也将消息写入数据库MDB。这是消息发送成功的正常情况。

倘若:发送消息失败,那么Consumer消费不到消息,Consumer的消息入库操作也失败了。这时也不用担心,因为在我们发送消息m后,过了几分钟后也会进行延迟发送消息m的副本给Q3,回调检查服务监听到延迟消息后,与MDB中的进行比对,MDB中没有消息m的记录,这说明Consumer消费消息m失败,那么回调检查服务就远程调用Producer跟它说一下再重发消息m,又重新进行上面消息发送的步骤。

几率很小的发送消息失败情况:

发送消息失败,延迟发送消息也失败。。。
这时定时检查服务会将消息数据库MDB中与业务数据库DB进行比对,然后让producer重发缺失的消息。

当消息从生产者发出的时候,首先在要发送的业务数据写到生产者的数据库,然后将消息发送到消息队列,如果消费者接受到了消息就进行消费并且写入数据库,同时返回一个确认消息,回调检查服务将确认消息写入数据库,如果此时生产者发送了一个延迟消息与上一次发送给消费者的消息是一样的,并且消费者成功消费了,那么回调检查服务就会通过监听延迟消息的id与自己的数据库中的消息进行对比,如果存在一样的id,就会知道生产者的这条消息已经消费过了,如果回调检查服务发现这个消息没有被消费者成功消费,那么就会通过远程调用告诉生成者需要重新发送这条消息给消费者。

还有一种情况是生产者发送消息失败,延迟发送的消息也失败了,这个时候rabbitmq就会通过定时检查服务,通过一定的时间检查消息数据库与生产者的数据库进行对比,发现与生成者的数据不一致,匹配不成功,就会通过远程调用告诉生产者需要重新发送数据不一致的消息。

真淦啊 【大概了解下这个方案 吧】

8.2 消息幂等性保障

幂等性指一次和多次请求某一个资源,对于资源本身应该具有同样的结果。

也就是说,其任意多次执行对资源本身所产生的影响均与一次执行的影响相同。

在MQ中指,消费多条相同的消息,得到与消费该消息一次相同的结果。

首先,无论是RabbitMQ、RocketMQ还是kafka,都有可能出现消息的重复发送,这个是MQ无法保障的,而幂等性是开发或者运维人员需要保证的。

所谓消息的幂等性是指即使收到多次消息,也不会重复消费,这点很重要,例如用户付钱,点的太快了,付了多次,但是你也只能扣一次钱。

比如说转账案例:我第一次通过手机银行发送的转账500申请由于网络或者说银行系统负载高等原因,导致没有执行成功,我个人又点了很多次转账的按钮,但是银行的系统必须保证我只转出去了500。

8.2.1 乐观锁机制

在这里插入图片描述

通过每次消息中带有的version信息,来判断该业务操作是否能执行成功:

针对每个操作,会生成一个唯一的id,并且携带version=1,那么通过数据库的乐观锁操作,如果重复入库的话,会无效,这样就实现了幂等性,避免重复处理相同的数据。

【比如】

用户付款500后,发送一条扣款500的消息到mq,但是由于网络什么各种原因,Consumer没有消费到消息便让Producer再发一条,此时Q1中还存在着未被消费的和重发的那一条消息,这时Consumer在来正常消费,就消费了两次同样的消息,扣了用户1000,用户表示【很无语】

可以使用数据库的乐观锁来解决这个问题。第一次发送的消息中version字段作为条件,在Consumer消费掉第一条消息完毕后将库中的version+1,这样重复的第二条消息的version字段值就不匹配,sql也就不会执行,也就不会重复消费了。

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

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

相关文章

pytorch【线性回归】【逻辑回归】【softmax回归】

文章目录零、前置函数线性相乘均方误差损失函数梯度下降函数数据的生成函数一、线性回归1.手动实现线性回归2.调库实现线性回归1.定义我们线性回归的模型2.定义我们的误差函数3.定义优化方法4.模型的训练5.开始训练6.查看模型的参数7.计算我们模型的当前的均方误差二、逻辑回归…

【5G RLC】AM模式的数据传输详解

博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客…

Linux内核死锁检测工具——Lockdep

文章目录前言配置内核简单的AB-BA死锁案例实际项目中的死锁前言 死锁是指两个或多个进程因争夺资源而造成的互相等待的现象,如进程A需要资源X,进程B需要资源Y,而双方都掌握对方所需要的资源,且都不释放,这会导致死锁。…

【圣诞快乐】如何用代码画一颗圣诞树?

文章目录一、前言二、创意角度三、java swing版 效果展示四、java swing版 实现步骤&代码五、springboot项目banner版 效果展示六、springboot项目banner版 实现步骤七、 linux shell界面打印版 效果展示八、 linux shell界面打印版 实现步骤一、前言 一年一度的圣诞节来了…

Allegro如何设置差分对内等长规则

Allegro如何设置差分对内等长规则 Allegro上可以对差分网络设置对内等长规则,方便把P/N网络进行等长处理,以下面这对USB为例 具体操作如下 打开Constraint Manage找到这对USB网络

vue3 antd table表格的样式修改(一)调整table表格每行(row)行高过高问题

vue3 antd项目实战——修改ant design vue table组件的默认样式(调整每行行高)知识调用场景复现实际操作解决a-table表格padding过宽知识调用 文章中可能会用到的知识链接vue3ant design vuets实战【ant-design-vue组件库引入】css样式穿透(…

RV1126笔记十三:实现RTMP多路拉流

若该文为原创文章,转载请注明原文出处。 一、介绍 通过RV1126实现RTMP的多路拉流,并在屏幕上显示出来,这里涉及到ffmpeg几个重要知识点,和RV1126如何在屏幕分屏显示。 二、流程图 流程和单路拉流类似,这里只是涉及拉取后的图像需要解码缩放,在合成分屏显示出来。 具体…

【完整】分类模型中类别不均衡问题解决

目录 1. 数据类别不均衡问题 2. 解决办法 过采样: 欠采样: ensemble 方法: 修改损失函数: 梯度调和机制: Dice Loss: 标签平滑: 3. 类别不均衡问题loss设计 4. 梯度调和机制GHM Gradi…

Graphviz安装向导

目录 1、首先在官网下载graphviz 2、安装。 3、测试 1、首先在官网下载graphviz 下载网址:Download | Graphviz 根据自身电脑位数选择合适的下载地址 2、安装。 打开第一步已经下载好的软件。点击下一步,在安装路径选择时可将安装路径修改为 E:\G…

JavaScript:栈的封装及十进制转二进制栈方法实现案例

栈的定义&#xff1a;是只允许在一端进行插入或删除的线性表。首先栈是一种线性表&#xff0c;但限定这种线性表只能在某一端进行插入和删除操作。 JavaScript中对栈的封装 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8&qu…

微信HOOK 协议接口 实战开发篇 2.好友列表与二叉树

前言&#xff1a;由于篇幅所限&#xff0c;文章无法详细到每个步骤&#xff0c;仅能写出关键的HOOK思路 好友列表 好友和群列表在汇编代码中有固定的常量保存 如图示&#xff0c;找到常量&#xff0c;回车进入 入口地址结构为 其指针内部便是我们需要的数据 群列表 搜索Ch…

Linux中的进程状态

目录 一、冯诺伊曼体系结构​编辑 关于冯诺依曼&#xff0c;必须强调几点&#xff1a; 二、操作系统 1、概念 2、操作系统的作用 3、本质 4、总结 5、系统调用和库函数概念 三、进程 1、基本概念 2、描述进程 3、task_struct 4、查看进程 5、通过系统调用获取进程…

第19章 随机变量

第19章 随机变量 19.1随机变量示例 定义19.1.1&#xff1a;概率空间上的随机变量R是域等于样本空间的全函数。 R的陪域可以是任何东西&#xff0c;但通常是实数的一个子集。 例&#xff1a; 例如&#xff0c;假设我们抛三个独立的、公平的硬币。令C表示正面朝上的次数。如…

js中的JSON的简单用法

目录 1.JSON说明 2.JSON.stringify 3.JSON.parse 4.示例 1.JSON说明 当数据在浏览器与服务器之间进行交换时&#xff0c;这些数据只能是文本&#xff0c;JSON 属于文本并且我们能够把任何 JavaScript 对象转换为 JSON&#xff0c;然后将 JSON 发送到服务器。我们也能把从服…

最强docker部署模板

00.背景 最近学校让一个小组做一个web项目最后部署到linux服务器上&#xff0c;项目本身并不难就是简单的增删改查&#xff0c;但是我想借着这个机会写一个docker部署的模板&#xff0c;方便自己以后用&#xff0c;也希望可以帮助到大家。 01.docker简介 docker可以快捷 轻量…

Redis原理篇—网络模型

Redis原理篇—网络模型 笔记整理自 b站_黑马程序员Redis入门到实战教程 用户空间和内核态空间 服务器大多都采用 Linux 系统&#xff0c;这里我们以 Linux 为例来讲解: ubuntu 和 Centos 都是 Linux 的发行版&#xff0c;发行版可以看成对 Linux 包了一层壳&#xff0c;任何 …

第八章:数据库编程

一、嵌入式、过程化SQL、存储过程和函数 1、【单选题】 下表为oracle数据库表cj.temp_20221106的数据。建立存储过程: CREATE OR REPLACE PROCEDURE proc_temp_20221106(i INT) IS CURSOR c_temp IS SELECT * FROM cj.temp_20221106; ROW_NR c_temp%ROWTYPE; i_count …

【Linux】基础IO——系统文件IOfd重定向理解

文章目录一、回顾C文件接口1.打开和关闭2.读写文件3.细节二、系统文件I/O 1.open和closeumask小细节2.read和write1.write2.read3.小总结三、理解文件四、文件描述符fd1.引入2.理解3.分配规则4.close(1)问题五、重定向1.重定向2.接口3.追加重定向4.输入重定向六、Linux一切皆文…

信息技术 定义内涵

工作流运行 定义内涵 工作流运行是工作流模板的依次执行&#xff0c;在工作流运行时&#xff0c;用户可以随时取消或查看正在 运行的任务。由于工作流运行的模板的不同&#xff0c;运行过程中可能会产生不同的新资源&#xff0c;如数据 处理类型的工作流会产生新的数据集&…

Java框架精品项目【用于个人学习】

难度系数说明&#xff1a; 难度系数用来说明项目本身进行分析设计的难度 难度系数大于1的项目可用作参赛作品、大作业、计算机毕业设计等需求 前言 大家好&#xff0c;我是二哈喇子&#xff0c;此博文整理了各种项目需求&#xff0c;用于博主自己学习&#xff0c;当做个人笔记…