消息队列mq

news2025/1/21 10:21:32

1. 为什么使用消息队列?

其实就是问问你消息队列都有哪些使用场景,然后你项目里具体是什么场景,说说你在这个场景里用消息队列是什么?

解耦、异步、削峰

2. 消息队列优缺点

2.1.优点

优点上面已经说了,就是在特殊场景下有其对应的好处解耦异步削峰

2.2.缺点

① 系统可用性降低

系统引入的外部依赖越多,越容易挂掉。本来你就是 A 系统调用 BCD 三个系统的接口就好了,ABCD 四个系统还好好的,没啥问题,你偏加个 MQ 进来,万一 MQ 挂了咋整?MQ 一挂,整套系统崩溃,你不就完了?如何保证消息队列的高可用,可以点击这里查看。

② 系统复杂度提高

硬生生加个 MQ 进来,你怎么保证消息没有重复消费?怎么处理消息丢失的情况?怎么保证消息传递的顺序性?头大头大,问题一大堆,痛苦不已。

③ 一致性问题

A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。

3. Kafka、ActiveMq、RabbitMq、RocketMq优缺点对比

特性ActiveMQRabbitMQRocketMQKafka
单机吞吐量万级,比 RocketMQ、Kafka 低一个数量级同 ActiveMQ10 万级,支撑高吞吐10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景
topic 数量对吞吐量的影响topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topictopic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源
时效性ms 级微秒级,这是 RabbitMQ 的一大特点,延迟最低ms 级延迟在 ms 级以内
可用性高,基于主从架构实现高可用同 ActiveMQ非常高,分布式架构非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用
消息可靠性有较低的概率丢失数据基本不丢经过参数优化配置,可以做到 0 丢失同 RocketMQ
功能支持MQ 领域的功能极其完备基于 erlang 开发,并发能力很强,性能极好,延时很低MQ 功能较为完善,还是分布式的,扩展性好功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用

综上,各种对比之后,有如下建议:

一般的业务系统要引入 MQ,最早大家都用 ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,所以大家还是算了吧,我个人不推荐用这个了。

后来大家开始用 RabbitMQ,但是确实 erlang 语言阻止了大量的 Java 工程师去深入研究和掌控它,对公司而言,几乎处于不可控的状态,但是确实人家是开源的,比较稳定的支持,活跃度也高。

不过现在确实越来越多的公司会去用 RocketMQ,确实很不错,毕竟是阿里出品,但社区可能有突然黄掉的风险(目前 RocketMQ 已捐给Apache,但 GitHub 上的活跃度其实不算高)对自己公司技术实力有绝对自信的,推荐用 RocketMQ,否则回去老老实实用 RabbitMQ 吧,人家有活跃的开源社区,绝对不会黄。

所以中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。

如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。

4. 如何保证消息队列的高可用?

5. 如何保证消息不被重复消费?幂等性

5.1.哪些情况下会导致重复消费

首先,比如 RabbitMQ、RocketMQ、Kafka,都有可能会出现消息重复消费的问题,正常。因为这问题通常不是 MQ 自己保证的,是由我们开发来保证的。挑一个 Kafka 来举个例子,说说怎么重复消费吧。

Kafka 实际上有个 offset 的概念,就是每个消息写进去,都有一个 offset,代表消息的序号,然后 consumer 消费了数据之后,每隔一段时间(定时定期),会把自己消费过的消息的 offset 提交一下,表示“我已经消费过了,下次我要是重启啥的,你就让我继续从上次消费到的 offset 来继续消费吧”。

但是凡事总有意外,比如我们之前生产经常遇到的,就是你有时候重启系统,看你怎么重启了,如果碰到点着急的,直接 kill 进程了,再重启。这会导致 consumer 有些消息处理了,但是没来得及提交 offset,尴尬了。重启之后,没被提交offset的消息会再次消费一次

5.2.幂等性

其实重复消费不可怕,可怕的是你没考虑到重复消费之后,怎么保证幂等性

其实还是得结合业务来思考,我这里给几个思路:

  • 比如你拿个数据要写库,你先根据主键查一下,如果这数据都有了,你就别插入了,update 一下好吧。
  • 比如你是写 Redis,那没问题了,反正每次都是 set,天然幂等性。

6. 如何保证消息可靠性传输?

这个是肯定的,用 MQ 有个基本原则,就是数据不能多一条,也不能少一条

  • 不能多,就是前面说的「重复消费和幂等性问题」
  • 不能少,就是说这数据别搞丢了

