RocketMQ面试题-未完
简述什么是rocketmq?rocketmq整体架构?
- rocketmq:“消息、事件、流”实时数据处理平台
- 整体架构:
- Producer:发布消息的角色
- Consumer:消息消费的角色,支持以推(push),拉(pull)两种模式对消息进行消费
- NameServer名字服务器:一个简单的 Topic 路由注册中心,支持 Topic、Broker 的动态注册与发现
- Broker代理服务器:负责消息的存储、投递和查询以及服务高可用保证
rocketmq执行流程
- 启动NameServer:NameServer启动后监听端口,等待Broker、Producer、Consumer连接,相当于一个路由控制中心
- 启动 Broker:与所有 NameServer 保持长连接,定时发送心跳包。心跳包中包含当前 Broker 信息以及存储所有 Topic 信息。注册成功后,NameServer 集群中就有 Topic跟Broker 的映射关系。
- 创建 Topic :需要指定该 Topic 要存储在哪些 Broker 上,也可以在发送消息时自动创建Topic。
- 生产者发送消息:生产者发送消息。启动时先跟 NameServer 集群中的其中一台建立长连接,并从 NameServer 中获取当前发送的 Topic存在于哪些 Broker 上,轮询从队列列表中选择一个队列,然后与队列所在的 Broker建立长连接从而向 Broker发消息。
- 消费者接受消息:消费者接受消息。跟其中一台NameServer建立长连接,获取当前订阅Topic存在哪些Broker上,然后直接跟Broker建立连接通道,然后开始消费消息。
rocketmq特点?
- 低延迟:通过优化消息存储和传输机制,能够支持每秒数百万级的消息吞吐量,同时保证消息传输的低延迟
- 高可靠性:支持多种消息存储策略(如同步刷盘、异步刷盘),确保消息在存储过程中的可靠性和数据一致性
- 事物支持:RocketMQ提供了事务消息的支持,允许开发者在发送消息的同时,保证消息的发送与业务操作的原子性
什么是RocketMQ的名字服务器
NameServer是一个简单的 Topic 路由注册中心,支持 Topic、Broker 的动态注册与发现。
主要包括两个功能:
- Broker管理,NameServer接受Broker集群的注册信息并且保存下来作为路由信息的基本数据。然后提供心跳检测机制,检查Broker是否还存活;
- 路由信息管理,每个NameServer将保存关于 Broker 集群的整个路由信息和用于客户端查询的队列信息。Producer和Consumer通过NameServer就可以知道整个Broker集群的路由信息,从而进行消息的投递和消费。
NameServer通常会有多个实例部署,各实例间相互不进行信息通讯。Broker是向每一台NameServer注册自己的路由信息,所以每一个NameServer实例上面都保存一份完整的路由信息。当某个NameServer因某种原因下线了,客户端仍然可以向其它NameServer获取路由信息。
简述RocketMQ的消息模型
RocketMQ 消息构成非常简单:
- topic,表示要发送的消息的主题。
- body 表示消息的存储内容
- properties 表示消息属性
- transactionId 会在事务消息中使用。
简述RocketMQ Producer 端的负载均衡机制 ?
生产者发送消息时,默认通过selectOneMessageQueue
方法选择队列。该方法采用轮询策略,按顺序从Topic下的所有队列中选取一个进行消息发送。当队列故障时,会通过容错策略调整选择逻辑。
RocketMQ的消费模式有几种?
在 Apache RocketMQ 有两种消费模式,分别是:
- 集群消费模式:当使用集群消费模式时,RocketMQ 认为任意一条消息只需要被消费组内的任意一个消费者处理即可。
- 广播消费模式:当使用广播消费模式时,RocketMQ 会将每条消息推送给消费组所有的消费者,保证消息至少被每个消费者消费一次。
集群消费模式适用于每条消息只需要被处理一次的场景,也就是说整个消费组会Topic收到全量的消息,而消费组内的消费分担消费这些消息,因此可以通过扩缩消费者数量,来提升或降低消费能力,是最常见的消费方式。
广播消费模式适用于每条消息需要被消费组的每个消费者处理的场景,也就是说消费组内的每个消费者都会收到订阅Topic的全量消息,因此即使扩缩消费者数量也无法提升或降低消费能力。
RocketMQ消息发送的三种方式/策略?
- 同步发送:最常用的方式,是指消息发送方发出一条消息后,会在收到服务端同步响应之后才发下一条消息的通讯方式,可靠的同步传输被广泛应用于各种场景,如重要的通知消息、短消息通知等。
- 异步发送:发送方发出一条消息后,不等服务端返回响应,接着发送下一条消息的通讯方式。
- 单向模式发送:发送方只负责发送消息,不等待服务端返回响应且没有回调函数触发,即只发送请求不等待应答。此方式发送消息的过程耗时非常短,一般在微秒级别。适用于某些耗时非常短,但对可靠性要求并不高的场景,例如日志收集。
为什么要保证消息有序性?如何保证?
如需保证消息生产的顺序性,则必须满足以下条件:
- 单一生产者: 消息生产的顺序性仅支持单一生产者,不同生产者分布在不同的系统,即使设置相同的分区键,不同生产者之间产生的消息也无法判定其先后顺序。
- 串行发送:生产者客户端支持多线程安全访问,但如果生产者使用多线程并行发送,则不同线程间产生的消息将无法判定其先后顺序。
满足以上条件的生产者,将顺序消息发送至服务端后,会保证设置了同一分区键的消息,按照发送顺序存储在同一队列中。
RocketMQ的消费模式?
MQ的消费模式可以大致分为两种,一种是推Push,一种是拉Pull。
Push是服务端主动推送消息给客户端,优点是及时性较好,但如果客户端没有做好流控,一旦服务端推送大量消息到客户端时,就会导致客户端消息堆积甚至崩溃。
Pull是客户端需要主动到服务端取数据,优点是客户端可以依据自己的消费能力进行消费,但拉取的频率也需要用户自己控制,拉取频繁容易造成服务端和客户端的压力,拉取间隔长又容易造成消费不及时。
Apache RocketMQ既提供了Push模式也提供了Pull模式。
RocketMQ如何处理pull请求?
RocketMQ相同的ConsumerGroup下消费者的负载均衡模式/消费方式?
- 集群模式:默认的消费方式,消息会被均匀分配到ConsumerGroup中的每个实例,每条消息仅被单个实例处理,适用于每条消息只需被处理一次的场景,消费进度由服务端维护,可靠性较高
- 广播模式:消息会被投递到ConsumerGroup中的每个实例,适用于每条消息被多台机器处理的场景,消费进度由客户端维护,可能出现重复消费;不支持顺序消息和重置消费位点
简述RocketMQ的Broker的存储机制和文件结构?
怎么判断MQ是否有消息堆积?如何处理?
详细简述RocketMQ 队列Queue分配算法 ?
平均分配策略:该策略通过计算
QueueCount / ConsumerCount
确定每个Consumer应分配的队列数量。若能整除,则每个Consumer平均分配;若不能整除,则多余队列按顺序逐个分配给Consumer环形平均策略:此策略基于环形图分配,无需预先计算每个Consumer应分配的队列数。消费者按顺序在环形图中逐个选择队列,实现动态负载均衡
一致性Hash策略:通过哈希函数将消息Key(如订单ID)映射到特定队列,确保相同Key的消息始终进入同一队列。此策略支持顺序消息处理
同机房策略:优先将队列分配给位于同一机房的消费者实例,减少网络延迟和跨机房通信压力
解释RocketMQ的rebalance机制
- rebalance:一种用于在消费者组中的消费者实例之间重新分配消息队列的机制,旨在提升消息的并行处理能力和系统的负载均衡
- 触发条件:
- ConsumerGroup中有Consumer加入或退出
- Broker端Topic的队列数量发生变化
- 可能带来的问题:
- 消费暂停:在只有一个consumer时,其负责消费所有队列,在新增了一个consumer后会出发Rebalance的发生,此时原consumer就需要暂停部分队列的消费,等到这些队列分配给新的consumer后,这些暂停消费的队列才能继续消费
- 消费重复:consumer在消费新分配给自己的队列时,必须接着之前consumer提交的消费进度的offset继续消费,然而默认情况下,offset是异步提交,这个异步性导致提交到Broker的offset与consumer实际消费的消息并不-致,这个不一致的差值就可能会重复消息消费(这里消费者并不是每次只获取一条消息,而是批量获取的)