Rabbitmq消息重复消费问题(幂等性保障)

消息百分百投递架构

在《消息可靠性保证》篇章中,我通过生产者确认机制保障了消息会发送到MQ中,但是在生产者与MQ建立过程的时候出现了网络抖动,连接建立失败,生产者就感知不到MQ返回的ack/nack,无法完全保障消息投递到MQ中,因此这里介绍如何保障生产者百分百将消息投递到MQ。
消息百分百投递架构图

  • step1:首先把消息信息(业务数据)存储到数据库中,紧接着,我们再把这个消息记录也给存储到一张消息记录表中,并且在消息记录表中指定一个状态字段status来记录消息的投递状态。将status设为0,表示还未被投递
  • step2:发送消息给MQ Broker节点(采用Confirm确认机制发送消息,会有异步的返回结果)
  • step3,4:生产者端接收MQ Broker节点返回的Confirm确认消息结果,然后进行更新消息记录表中的消息状态。将status设为1,表示投递成功
  • step5:但是在消息确认这个过程中可能出现网络抖动,MQ Broker端异常等原因导致 返回消息失败,这个时候需要生产者对消息进行可靠性投递,保障消息不丢失。所以我们需要一个定时任务(比如每1分钟拉取一些消息的状态信息,当然这个消息也可以设置一个超时时间,比如超过1分钟status=0,也就说明1分钟内,该消息没有被投递成功,那么就会被定时任务拉取出来)
  • step6:接下来我们把status=0的消息进行重新投递 retry send
  • step7:我们可以设置最大重试次数,比如投递3次还是失败,就可以把该消息的状态status标记为2,交给人工解决(或者把这些记录到一张失败表中)

通过以上步骤就能保障消息的百分百投递成功!!!

引出重复消费问题

image.png
step2 网络抖动没有投递成功,并不会照成重复消费问题,因为消息并没有投递到MQ中。而step3 此时MQ已经接收到该消息,返回ack时出现网络抖动,导致生产者接收不到MQ返回的ack,就误以为没有投递成功,将消息又重新投递一遍。造成消费者重复消费!!!

解决重复消费问题

解决消息重复消费问题,需要在消费端考虑消息的幂等性。

幂等性:对一个接口调用一次和调用多次得到的结果是一样的

解决方案有两套

  1. 使用数据库的唯一约束
  2. 使用redis的setnx

使用数据库的唯一约束保证幂等性

单体架构

单体架构


分布式

使用雪花算法、Tinyid 等生成唯一ID给消息标识和指纹码,消息入库时作为主键进行保存,因此保证消息唯一性
优点:实现简单
缺点:
1、高并发业务下游数据库有写入性能瓶颈
2、需要
本地ID生成服务,确保外部统一生成ID服务
无法使用时可以进行兜底
**解决方案:**数据库进行分库分表,对消息ID使用算法解析路由到不同的数据库中
唯一ID+指纹码方案架构

Redis原子性

利用redis的setnx命令,天然具有幂等性,从而实现不重复消费
**优点:**性能高,AOF模式数据不丢失
缺点:
1. 数据同步入库需要考虑到数据库和Redis之间的原子性
2. 消息不同步入库,Redis定时同步到数据库的策略需要具体设计

**
**

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

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

相关文章

modbus 通信协议介绍与我的测试经验分享

1、简介 Modbus 协议是一种通信协议,用于工业自动化系统中的设备间通信。该协议最初由 Modicon 公司开发,并于 1979 年发布。 Modbus 协议通过串行通信格式进行通信,在物理层上支持 RS-232、RS-422 和 RS-485 等多种通信方式。在协议层面&am…

Kotlin ArrayList类型toTypedArray转换Array