6.1.消费者弄丢了数据

手动提交消息

唯一可能导致消费者弄丢数据的情况,就是说,你消费到了这个消息,然后消费者那边自动提交了 offset,让 Kafka 以为你已经消费好了这个消息,但其实你才刚准备处理这个消息,你还没处理,你自己就挂了,此时这条消息就丢咯。

那么,只要关闭自动提交 offset,在处理完之后自己手动提交 offset,就可以保证数据不会丢。

但是此时确实还是可能会有重复消费,比如你刚处理完,还没提交 offset,结果自己挂了,此时肯定会重复消费一次,自己保证幂等性就好了。

6.2.Kafka弄丢了数据

kafka配置

这块比较常见的一个场景,就是 Kafka 某个 broker 宕机,然后重新选举 partition 的 leader。大家想想,要是此时其他的 follower 刚好还有些数据没有同步,结果此时 leader 挂了,然后选举某个 follower 成 leader 之后,不就少了一些数据?这就丢了一些数据啊。

生产环境也遇到过,我们也是,之前 Kafka 的 leader 机器宕机了,将 follower 切换为 leader 之后,就会发现说这个数据就丢了。

我们生产环境就是按照上述要求配置的,这样配置之后,至少在 Kafka broker 端就可以保证在 leader 所在 broker 发生故障,进行 leader 切换时,数据不会丢失。

所以此时一般是要求起码设置如下 4 个参数:

  • 给 topic 设置 replication.factor 参数:这个值必须大于 1,要求每个 partition 必须有至少 2 个副本。
  • 在 Kafka 服务端设置 min.insync.replicas 参数:这个值必须大于 1,这个是要求一个 leader 至少感知到有至少一个 follower 还跟自己保持联系,没掉队,这样才能确保 leader 挂了还有一个 follower 吧。
  • 在 producer 端设置 acks=all :这个是要求每条数据,必须是写入所有 replica 之后,才能认为是写成功了
  • 在 producer 端设置 retries=MAX (很大很大很大的一个值,无限次重试的意思):这个是要求一旦写入失败,就无限重试,卡在这里了。
  • unclean,leader,election,enable配置为false(不允许选择OSR中的从节点作为主节点)

6.3.生产者弄丢了数据

acks=all 

如果按照上述的思路设置了 acks=all ,一定不会丢,要求是,你的 leader 接收到消息,所有的 follower 都同步到了消息之后,才认为本次写成功了。如果没满足这个条件,生产者会自动不断的重试,重试无限次。

7. 如何保证消息的顺序性?

要想实现消息有序,需要从Producer和Consumer两方面来考虑。

如果对Kafka不了解的话,可以先看这篇博客《一文快速了解Kafka》。

针对消息有序的业务需求,还分为全局有序和局部有序。

  • 全局有序:一个Topic下的所有消息都需要按照生产顺序消费。

  • 局部有序:一个Topic下的消息,只需要满足同一业务字段的要按照生产顺序消费。例如:Topic消息是订单的流水表,包含订单orderId,业务要求同一个orderId的消息需要按照生产顺序进行消费。

7.1.全局有序

由于Kafka的一个Topic可以分为了多个Partition,Producer发送消息的时候,是分散在不同 Partition的。当Producer按顺序发消息给Broker,但进入Kafka之后,这些消息就不一定进到哪个Partition,会导致顺序是乱的。

因此要满足全局有序,需要1个Topic只能对应1个Partition。

而且对应的consumer也要使用单线程或者保证消费顺序的线程模型,否则消费端造成的消费乱序。

7.1.局部有序

生产者和消费者,指定Partition Key,保证局部有序

  1. 在发消息的时候指定Partition Key(Kafka内部实现会对其进行Hash计算,这样Partition Key相同的消息会放在同一个Partition)
  2. 每个消费者线程都指定Partition Key,这样该消费者只会消费这个分区的消息

消费者进程优化:在不增加partition数量的情况下想提高消费速度,每个消费者进程可以进行再次优化(实现以下功能)

  1. 每个消费者进程都维护N个内存队列,内存队列的规则是:通过hash函数,将具有相同key的msg,分发到相同的内存队列中
  2. 每个消费者进程都维护N个线程
  3. 线程和内存队列是1:1的,即单生产者单消费者模型

8. 如何解决消息队列的延时以及过期失效问题?

8.1.问题描述

如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决?

