延时消息+递归导致重复消费爆炸问题

news2024/11/19 1:33:05

背景

        公司所用消息队列为RoucketMQ,版本为4.x。最近公司有业务需要,将某个处理延迟到第二天的白天再进行。由于4.x版本队列,默认延时时间是按等级来延时的,默认有18个等级,如下图:

        默认的延时等级,无法满足延时任意时间的需要,所以现有的实现方式,是采用:延时队列+时间轮。延时队列可以延时指定等级的时间,当剩余时间小于1min时,再封装成定时任务,投递给netty中的时间轮来处理。然而当延时时间超过2H时,单次的延时队列已无法满足(默认最高2H),此时现有方案是递归的方式,继续延迟(当然也可以增加延时等级,减少递归次数)。实现方案如下图(以延时1.5H为例):

        在已有的延时业务下,通常都是短时间延迟,2H之内,所以以上方案未出现较大问题。

发现问题

        最近新增了业务需求,要求延时到第二天,例如延时20H,继续使用了上述方案,但后继续通过MQ的Console发现,延时队列的消息积压非常严重,数量远超出业务数量。然后开始通过ELK查看消息的消费日志,发现UUID标识的唯一消息,重复消费较严重,如下图:

排查问题

        图中只是重复消费的一部分,实际重复消费很严重,单条消息被重复消费了上万次(还好是在测试环境,生产不敢想象【狗头】)。

        然后,就准备从重复消费入手,未何会重复消费这么多次呢,查看mq的消费重试次数

RetryTimesSendFailed=2,意思是第一次消费未返回成功的话(未消费成功的原因有多种,可以另外查阅),会再进行两次重试,那就是会进行一次消费最多消费3次。

        通过上述延时方案图发现,当延时2H后,剩余时间仍超过60S时,会递归再进行延时2H,以此类推,那么问题就来了:如果以此延时重复消费3次,那么递归一次,原本重复的每次再重复3次,就是重复3*3=9次;第二次递归,就是重复3*3*3=27次;第三次递归就是3*3*3*3=81次……。随着递归次数增加,重复消费次数指数级增长,想想就阔怕。

        通过上图的日志图,每个时间点的重复消费次数:1、3、9、27……也验证了上述的推理。

解决问题

        那既然找到了上述重复消费的原因,我们也可以针对性的采取一些措施来应对,以下是想到一些初步举措,后续可能结合具体情况再做优化; 

  1. 如果消息消费的可靠性不是要求特别高,或者有其他补偿机制,最快速的方式,直接配置RetryTimesSendFailed=0,这样就没有重试,因而也就没有重复消费,即使递归延时也不影响。
  2. 通常情况下,可能不方便关闭重试,那就可以在消费时,进行幂等控制。这样即使进行重复消费,也只有一条消息正常消费执行。
  3. 如果只是采取第2条的话,由于递归次数没变,可能还是会存在一定数量的重复消费。我们可以扩展MQ默认的延时等级,比如增加5H/10H/20H/40H的延时等级,这样可以减少递归延时的重试次数,进而减少重复消费次数。
  4. 如果运维层面支持的话,我们也可以将RocketMQ升级为5.x版本,这个版本是支持任务时间的延时的,所以就不用自行扩展通过递归的方式来延时了。

思考总结

        通过上述分析,这次出现的重复消费的问题,还是挺严重,但幸好还是在测试环境,发生在了生产,估计都得提桶跑路了。通过上述问题排查,也总结了一些日常要注意的地方:

  1. 使用消息队列时,考虑可能出现的常见问题:重复消费,消息积压、消息丢失等;充分测试确保不会出现上述问题;
  2. 慎重使用递归、死循环;我们相信正常流程执行的话,递归和死循环是不会有大问题的;但根据墨菲定律,虽然意外情况概率小,但仍可能出现。所以使用递归、死循环时,一定要慎重,考虑各种意外场景,且考虑中断策略。
  3. 测试要覆盖实际业务场景,像上述问题,如果测试为了快速验证测试结果,只是延时了几分钟,那么递归延迟就不会触发,问题也不会再测试环境暴露。所以测试要全面,保证覆盖实际的业务场景
  4. 技术层面,我们需要重复理解学习所用的技术栈,如果不能知其所以然,那么一些容易出问题的地方,可能就会被我们所忽略,进而导致更大的问题。

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

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

相关文章

我对迁移学习的一点理解(系列2)

文章目录 我对迁移学习的一点理解 我对迁移学习的一点理解 源域和目标域是相对的概念,指的是在迁移学习任务中涉及到的两个不同的数据集或领域。 源域(Source Domain)通常指的是已经进行过训练和学习的数据集,它被用来提取特征、…

盒马补贴量价-2021KDD

概述: 电商商品定价三个关键问题: 在只有观测数据的时候,怎么构建价格弹性,现在来看这就是一个反事实推断的问题,不仅是如何做的问题,还有如何评估的问题。长周期的规划决策问题怎么建模 & 求解&#…

基于状态机的单片机编程

前言 在设计锂离子电池充电器时,对于以前的根据系统状态进行判断,置标志位的方法,会显得程序臃肿,且架构混乱,变量交错复杂,移植困难。 所以结合实际项目,给出了一种基于状态机的编程方法。 …

线程上下文切换

