合 RocketMQ常见面试题
- 1.为什么要使用消息队列呢?
- 2.为什么要选择RocketMQ?
- 3.RocketMQ有什么优缺点?
- 4.消息队列有哪些消息模型?
- 5.那RocketMQ的消息模型呢?
- 6.消息的消费模式了解吗?
- 7.RoctetMQ基本架构了解吗?
- 8.那能介绍一下这四部分吗?
- NameServer
- Broker
- Producer
- Consumer
- 9.如何保证消息的可用性/可靠性/不丢失呢?
- 生产
- 存储
- 消费
- 10.如何处理消息重复的问题呢?
- 11.怎么处理消息积压?
- 12.顺序消息如何实现?
- 部分顺序消息
- 全局顺序消息
- 13.如何实现消息过滤?
- 14.延时消息了解吗?
- RocketMQ怎么实现延时消息的?
- 15.怎么实现分布式消息事务的?半消息?
- 16.死信队列知道吗?
- 17.如何保证RocketMQ的高可用?
- 18.说一下RocketMQ的整体工作流程?
- 19.为什么RocketMQ不使用Zookeeper作为注册中心呢?
- 20.Broker是怎么保存数据的呢?
- 21.说说RocketMQ怎么对文件进行读写的?
- 说说什么是零拷贝?
- 22.消息刷盘怎么实现的呢?
- 22.能说下 RocketMQ 的负载均衡是如何实现的?
- Producer的负载均衡
- Consumer的负载均衡
- 23.RocketMQ消息长轮询了解吗?
- RocketMq的消息是有序的吗?
- RocketMq事务消息的实现机制?
- RocketMq逻辑结构
- RocketMq数据存储结构
- RocketMq会有重复消费的问题吗?如何解决?
- RocketMq延迟消息?如何实现的?
- RocketMq是推模型还是拉模型?
- RocketMq的负载均衡
- RocketMq消息积压
- RocketMq物理部署结构
- 参考
1.为什么要使用消息队列呢?
消息队列主要有三大用途,我们拿一个电商系统的下单举例:
解耦:引入消息队列之前,下单完成之后,需要订单服务去调用库存服务减库存,调用营销服务加营销数据……引入消息队列之后,可以把订单完成的消息丢进队列里,下游服务自己去调用就行了,这样就完成了订单服务和其它服务的解耦合。
异步:订单支付之后,我们要扣减库存、增加积分、发送消息等等,这样一来这个链路就长了,链路一长,响应时间就变长了。引入消息队列,除了
更新订单状态
,其它的都可以异步去做,这样一来就来,就能降低响应时间。削峰:消息队列合一用来削峰,例如秒杀系统,平时流量很低,但是要做秒杀活动,秒杀的时候流量疯狂怼进来,我们的服务器,Redis,MySQL各自的承受能力都不一样,直接全部流量照单全收肯定有问题啊,严重点可能直接打挂了。
我们可以把请求扔到队列里面,只放出我们服务能处理的流量,这样就能抗住短时间的大流量了。
解耦、异步、削峰,是消息队列最主要的三大作用。
2.为什么要选择RocketMQ?
市场上几大消息队列对比如下:
总结一下:
选择中间件的可以从这些维度来考虑:可靠性,性能,功能,可运维行,可拓展性,社区活跃度。目前常用的几个中间件,ActiveMQ作为“老古董”,市面上用的已经不多,其它几种:
RabbitMQ:
优点:轻量,迅捷,容易部署和使用,拥有灵活的路由配置
缺点:性能和吞吐量不太理想,不易进行二次开发
RocketMQ:
- 优点:性能好,高吞吐量,稳定可靠,有活跃的中文社区
- 缺点:兼容性上不是太好
Kafka:
- 优点:拥有强大的性能及吞吐量,兼容性很好
- 缺点:由于“攒一波再处理”导致延迟比较高
我们的系统是面向用户的C端系统,具有一定的并发量,对性能也有比较高的要求,所以选择了低延迟、吞吐量比较高,可用性比较好的RocketMQ。
3.RocketMQ有什么优缺点?
RocketMQ优点:
- 单机吞吐量:十万级
- 可用性:非常高,分布式架构
- 消息可靠性:经过参数优化配置,消息可以做到0丢失
- 功能支持:MQ功能较为完善,还是分布式的,扩展性好
- 支持10亿级别的消息堆积,不会因为堆积导致性能下降
- 源码是Java,方便结合公司自己的业务二次开发
- 天生为金融互联网领域而生,对于可靠性要求很高的场景,尤其是电商里面的订单扣款,以及业务削峰,在大量交易涌入时,后端可能无法及时处理的情况
- RoketMQ在稳定性上可能更值得信赖,这些业务场景在阿里双11已经经历了多次考验,如果你的业务有上述并发场景,建议可以选择RocketMQ
RocketMQ缺点:
- 支持的客户端语言不多,目前是Java及c++,其中c++不成熟
- 没有在 MQ核心中去实现JMS等接口,有些系统要迁移需要修改大量代码
4.消息队列有哪些消息模型?
消息队列有两种模型:队列模型和发布/订阅模型。
队列模型
这是最初的一种消息队列模型,对应着消息队列“发-存-收”的模型。生产者往某个队列里面发送消息,一个队列可以存储多个生产者的消息,一个队列也可以有多个消费者,但是消费者之间是竞争关系,也就是说每条消息只能被一个消费者消费。
发布/订阅模型
如果需要将一份消息数据分发给多个消费者,并且每个消费者都要求收到全量的消息。很显然,队列模型无法满足这个需求。解决的方式就是发布/订阅模型。
在发布 - 订阅模型中,消息的发送方称为发布者(Publisher),消息的接收方称为订阅者(Subscriber),服务端存放消息的容器称为主题(Topic)。发布者将消息发送到主题中,订阅者在接收消息之前需要先“订阅主题”。“订阅”在这里既是一个动作,同时还可以认为是主题在消费时的一个逻辑副本,每份订阅中,订阅者都可以接收到主题的所有消息。
它和 “队列模式” 的异同:生产者就是发布者,队列就是主题,消费者就是订阅者,无本质区别。唯一的不同点在于:一份消息数据是否可以被多次消费。
5.那RocketMQ的消息模型呢?
RocketMQ使用的消息模型是标准的发布-订阅模型,在RocketMQ的术语表中,生产者、消费者和主题,与发布-订阅模型中的概念是完全一样的。
RocketMQ本身的消息是由下面几部分组成:
- Message
Message(消息)就是要传输的信息。
一条消息必须有一个主题(Topic),主题可以看做是你的信件要邮寄的地址。
一条消息也可以拥有一个可选的标签(Tag)和额处的键值对,它们可以用于设置一个业务 Key 并在 Broker 上查找此消息以便在开发期间查找问题。
- Topic
Topic(主题)可以看做消息的归类,它是消息的第一级类型。比如一个电商系统可以分为:交易消息、物流消息等,一条消息必须有一个 Topic 。
Topic 与生产者和消费者的关系非常松散,一个 Topic 可以有0个、1个、多个生产者向其发送消息,一个生产者也可以同时向不同的 Topic 发送消息。
一个 Topic 也可以被 0个、1个、多个消费者订阅。
- Tag
Tag(标签)可以看作子主题,它是消息的第二级类型,用于为用户提供额外的灵活性。使用标签,同一业务模块不同目的的消息就可以用相同 Topic 而不同的 Tag 来标识。比如交易消息又可以分为:交易创建消息、交易完成消息等,一条消息可以没有 Tag 。
标签有助于保持你的代码干净和连贯,并且还可以为 RocketMQ 提供的查询系统提供帮助。
- Group
RocketMQ中,订阅者的概念是通过消费组(Consumer Group)来体现的。每个消费组都消费主题中一份完整的消息,不同消费组之间消费进度彼此不受影响,也就是说,一条消息被Consumer Group1消费过,也会再给Consumer Group2消费。
消费组中包含多个消费者,同一个组内的消费者是竞争消费的关系,每个消费者负责消费组内的一部分消息。默认情况,如果一条消息被消费者Consumer1消费了,那同组的其他消费者就不会再收到这条消息。
- Message Queue
Message Queue(消息队列),一个 Topic 下可以设置多个消息队列,Topic 包括多个 Message Queue ,如果一个 Consumer 需要获取 Topic下所有的消息,就要遍历所有的 Message Queue。
RocketMQ还有一些其它的Queue——例如ConsumerQueue。
- Offset
在Topic的消费过程中,由于消息需要被不同的组进行多次消费,所以消费完的消息并不会立即被删除,这就需要RocketMQ为每个消费组在每个队列上维护一个消费位置(Consumer Offset),这个位置之前的消息都被消费过,之后的消息都没有被消费过,每成功消费一条消息,消费位置就加一。
也可以这么说,Queue
是一个长度无限的数组,Offset 就是下标。
RocketMQ的消息模型中,这些就是比较关键的概念了。画张图总结一下:
6.消息的消费模式了解吗?
消息消费模式有两种:Clustering(集群消费)和Broadcasting(广播消费)。
默认情况下就是集群消费,这种模式下一个消费者组共同消费一个主题的多个队列,一个队列只会被一个消费者消费
,如果某个消费者挂掉,分组内其它消费者会接替挂掉的消费者继续消费。
而广播消费消息会发给消费者组中的每一个消费者进行消费。
7.RoctetMQ基本架构了解吗?
先看图,RocketMQ的基本架构: