当前位置: 首页 > news >正文

Kafka异常重试方案小记

背景

在最近进行的项目架构升级中,我们对原有的核心项目结构进行了细致的拆分。
现在,核心项目与非核心项目之间的通信和数据交换主要通过Kafka这一中间件来实现。
这种设计主要体现在核心项目向非核心项目发送通知,这些通知大致可以分为三个主要类别:

  1. 在设备租借流程中,订单状态发生变化时需要进行的额外业务处理,这是我们所说的核心消息
  2. 与用户相关的各类消息。
  3. 设备的心跳信号以及业务数据的上报消息。

针对这三类关键消息,从业务连续性和数据完整性的角度来看,我们的目标是确保它们的传递尽可能不受损失。如果出现异常情况,系统应自动触发重试机制,以保障消息的送达。同时,任何消息消费过程中的异常都不应影响到后续业务流程的执行,否则可能会对整个业务造成不利影响。

鉴于该项目已经在使用Kafka作为消息传递的基础设施,我们决定在当前场景下不更换为RocketMQ,尽管后者在某些方面可能更适合我们的需求。这一决定是基于对现有系统的依赖和对迁移成本的考虑,旨在保持系统的稳定性和减少不必要的复杂性。

死信队列:由于某些原因消息无法被正确的投递,为了确保消息不会被无故丢地丢弃,一般将其置于一个特殊角色的队列,这个队列一般称为死信队列。
后续分析程序可以通过消费这个死信队列中的内容来分析当时遇到的异常情况,进而可以改善优化系统。

看完这段介绍,死信队列简直就是我们当下最所需的功能,而对于RabbitMQ、RocketMQ来说,死信消息一般通过 broker 存入,
而在kafka中原本并无死信队列的概念,所以当需要自行封装这一层概念的时候,就可以脱离既定思维的约束,
根据应用情况选择合适的实现方式,理解死信的本质进而懂得如何实现死信队列的功能。

在实践中,我们对消息队列(MQ)的业务期望如下:

  1. 异常消费后的重试机制
    我们期望在消息消费过程中遇到异常时,系统能够自动进行重试,确保消息的可靠性。目前,Spring Kafka已经提供了异常重试的支持,并且能够在达到最大重试次数后将消息写入死信队列,以便于后续处理。
    为了进一步增强异常处理能力,我们可以通过自行编码,在消费异常时将相关信息写入日志,或者在消费后立即写入消息,待后续消费成功后再更新其状态。
  2. 异常消费与正常消费的隔离
    我们希望异常消费不会影响其他业务的正常进行。为此,MQ中的三类消息应该各自独立处理,互不干扰。这里可以采用线程池技术,为不同类型的消息分配专门的处理线程,从而实现并行处理和隔离。
  3. 发版期间的消息可靠性
    在发版期间,我们要求消息传递的高可靠性,确保消息不会丢失。为此,我们可以配置消费线程池的优雅停止机制,通过设置有限的等待时间来尽可能保证消息被完全消费。虽然这种方式无法100%保证所有消息都能在停止前消费完毕,但它可以在一定程度上减少消息丢失的风险。

在进行技术选型时,我们考虑了以下方案:

  1. 自动提交与手动提交:
    我们选择了自动提交模式,并将其时间间隔设置为30秒。这样做允许在发生异常或宕机后出现重复消费的情况,但需要业务逻辑自身实现幂等性以保证数据的一致性。
  2. Spring Kafka的使用:
    由于选择了自动提交,我们发现Sp
    ring Kafka中的重试机制缺乏持久化支持。这可能导致在发版过程中丢失消息,因此我们决定不采用这一方案。
  3. 重平衡期间的消息丢失问题:
    为了解决重平衡期间可能出现的消息丢失问题,我们计划引入JVM钩子,在发版时对当前工作线程池中的消息进行快照,并在后续重新推送这些消息。
  4. 本地消息处理:
    我们不采用在消息消费之初立即落库,在消费后修改状态的做法,以此减少对数据库的压力。
    在消费异常时,我们选择将消息落库,而在消费成功时则不进行写入。虽然在极端情况下这可能导致消息丢失,但对于这种极端情况业务层面是可以接受的。
  5. 业务之间的隔离:
    为了确保不同业务之间的相互独立性,我们将为三大类业务各自配置独立的线程池。如果某类业务的事件量特别大,我们还会考虑为其单独配置线程池,以实现更好的资源隔离和处理效率。

消费流程图

我们的最终技术方案如下:

  • Kafka自动提交设置:
    我们将Kafka的自动提交间隔设定为30秒,这有助于在发生异常或服务重启时减少消息的重复处理。
  • 异常处理机制:
    当工作线程在消费消息时遇到异常,系统将会自动记录这些异常信息到本地日志中。这些日志将用于后续的消息重推操作。此外,我们增加了一个Web端的手动重推功能,以便于在需要时手动触发消息的重新处理,若后续异常消息多时可以考虑自动的定时调度。
  • 线程池的优雅关闭:
    为了确保在服务停止时已拉取的消息能够被完全消费,我们配置了工作线程池的优雅关闭机制。在JVM关闭钩子执行时,系统将等待30到60秒,以确保当前已拉取的消息能够被完全消费。在此期间,系统将快照当前工作线程池队列中的所有消息,以便在必要时进行恢复。
  • 双重保障机制:
    为了提供额外的保障,我们在JVM关闭钩子执行时再次快照工作线程池队列中的所有消息。这一双重快照机制确保了即使在极端情况下,消息也不会丢失,从而保障了系统的高可靠性和数据的完整性。

写到最后

通过这些细致的技术选型和策略,我们旨在构建一个既高效又稳定的系统,以支持业务的持续发展和创新。

相关文章:

Kafka异常重试方案小记

背景 在最近进行的项目架构升级中,我们对原有的核心项目结构进行了细致的拆分。 现在,核心项目与非核心项目之间的通信和数据交换主要通过Kafka这一中间件来实现。 这种设计主要体现在核心项目向非核心项目发送通知,这些通知大致可以分为三个…...

非页面缓冲池占用过高处理方法

1.现象 电脑变莫名其妙得特别卡,明明16G的内存,理论上日常使用,打游戏之类的使用起来完全不会有什么大问题,但是实际使用却是卡的要死。 下面开始查找原因。 2.查找原因 使用win自带的任务管理器,可以看到日常内存…...

【Linux】进程信号(下)

目录 一、信号的阻塞 1.1 信号在内核中的保存方式 1.2 sigset_t信号集 (1)信号集操作 (2)sigprocmask函数 (3)sigpending函数 二、信号的处理 2.1 用户态和内核态 2.2 重谈进程地址空间 三、信号…...

FlinkCDC 实现 MySQL 数据变更实时同步

