kafka常见问题

news2024/9/29 13:16:58

1.为什么要用mq(mq的作用)?

2.引入mq会多哪些问题?

3. 如何解决这些问题?

1.1实现异步发送

有些复杂的业务系统,一次用户请求可能会同步调用N个系统的接口,需要等待所有的接口都返回了,才能真正的获取执行结果。这种同步接口调用的方式总耗时比较长,非常影响用户的体验,特别是在网络不稳定的情况下,极容易出现接口超时问题。

同步接口调用导致响应时间长的问题,使用mq之后,将同步调用改成异步,能够显著减少系统响应时间。


1.2解耦

很多复杂的业务系统,一般都会拆分成多个子系统。系统之间耦合性太高,如果调用的任何一个子系统出现异常,整个请求都会异常,对系统的稳定性非常不利。

子系统间耦合性太大的问题,使用mq之后,只需要依赖于mq,避免了各个子系统间的强依赖问题。订单系统作为消息生产者,保证它自己没有异常即可,不会受到支付系统等业务子系统的异常影响,并且各个消费者业务子系统之间,也互不影响。这样就把之前复杂的业务子系统的依赖关系,转换为只依赖于mq的简单依赖,从而显著的降低了系统间的耦合度。

1.3  削峰

某一时间请求量特别大时,消费方消费能力不足,可能会导致系统响应变慢或者直接挂掉。

订单系统接收到用户请求之后,将请求直接发送到mq,然后订单消费者从mq中消费消息,做写库操作。如果出现请求峰值的情况,由于消费者的消费能力有限,会按照自己的节奏来消费消息,多的请求不处理,保留在mq的队列中,不会对系统的稳定性造成影响。

2.引入mq会多哪些问题?

引入mq后子系统间耦合性降低了,异步处理机制减少了系统的响应时间,同时能够有效的应对请求峰值问题,提升系统的稳定性。

但是,引入mq同时也会带来一些问题。

2.1 重复消息问题

重复消费问题可以说是mq中普遍存在的问题,不管你用哪种mq都无法避免。

有哪些场景会出现重复的消息呢?

  • 消息生产者产生了重复的消息
  • kafka和rocketmq的offset被回调了
  • 消息消费者确认失败
  • 消息消费者确认时超时了
  • 业务系统主动发起重试


如果重复消息不做正确的处理,会对业务造成很大的影响,产生重复的数据,或者导致数据异常,比如会员系统多开通了一个月的会员。

2.2 数据一致性问题

很多时候,如果mq的消费者业务处理异常的话,就会出现数据一致性问题。比如:一个完整的业务流程是,下单成功之后,送100个积分。下单写库了,但是消息消费者在送积分的时候失败了,就会造成数据不一致的情况,即该业务流程的部分数据写库了,另外一部分没有写库。


如果下单和送积分在同一个事务中,要么同时成功,要么同时失败,是不会出现数据一致性问题的。

但由于跨系统调用,为了性能考虑,一般不会使用强一致性的方案,而改成达成最终一致性即可。

2.3 消息丢失问题

同样消息丢失问题,也是mq中普遍存在的问题,不管你用哪种mq都无法避免。

有哪些场景会出现消息丢失问题呢?

消息生产者发生消息时,由于网络原因,发生到mq失败了。

mq服务器持久化时,磁盘出现异常

kafka和rocketmq的offset被回调时,略过了很多消息。

消息消费者刚读取消息,已经ack确认了,但业务还没处理完,服务就被重启了。

导致消息丢失问题的原因挺多的,生产者、mq服务器、消费者 都有可能产生问题,我在这里就不一一列举了。最终的结果会导致消费者无法正确的处理消息,而导致数据不一致的情况。

2.4 消息顺序问题

有些业务数据是有状态的,比如订单有:下单、支付、完成、退货等状态,如果订单数据作为消息体,就会涉及顺序问题了。如果消费者收到同一个订单的两条消息,第一条消息的状态是下单,第二条消息的状态是支付,这是没问题的。但如果第一条消息的状态是支付,第二条消息的状态是下单就会有问题了,没有下单就先支付了?消息顺序问题是一个非常棘手的问题,比如:

