Rocketmq如何保证消息不丢失和幂等性

生产者

生产者通过RocketMQ提供的事务消息(两阶段提交)能保证消息的一致性。
第一阶段给Broker发送一个半事务消息,半事务消息是不能消费的消息,broker已经收到生产者发送的消息,但是并未收到生产者的二次确认,所以该消息被标记为【暂不能投递】状态(即消费者不能消费这条消息);
如果Producer发送成功,则执行本地事务,如果本地事务执行成功则二次确认消息,向Broker发送commit消息,如果本地事务执行失败则发送Rollback消息给Broker。如果Producer发送半事务消息后没有收到Broker的成功响应,可能是因为网络抖动,Broker宕机(则触发重试机制,在重试后仍然失败则将该消息持久化,通过线程扫描定时发送到Broker,直到Broker恢复)。
如果由于网络抖动,生产者重启导致而消息确认失败,Broker会通过扫描发现某条消息长期处于【半事务消息】状态,就会主动向生产者发起询问查询该条消息的最终状态,默认每隔60s回查一次,回查15次还是不行,则不投递半事务消息。

Ro
事务消息发送步骤如下:

  1. 生产者将半事务消息发送至 RocketMQ Broker。
  2. RocketMQ Broker 将消息持久化成功之后,向生产者返回 Ack 确认消息已经发送成功,此时消息暂不能投递,为半事务消息。
  3. 生产者开始执行本地事务逻辑。
  4. 生产者根据本地事务执行结果向服务端提交二次确认结果(Commit或是Rollback),服务端收到确认结果后处理逻辑如下:
  • 二次确认结果为Commit:服务端将半事务消息标记为可投递,并投递给消费者。
  • 二次确认结果为Rollback:服务端将回滚事务,不会将半事务消息投递给消费者。
  1. 断网或者是生产者应用重启的特殊情况下,若服务端未收到发送者提交的二次确认结果,或服务端收到的二次确认结果为Unknown未知状态,经过固定时间后,服务端将对消息生产者即生产者集群中任一生产者实例发起消息回查。
  2. 需要注意的是,服务端仅仅会按照参数尝试指定次数,超过次数后事务会强制回滚,因此未决事务的回查时效性非常关键,需要按照业务的实际风险来设置

消费者

消费者保证不丢失和幂等性

消息幂等判断去重

消费者消费到消息后,如何保证消息的幂等,很容易想到的是通过if判断;比如用户下单,在用户支付订单后,更新订单状态同时发布一条消息到Broker,通知下游服务新增物流、更新用户积分等信息,我们就那新增物流信息为例,物流服务在消费该消息时,通过if判断物流信息表中是否存在相同的物流id,不存在则正常消费,存在则直接return,不重复消费。

if(null != xxxMapper.selectById(id)) {return "success";
}
// todo 消费逻辑
问题分析

该方案非常简单,但是在大量并发和复杂的网络环境下,如果细节没有处理好会有很多漏洞。

  • 并发情况下如果网络抖动导致消息重复消费,在第一条消息没有消费完成,重复的消息又执行这个if判断会导致主键冲突异常
  • 在业务层面重复消费可能导致库存扣减两倍,用户积分也会新增两倍。
锁机制+事务去重
  • 在新增信息的表中,做好主键冲突的异常捕获处理
  • 将xxxMapper.selectById(id)的select语句使用for update和消费逻辑使用事务处理。
    这样虽然能保证消息不会重复消费,但是牺牲了很大的性能开销,因为消费消息逻辑被整个事务包裹而导致处理时间被延长。并且还增加了整个系统的复杂度,因为还有其他业务需要消费消息,其实我们还可以继续思考,引入所有业务更加通用的方案。
本地事务消息表

引入一张非业务的消息表,记录消息消费的状态,状态包括两种:消费中/已消费。将它与其他业务绑定在一起作为一个本地事务,大致逻辑如下:

  • 开启事务
  • 插入消息表
  • 处理其他业务(比如:新增物流,更新积分,更新库存信息)
  • 提交/回滚事务

虽然他没有对数据库记录加锁,但是他还是使用事务,有事务就会延长消费时间

去事务的本地消息表解决方案

利用消息表的消息状态作为基础条件,

  • 消费者消费首先插入消息去重表,
  • 插入成功,则继续执行消费逻辑:
    • 消费失败,则删除消息表,延迟继续消费
    • 消费成功,则更新消息表消息状态为已消费
  • 插入失败分为两种情况:
    • 消息如果在消费中,则延迟继续消费;
    • 消息如果已经消费,返回消费成功

特别注意:延迟继续消费的消息需要判断消费时长,或者消费次数,达到消费上限则告警,或者投递到死信Topic中。

代码和方案持续优化更新中。。。

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

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

相关文章

JavaScript使用 BigInt

在 JavaScript 中,最大的安全整数是 2 的 53 次方减 1,即 Number.MAX_SAFE_INTEGER,其值为 9007199254740991。这是因为 JavaScript 中使用双精度浮点数表示数字,双精度浮点数的符号位占 1 位,指数位占 11 位&#xff…

2024C题生物质和煤共热解问题的研究 详细思路

背景 随着全球能源需求的不断增长和对可再生能源的追求,生物质和煤共热解作为一种潜在的能源转化技术备受关注。生物质是指可再生能源,源自植物和动物的有机物质,而煤则是一种化石燃料。** 在共热解过程中,生物质和煤在高温和缺氧…

unity基础(二)

debug方法 Debug.Log(" 一般日志 ");Debug.LogWarning(" 警告日志 ");Debug.LogError(" 错误日志 ");// Player Informationstring strPlayerName "Peter";int iPlayerHpValue 32500;short shPlayerLevel 10;long lAdvantureExp 1…