你看这问法,其实本质针对的场景是:

  1. 可能你的消费端出了问题,不消费了
  2. 消费的速度极其慢

接着就坑爹了,可能你的消息队列集群的磁盘都快写满了,都没人消费,这个时候怎么办?或者是这整个就积压了几个小时,你这个时候怎么办?或者是你积压的时间太长了,导致比如 RabbitMQ 设置了消息过期时间后就没了怎么办?

所以就这事儿,其实线上挺常见的,一般不出,一出就是大 case。一般常见于,举个例子,消费端每次消费之后要写 mysql,结果 mysql 挂了,消费端 hang 那儿了,不动了;或者是消费端出了个什么岔子,导致消费速度极其慢。

8.2.消息积压解决方案

关于这个事儿,我们一个一个来梳理吧,先假设一个场景,我们现在消费端出故障了,然后大量消息在 mq 里积压,现在出事故了,慌了。

几千万条数据在 MQ 里积压了七八个小时,从下午 4 点多,积压到了晚上 11 点多。这个是我们真实遇到过的一个场景,确实是线上故障了,这个时候要不然就是修复 consumer 的问题,让它恢复消费速度,然后傻傻的等待几个小时消费完毕。这个肯定不能在面试的时候说吧。

分析速度:一个消费者一秒是 1000 条,一秒 3 个消费者是 3000 条,一分钟就是 18 万条。所以如果你积压了几百万到上千万的数据,即使消费者恢复了,也需要大概 1 小时的时间才能恢复过来。

一般这个时候,只能临时紧急扩容了,具体操作步骤和思路如下:

  • 先修复 consumer 的问题,确保其恢复消费速度,然后将现有 consumer 都停掉
  • 增加 topic 的 partition 的个数
  • 提升消费者组的消费者数量,消费数 = 分区数 (二者缺一不可)
  • 消费者程序,增加并发,扩大消费线程

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

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

相关文章

并查集的原理及实现

Ⅰ. 并查集原理 在一些应用问题中,需要将 n 个不同的元素划分成一些不相交的集合。开始时,每个元素自成一个单元素集合,然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一个元素归属于那个集合的运算。适合于描述这…

前端基础_线型Line styles

线型Line styles 线型包括如下属性。 lineWidth value lineCap type lineJoin type miterLimit value 通过这些属性来设置线的样式。下面将结合实例来讲解一下各属性的应用及应用后的效果。 lineWidth属性 该属性设置当前绘线的粗细,属性值必须…

ArcGIS编辑绘制图斑又慢又难?这些高效的处理技巧你值得拥有!

GIS画图是不是画得很慢! 图斑修改是不是无从下手! 图纸矢量化是不是琐碎繁杂、工作量大! 其实,强大的ArcGIS有很多高效的图斑编辑技巧,掌握这些技巧,无论是绘制图斑、还是修改图斑,还是图纸矢量化,绝对让你事半功倍! NO.1—自动完成面 当你要绘制一个图斑的相邻图…

华为云桌面,企业云上办公为何都偏好它?

在众多云上办公产品中,华为云桌面基于华为云的三十年投入的技术强、资源多、创新快和更可靠的优势,在众多云上办公产品中脱颖而出,成为众多企业数字化转型道路上不二选择,类似于三一重工、中泰模具、小飞侠等企业都选择了华为云桌…

非递归前序、中序遍历代码推演出后序遍历代码(极其透彻)

一、前言 众所周知,二叉树的遍历方式有三种:前序遍历、中序遍历和后序遍历。 🍌 前序遍历:首先访问根节点,然后递归遍历左子树,最后递归遍历右子树。 🍌 中序遍历:首先递归遍历左…

pypower的简单应用1

目录 一、背景描述 二、如何打开IEEE30节点并进行潮流计算 三、如何修改已有模型参数 四、完整代码 五、注意事项 pypower与matpower非常类似,可以利用matpower学习pypower,当然也有一些不同之处。下面记录一下应用pypower解决的问题。 一、背景描述…

Java优先队列的代码实现过程详解

1.优先队列定义 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在某些情况下,我们可能需要找出队列中的最大值或者最小值,例如使用一个队列保存计算机的任务,一般情况下计算机的任务都是有优先…

《Python程序开发》期末作业

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 一、题目: 1 .选修课信息(1).xlsx,信息如下: 2 .学生选课信息表.xls,信息如下 3.任务 二、将文件中的信息导入数据库 …