kafka同一个partition中能保证顺序,但是不同的partition无法保证顺序。

rabbitmq的同一个queue能够保证顺序,但是如果多个消费者同一个queue也会有顺序问题。

如果消费者使用多线程消费消息,也无法保证顺序。

如果消费消息时同一个订单的多条消息中,中间的一条消息出现异常情况,顺序将会被打乱。

还有如果生产者发送到mq中的路由规则,跟消费者不一样,也无法保证顺序。

2.5 消息堆积

如果消息消费者读取消息的速度,能够跟上消息生产者的节奏,那么整套mq机制就能发挥最大作用。但是很多时候,由于某些批处理,或者其他原因,导致消息消费的速度小于生产的速度。这样会直接导致消息堆积问题,从而影响业务功能。

这里以下单开通会员为例,如果消息出现堆积,会导致用户下单之后,很久之后才能变成会员,这种情况肯定会引起大量用户投诉。

2.6 系统复杂度提升

这里说的系统复杂度和系统耦合性是不一样的,比如以前只有:系统A、系统B和系统C 这三个系统,现在引入mq之后,你除了需要关注前面三个系统之外,还需要关注mq服务,需要关注的点越多,系统的复杂度越高。mq的机制需要:生产者、mq服务器、消费者。

有一定的学习成本,需要额外部署mq服务器,而且有些mq比如:rocketmq,功能非常强大,用法有点复杂,如果使用不好,会出现很多问题。有些问题,不像接口调用那么容易排查,从而导致系统的复杂度提升了。

3 如何解决这些问题?

mq是一种趋势,总体来说对我们的系统是利大于弊的,难道因为它会出现一些问题,我们就不用它了?

那么我们要如何解决这些问题呢?

3.1 重复消息问题

不管是由于生产者产生的重复消息,还是由于消费者导致的重复消息,我们都可以在消费者中通过做幂等设计来解决。

一种解决方法是增加一张消费消息表,来解决mq的这类问题。消费消息表中,使用messageId做唯一索引,在处理业务逻辑之前,先根据messageId查询一下该消息有没有处理过,如果已经处理过了则直接返回成功,如果没有处理过,则继续做业务处理。


3.2 数据一致性问题

数据一致性分为:

强一致性

弱一致性

最终一致性

而mq为了性能考虑使用的是最终一致性,那么必定会出现数据不一致的问题。这类问题大概率是因为消费者读取消息后,业务逻辑处理失败导致的,这时候可以增加重试机制。

重试分为:同步重试 和 异步重试。

有些消息量比较小的业务场景,可以采用同步重试,在消费消息时如果处理失败,立刻重试3-5次,如何还是失败,则写入到记录表中。但如果消息量比较大,则不建议使用这种方式,因为如果出现网络异常,可能会导致大量的消息不断重试,影响消息读取速度,造成消息堆积。

而消息量比较大的业务场景,建议采用异步重试,在消费者处理失败之后,立刻写入重试表,有个job专门定时重试。

还有一种做法是,如果消费失败,自己给同一个topic发一条消息,在后面的某个时间点,自己又会消费到那条消息,起到了重试的效果。如果对消息顺序要求不高的场景,可以使用这种方式。

3.3 消息丢失问题

不管你是否承认有时候消息真的会丢,即使这种概率非常小,也会对业务有影响。生产者、mq服务器、消费者都有可能会导致消息丢失的问题。

为了解决这个问题,我们可以增加一张消息发送表,当生产者发完消息之后,会往该表中写入一条数据,状态status标记为待确认。如果消费者读取消息之后,调用生产者的api更新该消息的status为已确认。有个job,每隔一段时间检查一次消息发送表,如果5分钟(这个时间可以根据实际情况来定)后还有状态是待确认的消息,则认为该消息已经丢失了,重新发条消息。

这样不管是由于生产者、mq服务器、还是消费者导致的消息丢失问题,job都会重新发消息。