越秀城投·星汇城 | 看得再多,都不如实景现房更安心

对于大多数家庭而言,买房是人生大事。经历了前几年房企暴雷、楼盘停工烂尾的风波,“现房”成为买房人心中最安心的代名词。无需再等待,所见即所得。 越秀城投星汇城位于平度南部新城核芯片区,不仅享受区域发展的利好,…

vs2019 里 C++ 20规范的 string 类的源码注释

(1)读源码,可以让我们更好的使用这个类,掌握这个类,知道咱们使用了库代码以后,程序大致具体是怎么执行的。而不用担心程序出不知名的意外的问题。也便于随后的代码调试。 string 类实际是 库中 basic_strin…

基于JAVAEE的停车场管理系统(论文 + 源码)

【免费】基于JAVAEE的停车场管理系统.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89292324 基于JAVAEE的停车场管理系统 摘 要 如今,我国现代化发展迅速,人口比例急剧上升,在一些大型的商场,显得就格外拥挤&…

每日两题 / 24. 两两交换链表中的节点 25. K 个一组翻转链表(LeetCode热题100)

24. 两两交换链表中的节点 - 力扣(LeetCode) 定义三个指针,交换前先保存ntnt指针为next->next,cur和next两个节点,然后将pre->next指向next 若pre为空,说明当前交换的节点为头两个节点,…

VM虚拟机安装调试(步骤如下图)

VM虚拟机安装调试 随着一顿安装操作,还有enter键敲下,出现如下界面。

实现MYSQL8.3.0 版本流量抓取

实现MYSQL8.3.0 版本流量抓取 根据测试需求,需要抓取MYSQL8.3.0流量包,使用wireshark 数据库客户端实现 安装数据库服务端 这里就不给详细操作方法, 网上教程一大堆,小编这里是最新的MYSQL 8.3.0版本 安装成功后,创…

Omnity 进展月报 | 2024.4.1-4.30

Omnity 大事摘要 1、Octopus 官宣升级为 Omnity。 2、Omnity 4月28号正式上线,实现BTC 和 ICP 之间跨链转账 Runes 资产。 3、为庆祝上线,以符文 HOPE•YOU•GET•RICH 为资产,发红包快速触达大量用户,体验跨链服务。 4、Omni…

【前端】前端数据本地化的多种实现方式及其优劣对比

前端数据本地化的多种实现方式及其优劣对比 在现代Web开发中,提高页面响应速度和改善用户体验是核心目标之一。数据本地化是其中一种实现方式,它通过在客户端存储数据来减少服务器请求,从而加快数据载入速度和改善用户的体验。本文将介绍前端…

26、Qt使用QFontDatabase类加载ttf文件更改图标颜色

一、图标下载 iconfont-阿里巴巴矢量图标库 点击上面的链接,在打开的网页中搜索自己要使用的图标,如:最大化 找到一个自己想用图标,选择“添加入库” 点击“购物车”图标 能看到刚才添加的图标,点击“下载代码”(需要…

4000字超详解Linux权限

各位大佬好 ,这里是阿川的博客 , 祝您变得更强 个人主页:在线OJ的阿川 大佬的支持和鼓励,将是我成长路上最大的动力 阿川水平有限,如有错误,欢迎大佬指正 在Linux当中权限的体现主要有两种 普通用户 超…

图片无损压缩工具-VIKY

一、前言 Viky v3.4是一款功能强大的图片压缩工具,它能够提供高效的图片无损压缩服务。通过使用独特的压缩算法,该软件在显著减小图片文件大小的同时,还保持了图像的清晰度和色彩饱和度,确保了图像质量的优异表现。 二、软件特点…

CAPL如何实现TLS握手认证

CAPL有专门的章节介绍如何实现TLS握手认证的函数: CAPL调用哪些函数实现TLS握手认证,需要了解TLS在整个通信过程的哪个阶段。 首先TCP需要建立连接,这是TLS握手的前提。当TLS握手认证完成后,可以传输数据。 所以TLS握手开始前需要确保TCP建立连接,TCP传输数据前需要确保…

泰迪科技2024中职大数据实训室方案解读

中职在大数据专业建设所遇到的困难 数据、信息安全、人工智能等新信息技术产业发展迅猛,人才极其匮乏,各个中职院校纷纷开设相应的专业方向。但是,绝大多数院校因为师资和积累问题,在专业建设规划、办学特色提炼、创新教学模…

Gradio 基础使用示例

文章目录 Gradio 基础使用示例简介安装示例-简单的输入、输出示例-启动配置示例-聊天对话示例-多页面Tab切换示例-使用Block自定义布局示例-Plot绘图示例-状态管理示例-提示、进度条参考 Gradio 基础使用示例 简介 Gradio 是一个用于构建快速原型和部署机器学习应用程序的开源…

wandb: - 0.000 MB of 0.011 MB uploaded持续出现的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

【异常检测】新版异常检测库anomalib的使用

every blog every motto: There’s only one corner of the universe you can be sure of improving, and that’s your own self. https://blog.csdn.net/weixin_39190382?spm1010.2135.3001.5343 0. 前言 异常检测库anomalib的使用 1. 前提 1.1 数据组织形式 说明&#…

15 华三华为链路聚合综述

1 链路聚合简介 以太网链路聚合通过将多条以太网物理链路捆绑在一起形成一条以太网逻辑链路,实现增加链路带宽的目的,同时这些捆绑在一起的链路通过相互动态备份,可以有效地提高链路的可靠性。 2 成员端口的状态 聚合组内的成员端口具有以下…