Kotlin ArrayList类型toTypedArray转换Array data class Point(val x: Float, val y: Float)fun array_test(points: ArrayList<Array<Point>>) {points.forEachIndexed { idx, ap ->ap.forEach {print("$idx $it ")}println()} }fun main(args: Arra…

verilog语法进阶-分布式ram原语

概述 官方提供的原语 RAM16X1S_1 #(.INIT(16h0000) // Initial contents of RAM) RAM16X1S_1_inst (.O(O), // RAM output.A0(A0), // RAM address[0] input.A1(A1), // RAM address[1] input.A2(A2), // RAM address[2] input.A3(A3), // RAM address[3…

pytest之allure测试报告02:allure具体使用方法

一、allure包含的方法 二、allure使用教程 &#xff08;1&#xff09;用例中写入allure方法 allure.epic("数据进制项目epic") allure.feature("手机号模块feature") class TestMobile:allure.story("杭州的手机号story")allure.title("测…

Selenium安装WebDriver:ChromeDriver与谷歌浏览器版本快速匹配_最新版120

最近在使用通过selenium操作Chrome浏览器时&#xff0c;安装中遇到了Chrome版本与浏览器驱动不匹配的的问题&#xff0c;在此记录安装下过程&#xff0c;如何快速找到与谷歌浏览器相匹配的ChromeDriver驱动版本。 1. 确定Chrome版本 我们首先确定自己的Chrome版本 Chrome设置…

如何从众多知识付费平台中正确选择属于自己的平台(明理信息科技知识付费平台)

在当今的知识付费市场中&#xff0c;用户面临的选择越来越多&#xff0c;如何从众多知识付费平台中正确选择属于自己的平台呢&#xff1f;下面&#xff0c;我们将为您介绍明理信息科技知识付费平台相比同行的优势&#xff0c;帮助您做出明智的选择。 一、创新的技术架构&#…

【linux】Debian不能运行sudo的解决

一、问题&#xff1a; sudo: 没有找到有效的 sudoers 资源&#xff0c;退出 sudo: 初始化审计插件 sudoers_audit 出错 二、可用的方法&#xff1a; 出现 "sudo: 没有找到有效的 sudoers 资源&#xff0c;退出" 和 "sudo: 初始化审计插件 sudoers_audit 出错&q…

IDEA中alt enter不显示创建实现类快捷键

alt enter不显示创建实现类快捷键是因为idea中的设置没打开&#xff0c;按照一下设置打开就可以了。 点击setting-->>editor-->>intentions-->>java下的declaration 如下图所示&#xff1a;

【C++干货铺】继承后的多态 | 抽象类

个人主页点击直达&#xff1a;小白不是程序媛 C系列专栏&#xff1a;C干货铺 代码仓库&#xff1a;Gitee 目录 多态的概念 多态的定义和实现 多态的定义条件 虚函数 虚函数的重写 特殊情况 协变&#xff08;基类和派生类的虚函数返回值不同&#xff09; 析构函数的重…

深度学习中的预测图片中的矩形框、标签、置信度分别是什么意思。

问题描述&#xff1a;深度学习中的预测图片中的矩形框、标签、置信度分别是什么意思。 问题解答&#xff1a; 目标框&#xff08;Bounding Box&#xff09;&#xff1a; 描述目标位置的矩形边界框。 类别标签&#xff1a; 表示模型认为目标属于哪个类别&#xff08;例如&#…

【Java JVM】实例对象内存布局

当 Java 应用启动后, 基本就是在不断的创建对象, 回收对象的过程中。 而这些创建的对象基本都是存放在应用的堆 (heap) 中, 但是这些对象在堆中又是什么样子的呢? 在这篇文章中, 我们分析一下 Java JVM 中实例对象的内存布局。 在 HotSpot 虚拟机里, 对象在堆内存中的存储布局…

结构体基础全家桶(2)结构体指针

目录 指向结构体类型数据的指针&#xff1a; 指向结构体变量的指针&#xff1a; 创建&#xff1a; 应用&#xff1a; 注意事项&#xff1a; 指向结构体数组的指针 创建&#xff1a; 应用&#xff1a; 注意&#xff1a; 用结构体变量和指向结构体的指针做函数的参数 …

eNSP小实验---(简单混合)

实验目的&#xff1a;实现vlan10 vlan20 172网段用户互访 1.拓扑图 2.配置 PC1 其它同理 SW4 <Huawei> <Huawei>u t m Info: Current terminal monitor is off. <Huawei>sys <Huawei>sys Enter system view, return user view with CtrlZ. [Hua…

深度学习小白学习路线规划

作为深度学习的初学者&#xff0c;以下是一个建议的学习路线&#xff0c;可以帮助你逐步掌握图像分类、目标检测与跟踪、实例分割和姿态估计&#xff1a; 掌握这些&#xff0c;计算机视觉算是入门了&#xff01; 1. 基础知识&#xff1a; 学习Python编程语言&#xff0c;它是…

当在VMware Workstation Pro 中查询不到ens33网卡的IP

在学习中我们经常要去查询ens33的IP&#xff0c;但是有时候会查询不到&#xff0c;今天就遇到了这样的问题并且找到了解决方法 记录一下 ip a 查询不到IP 显示代码为 ens33: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether …

[论文笔记] GAMMA: A Graph Pattern Mining Framework for Large Graphs on GPU

GAMMA: A Graph Pattern Mining Framework for Large Graphs on GPU GAMMA: 基于 GPU 的针对大型图的图模式挖掘框架 [Paper] [Code] ICDE’23 摘要 提出了一个基于 GPU 的核外(out-of-core) 图模式挖掘框架(Graph Pattern Mining, GPM) GAMMA, 充分利用主机内存来处理大型图…

〖大前端 - 基础入门三大核心之JS篇(55)〗- 内置对象

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;哈哥撩编程&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xff0c;目前在公司…

如何禁止孩子在电脑中浏览某些网页?

在使用电脑的过程中&#xff0c;我们会使用浏览器来查看网页。而在孩子使用电脑的过程中&#xff0c;有些网页并不适合孩子查看。因此&#xff0c;我们需要禁止孩子浏览不健康的网页。那么&#xff0c;该如何禁止孩子在电脑中浏览某些网页呢&#xff1f; 定时关机3000简介 定时…

QML 自定义进度条组件开发

一、效果预览 二、介绍&#xff1a; 自定义的QML 屏幕亮度拖动进度条组件CusProgressBar 可跟鼠标移动 更改进度条样式 三、代码 import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Controls.Material 2.12/***author:Zwj*csdn:来份煎蛋吧*date:2023/12/16*…

如何禁止服务器自动休眠

如何禁止服务器自动休眠 有时候服务器自己休眠&#xff0c;导致系统web站点无法访问&#xff0c;下面是解决办法&#xff01; 禁止服务器自动进入休眠状态的具体方法可能会因使用的Linux发行版而有所不同。以下是一些通用的方法&#xff0c;你可以根据你的系统选择适用的&#…