3.4 消息顺序问题

消息顺序问题是我们非常常见的问题,我们以kafka消费订单消息为例。订单有:下单、支付、完成、退货等状态,这些状态是有先后顺序的,如果顺序错了会导致业务异常。

解决这类问题之前,我们先确认一下,消费者是否真的需要知道中间状态,只知道最终状态行不行?

其实很多时候,我真的需要知道的是最终状态,这时可以把流程优化一下:

这种方式可以解决大部分的消息顺序问题。

但如果真的有需要保证消息顺序的需求。订单号路由到不同的partition,同一个订单号的消息,每次到发到同一个partition。


3.5 消息堆积

如果消费者消费消息的速度小于生产者生产消息的速度,将会出现消息堆积问题。

那么消息堆积问题该如何解决呢?

这个要看消息是否需要保证顺序。

如果不需要保证顺序,可以读取消息之后用多线程处理业务逻辑。


这样就能增加业务逻辑处理速度,解决消息堆积问题。但是线程池的核心线程数和最大线程数需要合理配置,不然可能会浪费系统资源。

如果需要保证顺序,可以读取消息之后,将消息按照一定的规则分发到多个队列中,然后在队列中用单线程处理。

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

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

相关文章

虹科分享 | 高考大数据可视化志愿填报分析-基于虹科Domo BI工具

高考是中国教育系统中一项极为重要的考试,它不仅是学生完成高中学业的重要标志,也是进入大学的门槛。每年高考都会吸引数百万学生参加,同时也吸引了各地高校和招生部门的关注。高考招生数据是教育研究和政策制定的重要依据,通过对…

技术管理第二板斧建团队-知人善用

1、什么是知人善用 知人善用就是指技术 Leader 怎么用对人?用好人?核心在于怎么给事情安排对的人?怎么给人安排合适的事情?其中,“人”与“事”相辅相成,如果把事情安排给对的人,不光会取得好结…

干货丨如何实现WinApp的UI自动化测试?自动化工具如何选择人?

WinApp(WindowsAPP)是运行在Windows操作系统上的应用程序,通常会提供一个可视的界面,用于和用户交互。例如运行在Windows系统上的Microsoft Office、PyCharm、Visual Studio Code、Chrome,都属于WinApp。常见的WinApp&…

Arduino IDE 2.1.0 下安装ESP32(2.0.9)

很久没玩Arduino了。新装了一台电脑,想重新捡起ESP32-WROOM-32开发板玩玩。官网上下了Arduino IDE 2.1.0,然后配置ESP32开发环境。 下载及安装Arduino IDE略过不谈。装完后还是老规矩,文件 -> 首选项,先把自定义板管理地址填入…

好程序员:2023年自学Java四阶段学习法,真滴好用麻啦!

同学们,我是好程序员小源,今天给大家整理了自学Java的四个阶段,大家可以按照这四个阶段学习哦~会更加规划系统一点! 第一阶段: JavaSE[5周] 本阶段从零基础起步,荃面深入的学系JavaSE课程,主要内容包括Java…

支付“清结算”体系的设计方法

支付完成以后进行履约,履约完成以后就需要清算各方利益并最终进行结算,清结算体系与支付体系并行是支付范畴另一个非常庞大的体系。 一、清算系统设计 我们都知道一笔支付最终都是要进行清算的,业务一般都会有众多参与者或者利益方&#xff…

ESP32网络应用 -- ESP32-S3使用MQTT协议与其他设备进行数据交互

在嵌入式物联网技术领域,MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)协议是一种非常常见且应用广泛的消息协议,它基于发布/订阅范式进行数据传输。关于MQTT协议的详细介绍,网络上不乏相关文章,此处不再进行详细论述。 ESP32-S3是一款应用广泛的物联网…

WPF实现登录页面设计

