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

news2024/11/24 0:32:10

生产者

生产者通过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.coloradmin.cn/o/1660857.html

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

相关文章

网络编程--tcp三次握手四次挥手

1、三次握手 (1)三次握手的详述 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了。…

【计算机毕业设计】springboot果蔬种植销售一体化服务平台

伴随着我国社会的发展,人民生活质量日益提高。于是对果蔬种植销售一体化服务管理进行规范而严格是十分有必要的,所以许许多多的 信息管理系统应运而生。此时单靠人力应对这些事务就显得有些力不从心了。所以本论文将设计一套果蔬种植销售一体化服务平台&…

【LLM 论文】Chain-of-Verification:通过验证链来减少 LLM 幻觉

论文:Chain-of-Verification Reduces Hallucination in Large Language Models ⭐⭐⭐ arXiv:2309.11495 论文速读 LLM 由于不可避免地会产生幻觉,现有的研究主要鼓励 LLM 在产生 response 之前生成内部思想的推理链,或者通过 self-critique…

FreeRTOS任务调度器

目录 1、什么是任务调度器 2、FreeRTOS中的任务调度器 2.1 抢占式调度 2.2 时间片调度 2.3 协作式调度 3、任务调度案例分析 3.1 实验需求 3.2 CubeMX配置 3.3 代码实现 3.3.1 uart.c 重定向printf 3.3.2 打开freertos.c并添加代码 3.3.4 代码现象 1、什么是任务调度…

苹果电脑免费第三方软件CleanMyMac X2025电脑版垃圾清理软件神器

Mac电脑用户在长时间使用电脑之后,时常会看到“暂存盘已满”的提示,这无疑会给后续的电脑使用带来烦恼,那么苹果电脑暂存盘已满怎么清理呢,下面将给大家带来一些干货帮你更好地解决这个问题。 CleanMyMac X2024全新版下载如下: h…

【C++】list的使用与模拟实现

🔥个人主页:北辰水墨 🔥专栏:C学习仓 本节内容我们来讲解list的使用和模拟实现。 本节难点:list迭代器的模拟实现。 一、list的介绍: 列表 列表是一种序列容器,允许在序列的任何位置进行时间复…

winform植物大战僵尸

winform植物大战僵尸 植物大战僵尸源码 半成品 需要的拿去学习 登陆注册选择关卡 向日葵 豌豆射手 双枪豌豆射手 项目获取: 项目获取:typora: typora/img (gitee.com) 备用项目获取链接1:yifeiyixiang/kamo: 源码下载 (github.com) 备用…

Python图形复刻——绘制母亲节花束

各位小伙伴,好久不见,今天学习用Python绘制花束。 有一种爱,不求回报,有一种情,无私奉献,这就是母爱。祝天下妈妈节日快乐,幸福永远! 图形展示: 代码展示: …

一定行:从零起步进入Java世界

郑重声明:本篇博客唯一目的就是带你从零起步,成功编写并运行你的第一个Java应用。 零:先给祖师爷来上柱香 Java之父简介 英文名:James Gosling中文名:詹姆斯高斯林祖籍:加拿大出生年:1955照片…

INS 论文分享:一种用于交通流预测的多通道时空Transformer模型

本文主要介绍了我们在长期交通流预测方面的最新研究成果,该成果已发表在信息学领域的顶级期刊《Information Sciences》上,论文题目为《A Multi-Channel Spatial-Temporal Transformer Model for Traffic Flow Forecasting》。该论文的第一作者及通讯作者…

Android项目转为鸿蒙,真就这么简单?

最近做了一个有关Android转换成鸿蒙的项目。经不少开发者的反馈;许多公司的业务都增加了鸿蒙板块。 对此想分享一下这个项目转换的流程结构,希望能够给大家在工作中带来一些帮助。转换流程示意图如下: 下面我就给大家介绍,Android…

Android 屏幕适配全攻略(上)-掌握屏幕单位,应对千变万化的设备

本文从 Android 开发中常见的长度单位 px、dp、sp 入手,详细介绍了它们的特点及转换关系。 接着深入探讨了屏幕尺寸、分辨率、像素密度等重要的屏幕指标,帮助读者全面理解它们之间的联系。最后,通过实例代码演示了如何在代码中进行单位转换&…

UE4\UE5 调试源代码流程(重点讲不去Github装源代码情况)

UE4\UE5 调试源代码流程 前言: 很多写UE C代码的小伙伴,肯定发现了,在虚幻源代码里面是没办法打断点进行调试的,就算走Debug调试流程,也依旧不能正常打断点调试,今天我们来分享一下不装Github源代码情况下…

Python语言基础学习(上)

目录 一、常量和表达式 二、变量和类型 2.1 认识变量 2.2 定义变量 2.3 变量类型 1、整数 int 2、浮点数(小数)float 3、字符串 str 4、布尔类型 2.4 类型转换 三、注释 3.1 单行注释 3.2 文档注释(或者多行注释) …

五金建材微信小程序商城系统开发搭建指南

如今,随着移动互联网的发展,小程序成为了商家们开拓新市场、增加收益的重要途径。特别是对于五金店这类实体店铺来说,通过小程序开设线上商城,不仅可以提升品牌影响力,还能够实现线上线下的无缝对接,为店家…

二、SPI协议

文章目录 总述1.SPI接口2. SPI工作模式3. SPI通信时序4. SPI协议 对比 UART协议(上一篇文章刚介绍过uart协议,这里来对比一下) 总述 SPI(Serial Peripheral Interface)是一种高速的、全双工、同步的串行通信总线&…

2024智能投影仪怎么选?大眼橙C1D,高清高亮高性价比

在这个科技飞速发展的时代,家庭智能化已经成为一种趋势。大眼橙C1D,2024年最新上市的一款智能投影仪,正以其独特的魅力,引领着智能家居的新潮流。 一、外观设计:简约而不简单 大眼橙C1D的外观设计采用了简约风格&…

pdffactory pro8.0虚拟打印机(附注册码)

PdfFactory pro是一款非常受欢迎的PDF虚拟打印机,可以帮助用户将你的其他文档保存为PDF格式。请为用户提供打印/发送/加密等多种实用功能,以及一套完善的PDF打印方案。 使用说明 下载pdfFactory Pro压缩包,解压后,双击exe文件&am…

2024数维杯A题可运行思路代码文章成品

为了能够精确地确定飞行器在三维空间中的位置,理论上至少需要从三个不同位置的发射源接收TOA数据。下面是使用TOA数据确定位置所需的计算基础和原理: 单个TOA数据: 单个TOA测量可以确定接收器与发射源之间的距离,这在三维空间中形…

error C2039: “NotifySeverity“: 不是 “osg“ 的成员 问题分析

程序从osg3.6.5Qt5.9osgearth2.10环境中移植到osg3.7.0Qt5.15.2osgearth3.3环境中,出现了无尽的错误。 有些错误很莫名奇妙,比如下述错误: D:\OsgEarth3.3\include\osgEarth\Notify(34,53): error C2039: "NotifySeverity": 不是 &…