线程上下文切换 巧妙地利用了时间片轮转的方式, CPU 给每个任务都服务一定的时间,然后把当前任务的状态保存下来,在加载下一任务的状态后,继续服务下一任务,任务的状态保存及再加载, 这段过程就叫做上下文切换。时间片轮转的方式…

对String类的操作 (超细节+演示)

[本节目标] 1.认识String类 2.了解String类的基本用法 3.熟练掌握String类的常见操作 4.认识字符串常量池 5.认识StringBuffer和StringBuilder 1.String类的重要性 在C语言中已经涉及到字符串了,但是在C语言中要表示字符串只能使用字符数组或者字符指针&…

差异计算基础知识 - 了解期末业务操作、WIP 和差异

原文地址:Basics of variance calculation-Understanding Period End activities, WIP and Variances | SAP Blogs 大家好, 这是我在成本核算方面的第六份文件,旨在解释期末的差异计算和相关活动。 我将引导您完成期末活动和差异计算。在本文…

Spring Cloud Gateway 网关的基础使用

1. 什么是网关?网关有什么用? 在微服务架构中,网关就是一个提供统一访问地址的组件,它解决了内部微服务与外部的交互问题。网关主要负责流量的路由和转发,将外部请求引到对应的微服务实例上。同时提供身份认证、授权、…

前后端数据传输格式(下)

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 上篇主要复习了HTTP以及…

解释AI决策,这10个强大的 Python 库记得收藏!

本文整理了10个常用于可解释AI的Python库,方便我们更好的理解AI模型的决策。 什么是XAI? XAI(Explainable AI)的目标是为模型的行为和决策提供合理的解释,这有助于增加信任、提供问责制和模型决策的透明度。XAI 不仅…

鸿蒙生态开发就业前景到底好不好

鸿蒙生态开发是指基于华为自主研发的操作系统鸿蒙(HarmonyOS)进行应用程序开发和生态建设。目前,鸿蒙生态开发的前景非常好,原因如下:做鸿蒙应用开发到底学习些啥? (qq.com) 1:政府支持&#x…

高德地图vue实现自定义标点热力图效果(缩放时展示不同数据)

高德地图插件引入省略。。。样式和vue基础组件省略。。。 如果每个标点没有数值,则可以用点聚合来实现功能下面例子,每个标点会有按市统计的数值,而且缩放一定程度时,需要展示按省统计的标点,因此需要自定义标点样式和…

Ubuntu中编译出Windows的可执行程序(.exe)

1、前言 在嵌入式开发中,交叉编译是很常见的情况,如果你把Windows电脑也看做一块高性能的开发板,那在Ubuntu中编译出Windows上运行的可执行程序也是很好理解的行为。 2、安装mingw64环境 sudo apt-get install mingw-w64 3、测试编译链是否安…

特权FPGA 学习笔记

存储器可用于异步时钟域的信号处理,双口RAM多用于交互式数据,FIFO多用于单向数据传输;以task的方式封装testbench子程序,以提高复用程度;模板中,vho是vhdl模板,veo是verilog模板;run…

第七届中老越三国丢包狂欢节暨2023年中老越三国(普洱)边境商品交易会新闻发布会在昆明召开

12月8日,第七届中老越三国丢包狂欢节暨2023年中老越三国(普洱)边境商品交易会新闻发布会在昆明召开。据悉,本届丢包节暨边交会将于2023年12月22日至26日在普洱市江城哈尼族彝族自治县举办。 发布会现场 中老越三国丢包狂欢节自200…

解决 php 连接mysql数据库时报错:Fatal error: Class ‘mysqli’ not found in问题

在使用php对mysql进行连接的过程中,出现了Fatal error: Uncaught Error: Class "mysqli" not found in的问题 解决方案 这个错误通常表示您的PHP代码中缺少MySQL扩展或者没有启用MySQL扩展。 我们首先确认一下PHP环境中已经安装了MySQL扩展。检查一下自己…

v4l2接收流程

内核media驱动目录结构 目录media/driver,子目录说明如下,主要列举本文中使用到的目录 目录功能I2C摄像头,解串器(max9296/9295等)platform控制器的驱动,例如mipi控制等v4l2_coreioctl 入口等media\common\videobuf2…

哈希表的几种实现方式与比较

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 哈希表概述 哈希表(Hash Table)是一种常用的数据结构,用于实现键值对的映射关系。它通过哈希函数将键映射到一个特定的索引位置&#xf…

Spring Boot 3 整合 Mybatis-Plus 实现动态数据源切换实战

🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🌺 仓库主页: Gitee 💫 Github 💫 GitCode 💖 欢迎点赞…

银河麒麟本地软件源配置方法

软件源介绍 软件源可以理解为软件仓库,当需要安装软件时则会根据源配置去相应的软件源下载软件包,此方法的优点是可以自动解决软件包的依赖关系。常见的软件源有光盘源、硬盘源、FTP源、HTTP源,本文档主要介绍本地软件源的配置方法&#xff…

专注抖音短视频账号矩阵系统源头开发---saas工具

抖音账号|短视频矩阵分发系统 | 多账号管理发布 |MVC架 短视频矩阵分发系统是一种可以帮助企业、机构和个人高效分发短视频的工具。随着社交媒体的不断普及,短视频的使用越来越广泛,因此如何快速而准确地将短视频传播到不同的平台和账号上已经成为了一个…