1、文件架构 2、CommandBase.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input;namespace CourseManagement.Common {public class CommandBase : ICommand{public ev…

EXCEL和VBA如何改变字母大小写 和 大小写互换?我写的自定义函数

目录 1 EXCEL里改变大小写的内置函数 2.1 转换大小写的函数 2.2 神奇的把数字和中文大小写转换的函数 2 VBA里改变大小写的内置函数 2.1 改变大小写 的内置函数 2.2 使用 excel的WorksheetFunction. text() 函数 3 如果想交换字母的大小写呢? 3.1 ASCII码里…

Java Servlet 技术

一、Servlet 简介 Servlet 是 JavaEE 的规范之一,通俗的来说就是 Java 接口,将来我们可以定义 Java 类来实现这个接口,并由 Web 服务器运行 Servlet ,所以 TomCat 又被称作 Servlet 容器。 Servlet 提供了动态 Web 资源开发技术…

偷偷爆料下工资特别高的8个开发岗。。。。。

外国网站 devjobsscanner 统计了全年需求量大的8种编程语言,基本上薪资很高的,也就是这几个方向了。 对于跳槽、找工作、转行、转语言等,都有一定的参考意义。 接下来结合网站统计和招聘网站的数据,可以做一个对照。 NO.1 Java…

MongoDB的基本操作

MongoDB的基本操作 MongoDB MongoDB是一个基于分布式文件存储的数据库,由C语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数…

游泳带什么防水耳机好,最佳游泳耳机的推荐排行榜

在炎炎夏日,玩水无疑是降温的最佳方式。既可以在室内游泳馆通过游泳锻炼身体,也可以到海滨浴场享受游泳和日光浴的乐趣。因此,选购一款适合水上活动的游泳耳机变得尤为重要。音乐的力量可以让原本单调乏味的游泳运动变得更具活力,…

Linux基础服务4——ftp

文章目录 一、基本了解1.1 C/S型架构1.2 数据连接模式1.3 用户认证 二、安装服务端2.1 安装vsftpd2.2 配置文件2.3 主配置文件参数2.4 windows访问服务端2.4.1 系统用户访问2.4.2 匿名用户访问2.4.2 开启客户端上传权限2.4.3 开启客户端其他权限2.4.4 开启客户端删除、修改权限…

hvv 文件上传和文件包含考点

天眼如何判断文件上传漏洞是否成功 数据包分析 观察客户端请求数据:是否包含webshell流量特征观察服务器返回信息:是否有“上传成功”或“success upload”等信息提示 尝试寻找上传的文件:访问上传的文件看是否存在;查看文件上传…

Redisson分布式锁-源码分析

Redisson分布式锁整体流程图 Redisson分布式锁源码流程图 Redisson分布式锁源码解析 获取分布式锁lock private void lock(long leaseTime, TimeUnit unit, boolean interruptibly) throws InterruptedException {//获取当前线程IDlong threadId Thread.currentThread().get…

参与 2023 第二季度官方 Flutter 开发者调查

Flutter 3.10 已经正式发布,每个季度一次的 Flutter 开发者调查也来啦!邀请社区的各位成员们填写: 调研旨在了解你对 Flutter 的满意程度以及对其各个子系统的反馈。你的意见将对我们改进 Flutter 的功能和性能产生重要影响。 在这次调研中&a…

Linux——软硬链接的理解

目录 那什么是链接? 链接命令的生成: 实验案例: 硬链接概念: 软链接概念: 情况1:删除myfile.txt: 情况2:重新创建一个新的myfile.txt文件: 软链接作用&#xff1…

推特引流:社交引流的技巧与方法

推特是一个广泛使用的社交媒体平台,可以用于引流和推广您的品牌、产品或服务。以下是一些社交引流的技巧和方法,可以帮助您在推特上获得更多的关注和流量: 优化个人资料:确保您的推特个人资料完整并具有吸引力。包括一个清晰的头…

yolov8-02 训练自己的数据集

1. 准备数据集 数据集格式跟yolov5一样,关于如何准备数据集可见之前的文章。 2. 创建 mydata.yaml 格式参考coco128.yaml,主要是 train / validate文件的存放路径,可以是同一个。 在ultralytics-main/ultralytics/datasets中,…