文章目录 1、基本介绍2、代码实战2.1、数据源准备2.2、代码实战2.3、数据格式 1、基本介绍 Flink CDC 是 Apache Flink 提供的一个功能强大的组件,用于实时捕获和处理数据库中的数据变更。可以实时地从各种数据库(如MySQL、PostgreSQL、Oracle、MongoDB…...

JavaWeb——Maven(4/8):Maven坐标,idea集成-导入maven项目(两种方式)

目录 Maven坐标 导入Maven项目 第一种方式 第二种方式 Maven坐标 Maven 坐标 是 Maven 当中资源的唯一标识。通过这个坐标,我们就能够唯一定位资源的位置。 Maven 坐标主要用在两个地方。第一个地方:我们可以使用坐标来定义项目。第二个地方&#…...

实现uniapp天地图边界范围覆盖

在uniapp中,难免会遇到使用地图展示的功能,但是百度谷歌这些收费的显然对于大部分开源节流的开发者是不愿意接受的,所以天地图则是最佳选择。 此篇文章,详细的实现地图展示功能,并且可以自定义容器宽高,还可…...

思科网络设备命令

一、交换机巡检命令 接口和流量状态 show interface stats:查看所有接口当前流量。show interface summary:查看所有接口当前状态和流量。show interface status:查看接口状态及可能的错误。show interface | include errors | FastEthernet …...

Egg.js使用ejs快速自动生成resetful风格的CRUD接口

目前的插件能够自动生成egg的crud的都不太好用 我们自己写一个吧 ejs模块 也方便定制 安装依赖 npm install ejs --save ejs 是一个简单易用的模板引擎,常用于 Node.js 应用程序中 在项目根目录下创建 template/controller.ejs 模板文件 use strict;const Co…...

自动化抖音点赞取消脚本批量处理

🌟 前言 欢迎来到我的技术小宇宙!🌌 这里不仅是我记录技术点滴的后花园,也是我分享学习心得和项目经验的乐园。📚 无论你是技术小白还是资深大牛,这里总有一些内容能触动你的好奇心。🔍 &#x…...

基于YOLOv8深度学习的智能车牌检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

背景及意义 智能车牌检测与识别系统通过使用最新的YOLOv8与PaddleOCR算法能够迅速、准确地在多种环境下实现实时车牌的检测和识别。本文基于YOLOv8深度学习框架,通过16770张图片,训练了一个进行车牌检测模型,可以检测蓝牌与绿牌,然后对检测到的车牌使用O…...

qt QGraphicsGridLayout详解

一、概述 QGraphicsGridLayout是Qt框架中用于在QGraphicsScene中布置图形项的一个布局管理器。它类似于QWidget中的QGridLayout,但主要处理的是QGraphicsItem和QGraphicsWidget等图形项。通过合理设置网格位置、伸缩因子和尺寸,可以实现复杂而灵活的布局…...

数字处理系列

&#xff08;1&#xff09;将数字转化成中文的过滤器 <template><div><p>数字转中文&#xff1a;{{ 110 | numberToChinese }}</p></div></template><script>export default {filters: {numberToChinese(num) {const chineseNums …...

基于开源Jetlinks物联网平台协议包-MQTT自定义主题数据的编解码

目录 前言 1.下载官方协议包 2.解压 3.自定义主题 4.重写解码方法 5.以下是我解析后接收到的数据 前言 最近这段时间&#xff0c;一直在用开源的Jetlinks物联网平台在学习&#xff0c;偶尔有一次机会接触到物联网设备对接&#xff0c;在协议对接的时候&#xff0c;遇到了…...

【Python】Python2.7升级Python3

需求背景 服务是跑在docker的容器里的&#xff0c;因此要新建image依赖环境是Ubuntu&#xff0c;老的是16.4。 步骤 先准备环境&#xff0c;因为只有你的环境上去了&#xff0c;运行代码的时候才会报错&#xff0c;这样才会把需要改的代码暴露出来。 python3.5目前也是被遗弃的…...

Python 内置函数 round() 详解

在 Python 编程中&#xff0c;round() 函数是一个非常实用的内置函数&#xff0c;用于对数字进行四舍五入。无论是在数据处理、财务计算还是科学计算中&#xff0c;round() 函数都能帮助我们得到所需的精确值。本文将详细介绍 round() 函数的用法和注意事项。 1. round() 函数…...

JavaScript入门中-流程控制语句

本文转载自&#xff1a;https://fangcaicoding.cn/article/52 大家好&#xff01;我是方才&#xff0c;目前是8人后端研发团队的负责人&#xff0c;拥有6年后端经验&3年团队管理经验&#xff0c;截止目前面试过近200位候选人&#xff0c;主导过单表上10亿、累计上100亿数据…...

kconfig语法(一)

一、安装Kconfiglib python -m pip install windows-curses python -m pip install kconfiglib二、使用样例 ①创建kconfig文件。 ②在kconfig文件添加内容: config KCONFIG_DEMO_ITEM1boolprompt "demonstate item1 for bool learning"config KCONFIG_DEMO_ITE…...

十七、行为型(命令模式)

命令模式&#xff08;Command Pattern&#xff09; 概念 命令模式是一种行为型设计模式&#xff0c;它将请求封装成一个对象&#xff0c;从而使您可以使用不同的请求对客户进行参数化&#xff0c;排队请求&#xff0c;以及支持可撤销操作。通过这种模式&#xff0c;调用操作的…...

原材料供应商的GRS认证证书过期了怎么办?

在全球纺织和时尚产业中&#xff0c;GRS&#xff08;Global Recycle Standard&#xff0c;全球再生标准&#xff09;认证已成为衡量企业环保和可持续发展的重要指标。然而&#xff0c;当原材料供应商的GRS认证证书过期时&#xff0c;企业需迅速采取行动&#xff0c;以确保供应链…...

C++编程:实现一个基于原始指针的环形缓冲区(RingBuffer)缓存串口数据

文章目录 0. 引言1. 使用示例2. 流程图2.1 追加数据流程2.2 获取空闲块流程2.3 处理特殊字符流程2.4 释放块流程2.5 获取下一个使用块流程 3. 代码详解3.1 Block 结构体3.2 RingBuffer 类3.3 主要方法解析append 方法currentUsed 和 currentUsing 方法release 方法nextUsed 方法…...

LangChain 创始人万字科普:手把手教你设计 Agent 用户交互

LangChain 可以算是 LLM 时代做 AI 应用开发必备的框架和平台&#xff0c;从模型选择、数据库链接与各种 Agent 搭建等&#xff0c;AI 应用的搭建、运行和管理都可以在 LangChain 上进行。 某种意义上&#xff0c;LangChain 可能是最了解 Agent&#xff08;智能体&#xff09;…...

Docker 用例:15 种最常见的 Docker 使用方法

容器化应用程序而不是将它们托管在虚拟机上是过去几年一直流行的概念&#xff0c;使容器管理流行起来。Docker 处于这一转变的核心&#xff0c;帮助组织无缝地采用容器化技术。最近&#xff0c;Docker 用例遍布所有行业&#xff0c;无论规模大小和性质如何。 什么是Docker&…...

若依 RuoYi4.6.0 代码审计

环境布置&#xff1a; 到官网下载源码&#xff1a;https://github.com/yangzongzhuan/RuoYi 采用phpstudy集成数据库&#xff0c;5.7版本。JDK1.8。 IDEA打开项目&#xff0c;等待自动加载&#xff0c;修改application-druid.yml配置文件&#xff1a;数据库名&#xff0c;账…...

C语言入门-选择结构

在编程中&#xff0c;我们经常需要根据不同的条件执行不同的操作。C语言为此提供了几种非常实用的选择结构&#xff1a;条件运算符、逻辑运算、if语句和switch语句。接下来&#xff0c;让我们深入探讨这些重要的知识点&#xff0c;帮助你更好地理解和掌握C语言的选择结构。 1.…...

Legion拯救者 刃7000K-26IAB联想台式机T5 26IAB7(90SU,90SV,90SW,90SX)原厂Windows11系统镜像下载

适用机型&#xff1a;【90SW、90SX、90SU、90SV】 链接&#xff1a;https://pan.baidu.com/s/1gJ4ZwWW2orlGYoPk37M-cg?pwd4mvv 提取码&#xff1a;4mvv lenovo联想原装WIN系统自带所有驱动、出厂主题专用壁纸、系统属性联机支持标志、系统属性专属LOGO标志、Office办公软…...

代码随想录算法训练营第二十四天|Day24 回溯算法

93.复原IP地址 题目链接/文章讲解&#xff1a;https://programmercarl.com/0093.%E5%A4%8D%E5%8E%9FIP%E5%9C%B0%E5%9D%80.html 视频讲解&#xff1a;https://www.bilibili.com/video/BV1XP4y1U73i/ 思路 char** result; int resultTop; int segments[3]; int isValid(char* s…...

vue elementui table编辑表单时,弹框增加编辑明细数据

需求: 前端进行新增表单时&#xff0c;同时增加表单的明细数据。明细数据部分&#xff0c;通过弹框方式增加或者编辑。 效果图&#xff1a; 代码&#xff1a; <!-- 新增主表弹窗 Begin --><el-dialog:title"titleInfo"top"5vh"centerwidth"…...

springboot集成Redisson做分布式消息队列

这里演示Redisson做分布式消息队列。首先引入 Redisson依赖&#xff0c;官方github <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.17.6</version> </dependen…...

如何通过Lua语言请求接口拿到数据

文章目录 概要http客户端通过请求下载数据 概要 当某个需求是需要在模块内请求接口拿到数据&#xff0c;需要使用http客户端调用接口 http客户端 LuaSOC请求接口官方文档 调用&#xff1a;http.request(method,url,headers,body,opts,ca_file,client_ca, client_key, clien…...

Android 13 SystemUI 隐藏下拉快捷面板部分模块(wifi,bt,nfc等)入口

frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java createTileInternal(tileSpec)方法注释想隐藏的模块即可。...

图书馆门户网站建设方案/搜索引擎营销sem

一.Flutter 线程管理 Embeder : 嵌入器 Flutter Engine要求Embeder提供四个Task Runner&#xff0c;Embeder指的是将引擎移植到平台的中间层代码。这四个主要的Task Runner包括&#xff1a; 效果图 1.Platform Task Runner Flutter Engine的主Task Runner&#xff0c;类似于A…...

杭州服装网站建设/网络怎样做推广

android-iconify 使用详解 有图有真相 1、android-iconify简介 iconify的github地址&#xff1a;https://github.com/JoanZapata/android-iconify项目地址&#xff1a;http://joanzapata.com/android-iconifyiconify是一个矢量图标库&#xff0c;包含使用 Dave Gandy 制作的超过…...

合肥做公司网站一般多少钱/网页设计代码大全

中断由外部设备产生&#xff0c;异常由CPU内部产生&#xff08;异常包括错误Fault, 陷阱Trap即故意出错&#xff0c;和终止Abort&#xff09;。中断要找到中断服务程序所以需要IDT这个大数组来存放中断门&#xff08;中断门就是一种段描述符&#xff0c;用于找到中断程序入口地…...

学ui可以做网站么/百度收录网址

题目: 定义一个区间的值为其众数出现的次数。 现给出n个数&#xff0c;求将所有区间的值排序后&#xff0c;第K大的值为多少。 题解: 答案明显单调,我们考虑二分答案. 转化为判定问题后我们需要观察到一个性质: 如果一个区间的价值已经 > mid了,那么这个无论左右端点向外延伸…...

个体工商户可以网站建设吗/网站优化推广哪家好

https://mp.weixin.qq.com/s/HVBGhtJ6Cm6hwpLUEz76BQ...

成都智能建站模板/优化大师app

##前言 通信&#xff0c;是指人与人、人与物、物与物之间通过某种媒介和行为进行的信息传递与交流。 网络通信&#xff0c;是指终端设备之间通过计算机网络进行的通信。 两台计算机通过一根网线相连&#xff0c;就组成了一个最简单的网络。 由一台路由器&#xff08;或交换机…...