脱水蔬菜开启蔬菜产业发展新道路 国内市场正不断扩大

根据观研报告网发布的《中国脱水蔬菜市场发展现状研究与投资前景预测报告(2022-2029年)》显示,脱水蔬菜又称复水菜,是将新鲜蔬菜经过洗涤、烘干等加工制作,脱去蔬菜中大部分水分后而制成的一种干菜,食用时只…

Netty实战与源码剖析(一)——浅谈NIO编程

1 前言 很久之前就想写与Netty相关的博客了,但由于个人时间安排的问题一直拖到了现在,借助这个机会,重新温习Java高级编程的同时,也把Netty实战以及源码剖析分享给各位读者。 2 Netty是什么? Netty is a NIO client …

Spring—Spring IOC

文章目录Spring IOC容器1. 什么是IOC2.IOC的核心原理IOC如何充当对象容器?具体什么作为对象容器?IOC的核心原理图3. IOC容器的底层原理IOC的实现,依赖于以下3门技术上边提到的三种技术如何实现IOC的呢?4.IOC(接口)————————…

官宣!CATCTF不日开赛!!

各位极客请注意! 2022.12.31 10:00—2023.01.01 17:00 攻防世界 x Nepnep x CATCTF 即将开赛 请做好参战准备! 本场赛事由攻防世界提供技术与平台支撑 部分赛题募集自各位爱猫人士 其他题目则由Nepnep的师傅们承包 赛事运维人员也将由志愿者师傅们…

一起Talk Android吧(第四百四十八回:UI控件之Switch)

文章目录概念介绍使用方法内容总结各位看官们大家好,上一回中咱们说的例子是"UI控件之TimePickerDialog",这一回中说的例是" UI控件之Switch"。闲话休提,言归正转,让我们一起Talk Android吧!概念介绍 我们在…

设计模式~简单工厂模式

简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。 工厂模式专门负责将大量有共同接口的类实例化。 工厂模式的几种形态: 简单工厂模式(Simple Factory):又称静态工厂方法模式工厂方法模式(Factory Method):又称多态…

云卷云舒:2022 数据库总结从Gartner到IDC

2022年尾已至,行业总结纷纷而至。Gartner 于12月13日发布了其 “2022 云数据库管理系统魔力象限”IDC于12月15日发布了 “2022年上半年中国关系型数据库软件市场跟踪报告”Gartner 的魔力象限,聚焦在 "Cloud Database",不再进行本地…

《Redis实战篇》三、优惠券秒杀

文章目录3.1 全局唯一ID3.2 Redis实现全局唯一Id3.3 添加优惠卷3.4 实现秒杀下单3.5 库存超卖问题分析3.6 乐观锁解决超卖问题3.7 优惠券秒杀-一人一单3.8 集群环境下的并发问题3.1 全局唯一ID 每个店铺都可以发布优惠券: 当用户抢购时,就会生成订单并保…

nginx+rtmp+OBS搭建音视频直播服务

文章目录OBSNginx-rtmpdocker方式野生方式推流hls单码流rtmp多码流拉流OBS 下载地址: http://www.obsproject.com.cn/download/https://obsproject.com/zh-cn/download 傻瓜式一路按照提示安装即可。 Nginx-rtmp docker方式 有很多个镜像可供选择,我…

3.0、Hibernate-延迟加载 1

3.0、Hibernate-延迟加载 1 Hibernate 延迟加载 也叫 惰性加载、懒加载; 使用延迟加载可以提高程序运行效率,Java 程序 与 数据库交互的频次越低,程序运行的效率就越高,所以我们应该尽量减少 Java 程序 与 数据库的交互次数&#…

“ 总有个人会捡起 七零八落的你 “

把我所有最好的那些东西 给从来不曾抛弃我的人 所幸音频:00:0003:50 | 01 | 我想象过漂洋过海的冒险 向往过孤身一人的江湖 也憧憬过无拘无束的高飞 但是 越长大我越发现 家人在我生命中占据着不可或缺 | 02 | “怎么都不要我” 贺子秋说出来这句话的时候我…

【Python机器学习】隐马尔可夫模型讲解及在中文分词中的实战(附源码和数据集)

需要源码和数据集请点赞关注收藏后评论区留言私信~~~ 隐马尔可夫模型(HMM)是关于时序的概率模型,它可用于标注等问题中 基本思想 假设一个盒子里可以装两个骰子,骰子的种类有四面的和六面的两种。现在进行猜骰子实验&#xff0c…