消息队列总结(面试)

 

一、为什么要使用mq

  1. 优点

  • 异步:并行处理提高系统吞吐量( 推送路由和渠道服务之间
  • 削峰:系统流量高峰期间,减少对服务器的额压力( 推送路由和渠道服务之间
  • 解耦:系统之间通过消息通信,发送者不依赖消费者;( 推送路由和渠道服务之间

    2.缺点

  • 系统可用性降低,mq挂掉,要考虑服务可用性
  • 系统复杂度提高,接入组件维护麻烦等
  • 数据一致性问题,调用ab两个接口, 使用mq后其中一个失败无法感知

技术选型

1、rabbitmq目前支持高并发,高吞吐、高性能,并且提供完善的统一后台管理,并且支持集群化、高可用架构,功能较为完善, 但基于erlang语言开发,针对其封装较难
经调研大多数一二线互联网公司都使用了rabbitmq支撑业务
2、kafka用户超高吞吐,高可用,常用于大量日志实时处理,大数据处理场景,实时数据同步等场景,例如配合spark。flink等技术使用
3、rocketmq阿里开源的java版本的高可用、高吞吐、支持分布式事务等特殊场景    

三、Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什么优缺点?

 ActiveMQ
RabbitMQ
RocketMQ
Kafka
ZeroMQ
单机吞吐量
比RabbitMQ低
2.6w/s(消息做持久化)
11.6w/s
17.3w/s
29w/s
开发语言
Java
Erlang
Java
Scala/Java
C
主要维护者
Apache
Mozilla/Spring
Alibaba
Apache
iMatix,创始人已去世
成熟度
成熟
成熟
开源版本不够成熟
比较成熟
只有C、PHP等版本成熟
订阅形式
点对点(p2p)、广播(发布-订阅)
提供了4种:direct, topic ,Headers和fanout。fanout就是广播模式
基于topic/messageTag以及按照消息类型、属性进行正则匹配的发布订阅模式
基于topic以及按照topic进行正则匹配的发布订阅模式
点对点(p2p)
持久化
支持少量堆积
支持少量堆积
支持大量堆积
支持大量堆积
不支持
顺序消息
不支持
不支持
支持
支持
不支持
性能稳定性
一般
较差
很好
集群方式
支持简单集群模式,比如’主-备’,对高级集群模式支持不好。
支持简单集群,'复制’模式,对高级集群模式支持不好。
常用 多对’Master-Slave’ 模式,开源版本需手动切换Slave变成Master
天然的‘Leader-Slave’无状态集群,每台服务器既是Master也是Slave
不支持
管理界面
一般
较好
一般
社区活跃度
版本更新慢,活跃慢
 
 
 
 
综上,各种对比之后,有如下建议:
1、早期使用ActiveMQ,但由于没经过大规模吞吐量场景的验证,社区也不是很活跃,不推荐;
2、RabbitMQ,代码开源,社区活跃度高,吞吐还可以,比较稳定,后台功能丰富,但erlang 语言阻止java从事者;
3、RocketMQ,阿里出品,但社区可能有突然黄掉的风险(目前 RocketMQ 已捐给  Apache ,但 GitHub 上的活跃度其实不算高)对自己公司技术实力有绝对自信的,推荐用 RocketMQ,否则回去老老实实用 RabbitMQ 吧,人家有活跃的开源社区,绝对不会黄。
所以 中小型公司 ,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择; 大型公司 ,基础架构研发实力较强,用 RocketMQ 是很好的选择。
如果是 大数据领域 的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。
 
 

如何保证可靠性传输(消息不丢失)

  • 生产者往队列写消息
rabbitmq:
  1. 事务(开启事务,发送消息,异常时回滚消息,由于同步阻塞等待成功,所以吞吐量低) 不推荐
  2. comfirm机制(信道上发布的消息都会指派一个唯一id,一旦消息投递到所有匹配队列上,会发送一个ack给生产者,反之会给个nack,生产者可以重试)
    异步不阻塞,等待成功回调或者失败回调,失败时可以记录日志和重试,吞吐量更高, 推荐
kakfa:生产者设置acks=all,只有leader和follower都接受成功后才能算生成成功,但是吞吐量偏低些 一般保证leader接受成功即可
  • 消息队列保存数据
rabbitmq:消息持久化,同时设置队列属性 durable为true和rabbitmq属性 deliveryMode=2, rabbitmq会持久化数据到磁盘上
kafka:topic每个分区paration顺序持久化到磁盘
  • 消费者消费时 丢失消息
    rabbitmq:设置autoack时,消费者还没成功时自动提交时,所以需要根据实际业务 设置手动确认,只有当消费成功后再提交确认
    kafka:关闭自动提交offset,手动提交offset,但是这样会导致消费变慢
 

如何保证顺序性消费

原因:
    rabbitmq:一个queue,多个consumer,c2比c1消费快
    kafka:
        一个topic,一个分区,一个consumer,内部使用多线程去消费
        一个topic,多个分区,多个consumer,内部使用多线程消费
解决办法:
    rabbitmq·:将保证顺序的消息生产到一个queue中,然后一个消费者去顺序消费即可;
    kafka:首先生产者可以 根据业务参数或者key指定到相同的分区中,保证业务顺序在一个分区中;然后消费者消费时可以采取单线程消费
或者多线程消费,多线程消费时根据业务参数路由到不同内存队列中,然后每个队列起一个线程去消费数据
 

为什么不应该对所有的 message 都使用持久化机制?

首先,必然导致性能的下降,因为写磁盘比写 RAM 慢的多,message 的吞吐量可能有 10 倍的差距。
其次,message 的持久化机制用在 RabbitMQ 的内置 cluster 方案时会出现“坑爹”问题。矛盾点在于,若 message 设置了 persistent 属性,但 queue 未设置 durable 属性,那么当该 queue 的 owner node 出现异常后,在未重建该 queue 前,发往该 queue 的 message 将被 blackholed ;若 message 设置了 persistent 属性,同时 queue 也设置了 durable 属性,那么当 queue 的 owner node 异常且无法重启的情况下,则该 queue 无法在其他 node 上重建,只能等待其 owner node 重启后,才能恢复该 queue 的使用,而在这段时间内发送给该 queue 的 message 将被 blackholed 。
所以,是否要对 message 进行持久化,需要综合考虑性能需要,以及可能遇到的问题。若想达到 100,000 条/秒以上的消息吞吐量(单 RabbitMQ 服务器),则要么使用其他的方式来确保 message 的可靠 delivery ,要么使用非常快速的存储系统以支持全持久化(例如使用 SSD)。另外一种处理原则是:仅对关键消息作持久化处理(根据业务重要程度),且应该保证关键消息的量不会导致性能瓶颈。

如何保证高可用的?

RabbitMQ 的集群(基于主从非分布式

单机模式:就是 Demo 级别的,一般就是你本地启动了玩玩儿的?,没人生产用单机模式

普通集群模式: 多个实例部署 ,其中 只有一个节点会保存queue完整数据 ,但是 每个实例会同步保存一份queue的元数据 ,通过元数据可以找到queue所在实例,当 消费时,当前实例没有该queue数据,则会根据元数据找到实际存放消息数据的节点;
优势:高吞吐量,集群中多个节点来服务某个 queue 的读写操作。
缺点: 当前访问数据没在该节点上, 集群内部可能产生大量数据传输 ;当q所在的节点挂掉, 可用性无法保证
镜像集群模式(高可用)
概念:每个节点(节点数量可配置)都有 queue 的完整镜像,包含 queue 的全部数据(元数据和消息内容)。当写消息到 queue 的时,都会自动把消息同步到多个实例的 queue 上。
如何配置:通过在管理控制台新增一个镜像集群模式的策略,指定的时候是可以要求数据同步到所有节点的,也可以要求同步到指定数量的节点,再次创建 queue 的时候,应用这个策略,就会自动将数据同步到其他的节点上去了。
优势:可用性高,当一个机器宕机了,其它机器(节点)还包含了这个 queue 的完整数据,别的 consumer 都可以到其它节点上去消费数据。
缺点:性能开销大,消息需要同步到所有机器上,导致网络带宽压力和消耗很重!RabbitMQ 一个 queue 的数据都是放在一个节点里的,镜像集群下,也是每个节点都放这个 queue 的完整数据。
kafka的集群(基于 分布式
分布式: 指消息数据是不是分散在多个节点上 ,kafka采取是:每个broker节点都有一部分topic数据

如何保证消息消费幂等性(重复消费)?

缘由:kafka提交消费消息offset时失败(消费者重启、提交超时等),再次消费时会重复消费已经消费的数据
如何解决:
如果是提交超时可以适当增大提交的时间或者减少提交的数量,最后还是要根据实际的业务进行唯一性判断,例如采取redis,数据库唯一性键

 

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

MQ中消息失效: 最好不要设置过期时间
RabbtiMQ 可以通过ttl设置过期时间的。如果消息在 queue 中积压超过一定的时间就会被 RabbitMQ 给清理掉,大量的数据会直接搞丢。我们可以采取一个方案,就是 批量重导 。大量积压的时候,我们当时就直接丢弃数据了,然后等过了高峰期以后,写程序,将丢失的那批数据,查出来,然后重新灌入 mq 里面去;

消息队列满了以后该怎么处理?

快速消费队列数据不要处理逻辑直接丢弃,然后后期通过临时程序查询出丢失的数据从新处理;

有几百万消息持续积压几小时怎么解决?

消息积压处理办法:临时紧急扩容:

 

先修复 consumer 的问题,确保其恢复消费速度,然后将现有 cnosumer 都停掉。
新建一个 topic,partition 是原来的 10 倍,临时建立好原先 10 倍的 queue 数量。
然后写一个临时的分发数据的 consumer 程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的 10 倍数量的 queue。
接着临时征用 10 倍的机器来部署 consumer,每一批 consumer 消费一个临时 queue 的数据。这种做法相当于是临时将 queue 资源和 consumer 资源扩大 10 倍,以正常的 10 倍速度来消费数据。
等快速消费完积压数据之后,得恢复原先部署的架构,重新用原先的 consumer 机器来消费消息。

设计MQ思路

首先这个 mq 得支持可伸缩性吧,就是需要的时候快速扩容,就可以增加吞吐量和容量,那怎么搞?设计个分布式的系统呗,参照一下 kafka 的设计理念,broker -> topic -> partition,每个 partition 放一个机器,就存一部分数据。如果现在资源不够了,简单啊,给 topic 增加 partition,然后做数据迁移,增加机器,不就可以存放更多数据,提供更高的吞吐量了?
其次你得考虑一下这个 mq 的数据要不要落地磁盘吧?那肯定要了,落磁盘才能保证别进程挂了数据就丢了。那落磁盘的时候怎么落啊?顺序写,这样就没有磁盘随机读写的寻址开销,磁盘顺序读写的性能是很高的,这就是 kafka 的思路。
其次你考虑一下你的 mq 的可用性啊?这个事儿,具体参考之前可用性那个环节讲解的 kafka 的高可用保障机制。多副本 -> leader & follower -> broker 挂了重新选举 leader 即可对外服务。
能不能支持数据 0 丢失啊?可以的,参考我们之前说的那个 kafka 数据零丢失方案。
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
探索全栈前端技术的魅力:HTML+CSS+JS+JQ+Bootstrap网站源码深度解析 在这个数字化时代,构建一个既美观又功能强大的网站成为了许多开发者和企业追逐的目标。本份资源精心汇集了一套完整网站源码,融合了HTML的骨架搭建、CSS的视觉美化、JavaScript的交互逻辑、jQuery的高效操作以及Bootstrap的响应式设计,全方位揭秘了现代网页开发的精髓。 HTML,作为网页的基础,它构建了信息的框架;CSS则赋予网页生动的外观,让设计创意跃然屏上;JavaScript的加入,使网站拥有了灵动的交互体验;jQuery,作为JavaScript的强力辅助,简化了DOM操作与事件处理,让编码更为高效;而Bootstrap的融入,则确保了网站在不同设备上的完美呈现,响应式设计让访问无界限。 通过这份源码,你将: 学习如何高效组织HTML结构,提升页面加载速度与SEO友好度; 掌握CSS高级技巧,如Flexbox与Grid布局,打造适应各种屏幕的视觉盛宴; 理解JavaScript核心概念,动手实现动画、表单验证等动态效果; 利用jQuery插件快速增强用户体验,实现滑动效果、Ajax请求等; 深入Bootstrap框架,掌握移动优先的开发策略,响应式设计信手拈来。 无论是前端开发新手渴望系统学习,还是资深开发者寻求灵感与实用技巧,这份资源都是不可多得的宝藏。立即深入了解,开启你的全栈前端探索之旅,让每一个网页都成为技术与艺术的完美融合!
探索全栈前端技术的魅力:HTML+CSS+JS+JQ+Bootstrap网站源码深度解析 在这个数字化时代,构建一个既美观又功能强大的网站成为了许多开发者和企业追逐的目标。本份资源精心汇集了一套完整网站源码,融合了HTML的骨架搭建、CSS的视觉美化、JavaScript的交互逻辑、jQuery的高效操作以及Bootstrap的响应式设计,全方位揭秘了现代网页开发的精髓。 HTML,作为网页的基础,它构建了信息的框架;CSS则赋予网页生动的外观,让设计创意跃然屏上;JavaScript的加入,使网站拥有了灵动的交互体验;jQuery,作为JavaScript的强力辅助,简化了DOM操作与事件处理,让编码更为高效;而Bootstrap的融入,则确保了网站在不同设备上的完美呈现,响应式设计让访问无界限。 通过这份源码,你将: 学习如何高效组织HTML结构,提升页面加载速度与SEO友好度; 掌握CSS高级技巧,如Flexbox与Grid布局,打造适应各种屏幕的视觉盛宴; 理解JavaScript核心概念,动手实现动画、表单验证等动态效果; 利用jQuery插件快速增强用户体验,实现滑动效果、Ajax请求等; 深入Bootstrap框架,掌握移动优先的开发策略,响应式设计信手拈来。 无论是前端开发新手渴望系统学习,还是资深开发者寻求灵感与实用技巧,这份资源都是不可多得的宝藏。立即深入了解,开启你的全栈前端探索之旅,让每一个网页都成为技术与艺术的完美融合!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值