前言
本篇文章主要汇总RocketMQ面试题
问题及答案
- RocketMQ是什么? 一个开源的消息中间件平台,具有低延时,高吞吐,易使用的特点
- RocketMQ有哪些角色? Producer、Consumer、Broker、NameServer
- RocketMQ消息模型? 支持压力大的业务场景,具有高性能,高可靠,高实时性等特点。
- RocketMQ和Kafka有什么区别? RocketMQ:单机吞吐量更高,消息查询更容易,拥有更丰富的消息订阅模型。Kafka:适合大数据场景,拥有更好的水平扩展能力。
- RocketMQ的Broker角色是什么? 消息中转角色,负责存储消息,接受producer发送的消息并向consumer转发消息。
- 一个topic可以有多个queue吗? 可以,一个topic可以包含多个queue,producer可以选择向topic中的某个queue发送消息。
- consumed的概念? 消费进度,表示consumer已经消费了topic某queue到什么位置的消息。
- RocketMQ的消费方式? 支持push和pull两种模式。push是broker主动将消息推送给consumer;pull是consumer主动从broker拉取消息。
- 怎么实现延时消息? 通过设置消息的延时等级来实现。RocketMQ 支持18个延时等级,等级越高延时越长。
- RocketMQ的事务消息是什么? 一条事务消息要么全成功接收,要么全失败回滚。用在colnus之间的数据一致性问题。
- RocketMQ事务消息的原理是什么? 通过Prepared消息和Commit/Rollback消息来实现。Producer发送Prepare消息,接着发送Commit或者Rollback消息。
- RocketMQ的消费进度保存机制? RocketMQ的消费进度保存分为两级:Consumer端和Broker端。Consumer端实时记录自己已消费消息的offset;Broker定期批量更新该offset。
- RocketMQ的过滤消息? 支持SQL92标准的过滤语法,Consumer可以按条件筛选想要消费的消息。
- RocketMQ支持哪些订阅模式? 支持普通订阅、广播订阅和通配符订阅。
- 说一下消费者拉取方式的流程? 1)Consumer查询消息队列信息 2) consumer查询位点信息 3) consumer拉取消息 4) consumer消费消息 5) consumer更新位点
- Broker支持哪些消息存储方式? File、CommitLog、ConsumeQueue三种存储方式。
- 文件存储消息的文件格式? 消息内容实际存储在CommitLog文件中,索引信息存储在ConsumeQueue文件中。
- 默认的存储路径? ${user.home}/store/commitlog, ${user.home}/store/consumequeue
- Broker的HA机制是什么? 主从备份+快速容灾Failover
- NameServer的作用? 名称服务,管理集群中的Broker名称与地址的对应关系。Producer和Consumer通过NameServer查询Broker的地址信息。
- NameServer的部署建议? 部署双机或多机集群,避免单点故障。
- Producer发送消息的流程? 1)获取topic路由信息 2)根据路由信息选择queue 3)序列化消息 4)发送消息到broker 5)获取发送响应状态
- 消息如何进行负载均衡? 轮询选出一个queue,如果queue不可用再选一个,如果所有queue不可用则抛出异常。
- 消息如何进行重试? 通过设置重试次数和重试间隔来实现消息重试。
- 延时级别与时间的对应关系? 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h。
- 怎么控制消息的重试次数和间隔? 通过设置Producer中的 maxReconsumeTimes和reconsumeInterval来控制。
- 怎么实现定时消息? 通过设置Producer中的scheduleMessageService来实现定时消息。
- Zookeeper在RocketMQ中扮演什么角色? 用来做Broker的注册与发现,选主功能。
- Broker如何实现消息过滤? 通过sql表达式,支持>,<,=,>=,<=,<> (, )逻辑,AND,OR,NOT 关键字。
- 怎么控制Consumer的流量? 通过设置ConsumeFromWhere来控制Consumer初始位置以及设置ConsumeMessageBatchMaxSize控制每次拉取消息的数量。
- Broker支持批量消息吗?支持,通过设置Producer中的batchSize来实现批量发送。
- Consumer 支持批量消费吗?支持,通过设置ConsumeMessageBatchMaxSize来控制每次从Broker拉取的消息数量。
- RocketMQ的顺序消息是什么? 发送和消费顺序保证的消息,通过设置Producer中的messageDelayLevel来实现。
- RocketMQ怎么保证消息幂等? 同一消息的Message ID相同。
- 怎样实现消息的定制序列化? 实现Serialization接口,设置Producer中的serializer或consumer中的deserializer。
- 怎样查看Broker中的消息数据? 通过MQAdmin工具中的topicStatus, topicRoute,brokerStatus等命令查看。
- Broker重要的配置参数有哪些? sendMessageThreadPoolNums,pullThreadPoolNums等
- NameServer重要的配置参数? kvConfigPath等
- Producer重要的配置参数? groupName,sendMsgTimeout,compressMsgBodyOverHowmuch等
- Consumer重要的配置参数? groupName, consumeThreadMin, consumeThreadMax等
- 如何进行消息追踪? 通过设置Producer中的traceOn和Consumer中的traceOn来打开消息追踪功能。
- trace日志的级别有哪些? FATAL > ERROR > WARN > INFO > DEBUG > TRACE。
- 怎样查看trace日志? 在Broker或Producer或Consumer的配置文件中设置trace.file.name来指定日志文件路径。
- 支持多语言? 支持Java、C++、Python 等多种语言。
- 怎样防止消息重复消费? 先判断数据库或其他介质中是否已经消费过,如果没有则进行消费并更新状态。
- 怎样解决消息积压? 1)适当提高消费能力;2)减少生产频率;3)增加更多集群。
- Broker的默认端口号? 10911、10912
- NameServer的默认端口号? 9876
- Broker数据丢失的主要原因? 硬盘损坏、文件系统损坏等。
- 怎样避免消息重复? 发送消息前,Producer查询数据库中是否有相同消息,如果有则不发送。
- 怎样提高RocketMQ的吞吐量? 调大发送和消费线程池、批量发送消息、数据压缩、提高机器配置等。
- 怎样保证RocketMQ的高可用? 部署多Master、采用异步复制方式、NameServer集群部署、消费者连接多个Broker。
- 一个消息最长可以存活多久? 默认3天,可配置,消息过期时间由Message.setDelayTimeLevel()设置。
- 消息回查多久能查到? 默认3天,即消息最大存活时间,可配置MESSAGE_MAX_STORE_TIME。
- 发送同步消息会有什么问题? 消息发送卡住造成生产端阻塞。
- Broker中的页大小默认是多大? 4K,一页可存储多个消息,页满后再申请新页。
- 日志文件的存储格式? 消息存储在CommitLog ,索引存储在ConsumeQueue。
- 发送消息失败的主要原因? 网络异常、NameServer下线、Topic不存在、消息超大导致OOM等。
- Consumer中止时消息会有什么状态? 重新发送或转发到其他Consumer。
- 怎样提高消息大队列的处理能力? 加大消费者数量、提高机器配置、批量消费消息等。
- 消息消费失败会有什么影响? 消息重发或转发到其他消费者,造成消息延迟。
- 怎样设置消息的优先级? 暂不支持消息优先级,消息是先进先出。
- Broker的工作流程? 1) 收到生产者的消息写入CommitLog;2)消息发布到ConsumeQueue; 3)消费者取消息;4)消费者回复消费进度。
- 批量消息的好处与坏处? 好处:提高吞吐量;坏处:增加消息延迟。
- pull方式工作流程? 消费者主动向Broker拉取消息,Broker将消息返回给消费者,消费者确认消息后,Broker删除消息。
- push方式工作流程? Broker将消息主动推送给消费者,消费者确认消息后,Broker删除消息。
- 消息堆积的场景? 消息生产速度过快,而消费者处理不及时导致消息堆积。
- Producer发送同步消息会带来什么问题? 会阻塞生产者,影响消息发送。
- 怎么处理消费失败的消息? 等待重试或转发给其他消费者。
- Broker启动参数有哪些? namesrvAddr、brokerClusterName、brokerName等。
- 消息回溯的方法? 使用rocketmq-console工具、通过时间戳查询等。
- 顺序消息的实现原理? 消息发送时加上队列编号,消费时按队列编号顺序消费。
- 消息延迟的实现原理? 在消息发送时设置延迟等级,Broker在写入 CommitLog 后会定期检查消息是否到期。
- Broker主从复制机制? 主从异步复制,Master将消息发送给Slave,Slave写入消息。
- consumer端消费进度的作用? 用于记录消费群组的消费位置,避免重复消费。
- 怎样防止消息丢失? 1)同步刷盘 2)主从复制 3)消息持久化
- Broker启动常见的错误? 端口冲突、磁盘空间不足、NAME Server未启动等。
- 单播订阅与广播订阅的区别? 单播订阅会将消息投递到指定队列,广播订阅会将消息投递到所有队列。
- 集群部署时NameServer的个数最好是什么? 建议2n+1台,n>0,保证高可用。
- RocketMQ的消息存储结构? 消息内容存储在CommitLog,消息索引存储在ConsumeQueue。
- 消息查询支持哪些条件? 支持消息key、tags、它们的组合等作为查询条件。
- 消息过滤的原理是什么? Broker根据ConsumeQueue中的消息属性进行过滤,只返回满足条件的消息。
- 怎样处理重复投递消息? 在消费方法中判断消息是否被消费过,如果没有消费则进行消费,并标记该消息已被消费。
- 顺序消息实际应用场景? 订单生成、账单生成。
- RocketMQ的线程模型? 1)发送线程池 2) 拉取线程池 3) 消费线程池。
- comsumeQueue数据格式? queueID+offset+size+消息内容。
- 同步刷盘的设置及意义? flushDiskType=SYNC_FLUSH 设置,意义是消息写入CommitLog后强制刷盘,保证消息不丢失。
- 批量发送消息的好处? 提高生产者吞吐量,减少网络调用次数。
- 批量拉取消息的好处? 提高消费者吞吐量,减少网络调用次数。
- 消息过滤某个key的SQL语句? KEYS LIKE 'KEY%' 用于过滤ksy以KEY开头的消息。
- 消息回溯的方法有哪些? 根据时间戳查询、根据消息KEY查询、根据消息TAG查询。
- RocketMQ的消息类型? 普通消息、定时消息、延时消息、顺序消息、事务消息。
- 如何保证消息顺序? 发送方生成全局唯一的 queueId 标识,消费方按 queueId 消费。
- 如何避免重复消费? 1) 消费前查询数据库、缓存是否消费过。2) 采用增量消费方式,每次消费一定量数据。3) 掉线后从上次消费位置开始消费。
- RocketMQ消息重试机制? 消息发送失败会自动重试,重试间隔可以设置,超过最大重试次数消息最终失败。消息消费失败也会定期重试。
- 怎样设置较低的消息延迟? 设置较小的消息延迟等级,越小延迟越短。
- RocketMQ的事务消息适用场景? 分布式事务场景,用于数据一致性。
- 怎样查询RocketMQ统计信息? 通过Monitor功能统计Broker吞吐量、延迟、生产者、消费者信息等。
- 消息过滤通过设置哪些属性实现? 消息TAG、消息KEY。
- RocketMQ HA机制是什么? 1) 主从Broker,主Broker下线后从Broker顶替。2) NameServer集群,某个NameServer下线后其它NameServer继续提供服务。3) 消费者可以连接多个Broker。
- RocketMQ的顺序消息是如何实现的? 顺序消息主要依靠全局唯一的queue ID来实现。发送消息时,producer 需要指定相同的 queue ID,broker会根据queue ID将消息存入同一个队列中,consumer 消费时也需要按照queue ID来消费,这样就能达到消费顺序的目的。
- RocketMQ支持事务消息吗?支持,通过Prepared消息和Commit/Rollback消息来实现。
- RocketMQ的延时消息是如何实现的? 通过设置消息的延时等级来实现。RocketMQ支持18个延时等级,等级越高延时越长。Broker会定期扫描消息,一旦消息到达延时时间就会变为可消费状态。
- RocketMQ的广播订阅模式适用于什么场景?
适用于一条消息需要被多个消费者消费的场景,例如推送业务。广播订阅会将消息投递到所有队列,实现一对多的消息分发。 - RocketMQ的过滤消息是如何实现的?
RocketMQ支持SQL92标准的过滤语法,Consumer可以通过Destination进行消息过滤。Broker在发布消息到ConsumeQueue时,会根据Consumer的过滤语法过滤掉不匹配的消息,只将匹配的消息发布。 - RocketMQ的消费进度保存机制是什么?
RocketMQ的消费进度主要保存消费者消费的offset信息。offset由Consumer控制,Consumer会将offset信息周期性发送给Broker;同时Broker也会定期将消费者的offset信息保存到文件中,以防Consumer异常宕机 offset丢失。 - RocketMQ的事务消息波及的角色有哪些?
主要包括:TransactionProducer(发送Prepare和Commit/Rollback消息)、MQBroker(存储消息并回查状态)、TransactionListener(接收TransactionProducer的回调)。 - RocketMQ的顺序消息是基于队列的吗?
是的,RocketMQ的顺序消息是基于全局唯一的queue ID来实现的。生产者发送消息时指定相同的queue ID,Broker根据queue ID将消息存入同一个队列,消费者消费时也需要按queue ID顺序消费。 - RocketMQ的消费模式有哪两种?
RocketMQ支持PUSH和PULL两种消费模式:
PUSH模式:Broker主动推送消息给Consumer。
PULL模式:Consumer主动从Broker拉取消息。 - RocketMQ的消息存储结构是什么?
RocketMQ的消息存储主要分为两部分:
CommitLog:消息主体内容的存储,采用 mmap 映射方式存储消息;
ConsumeQueue:消息消费队列,主要存储消息的索引,用于查找CommitLog中消息内容。 - RocketMQ的Filter SQL支持哪些语法?
RocketMQ的Filter SQL支持以下语法:
数值比较:>、<、=、>=、<=、<>
逻辑运算:AND、OR、NOT
字符匹配:LIKE
例如:
SQL92 SQL= "age>18 AND name LIKE 'J%'"
TAG IN ('beijing','shanghai')
KEYS NOT IN ('k1') - RocketMQ的Consumer端消费进度作用是什么?
Consumer端的消费进度主要用于记录Consumer消费情况,避免重复消费。Consumer会定期将消费进度信息发送给Broker,Broker收到后会更新文件记录,方便Consumer宕机重启后继续消费。 - RocketMQ的Batch消息最大大小是多少?
RocketMQ的Batch消息最大大小默认为4MB,可以通过Broker的maxMessageBytes属性配置,Producer也可以通过maxMessageSize属性覆盖。如果某条消息超过maxMessageSize,它将作为一个批次单独发送。 - RocketMQ的消息过滤在哪个环节实现?
RocketMQ的消息过滤主要在Broker发布消息到ConsumeQueue的过程中实现。Broker会根据Consumer指定的过滤语法过滤不满足条件的消息,只将满足过滤条件的消息发布到ConsumeQueue。 - RocketMQ的消费进度保存的两级是什么意思?
RocketMQ的消费进度保存分为Consumer级别和Broker级别两级:
Consumer级别:Consumer会实时记录自己消费的位点信息,用于自己重启从上次断点开始消费。
Broker级别:Broker会定期批量更新所有的Consumer消费位点信息,用于Cluster其他Broker在重启时初始化Consumer位点。 - RocketMQ的消息查询支持哪些条件?
RocketMQ的消息查询支持以下条件:
根据消息Key查询
根据消息Tag查询
根据消息ID查询
根据时间戳查询
组合查询(Key+Tag、Key+时间戳) - RocketMQ的广播订阅适用于什么场景?
RocketMQ的广播订阅适用于一条消息需要被多个Consumer消费的场景,例如:
消息推送:一个消息需要推送给多个用户。
日志分发:一条日志需要分发到多个日志处理系统。
广播订阅会将消息发布到所有队列,实现一对多的消息分发。 - RocketMQ的Consumer端消费进度保存机制?
RocketMQ的Consumer消费进度主要由Consumer自己控制,保存方式有两种:
文件保存:Consumer将位点定期写入到文件,用于自己 restart 后恢复消费。
Broker保存:Consumer会定期将消费位点信息上报给Broker,Broker收到后更新文件记录。重启时Broker会将位点信息推送给Consumer。 - RocketMQ的消息发送流程是什么?
RocketMQ的消息发送流程如下: - Producer获取topic路由信息,包括queue信息和broker信息。
- 选择目标队列,如果队列不可用则重试其他队列。
- 序列化消息。
- 连接Broker,发送消息。
- 获取发送结果,成功或失败。发送失败会重试。
- 成功发送后,等待Broker的响应。
- RocketMQ的Consumer端消息拉取流程是什么?
RocketMQ的Consumer端消息拉取流程如下: - Consumer查询topic路由信息和消费进度。
- 计算拉取位点,如果是首次消费则从头开始消费。
- 连接Broker,发送拉取请求。
- Broker返回消息到Consumer。
- Consumer消费消息。
- Consumer更新消费进度,并定期发送至Broker。
- RocketMQ的定时消息是如何实现的?
RocketMQ的定时消息是通过ScheduledMessageService实现的。其原理是: - 生产者发送消息时,在消息属性中指定定时时间。
- Broker在写CommitLog后,不会立即发布消息到ConsumeQueue。
- Broker有个定时任务会扫描CommitLog,检查是否有定时消息到期。
- 到期的定时消息会被发布到ConsumeQueue,变为可消费状态。
- Consumer消费ConsumeQueue中的定时消息。
此机制需要Broker定期扫描,会带来一定的性能损耗,所以定时精度会有限制。 - RocketMQ的顺序消息的实现原理 ?
RocketMQ的顺序消息主要依靠全局唯一的queue ID来实现。其原理是: - 生产者发送顺序消息时,会指定相同的queue ID。
- Broker收到消息后,会根据queue ID hash到同一个队列中。
- 消费者消费消息时,需要按queue ID顺序消费。
- 由于queue ID全局唯一,所以可以保证不同生产者的消息按 queue ID有序。
此机制实现简单,消费复杂度O(1),适合大规模顺序消费场景。 - RocketMQ的过滤消息和SQL92有什么关系?
RocketMQ的消息过滤语句支持SQL92标准的一部分语法,主要包括:
数值比较:>、<、=、>=、<=、<>
逻辑运算:AND、OR、NOT
字符匹配:LIKE
Broker会解析这些语法,过滤不满足条件的消息,所以Consumer可以通过标准的SQL方式灵活配置不同的过滤逻辑。 - RocketMQ的Batchsizes参数代表什么?
Batchsizes参数代表RocketMQ批量发送消息的大小,当一批消息体积超过Batchsizes时,会作为一个批次单独发送。
其好处是:
提高生产者的发送吞吐量。减少网络IO次数,提高网络利用率。
缺点是:
增加消息发送延迟。批量发送会等待一定时间进行批量聚合。
所以需要根据实际场景选择合适的批次大小,一般不大于4MB。 - RocketMQ的消息查询类型有哪些?
RocketMQ支持以下几种消息查询类型:
根据消息Key查询
根据消息Tag查询
根据消息ID查询
根据消息存储时间戳查询
组合查询(Key+Tag, Key+时间戳)
这些查询类型可以配合RocketMQ提供的工具 queryingMessage进行消息回溯和跟踪。 - RocketMQ的事务消息实现原理是什么?
RocketMQ的事务消息实现原理是: - 生产者发送Prepare消息。
- Broker接受Prepare消息,写入CommitLog,返回Prepare消息的LocalTransactionId。
- 生产者本地事务执行,如果提交则发送Commit消息,回滚则发送Rollback消息。
- Broker接收到Commit消息,发布Prepare消息到ConsumeQueue。接收到Rollback消息则删除Prepare消息。
- 消费者消费ConsumeQueue中的消息。
此机制通过Prepare、Commit、Rollback三种消息类型来控制消息最终提交或回滚,实现分布式事务最终一致性。 - RocketMQ的延时消息有何作用?
RocketMQ的延时消息主要有以下作用: - 定时任务:发送延时消息,在指定时间被消费,实现定时任务的功能。
- 订单超时检查:发送延时消息,如果在指定时间内没有收到支付则消费消息发出提醒。
- 会员生日祝福:提前指定时间发送延时消息,准确在会员生日当天发送祝福。
- 限购秒杀:发送延时消息,在指定时间展示商品并消费消息开始秒杀活动。
所以延时消息常用于需要在将来的某个时间点执行任务或消费消息的场景。 - RocketMQ的Consumer端消息拉取方式有什么区别?
RocketMQ支持PUSH和PULL两种消费模式,主要区别是:
PUSH模式:
Broker主动推送消息给Consumer,Consumer消费完消息后确认消费。
优点:消费端零代码,消费者宕机时Broker仍然推送。
缺点:推送速度受限,扩展性差。
PULL模式:
Consumer主动到Broker拉取消息消费,拉取完成后确认消费位点。
优点:消费速度不受Broker影响,扩展性好。
缺点:Consumer宕机时无法拉取消息,存在消息补偿的开发成本。
所以根据实际业务场景选择合适的消费模式。一般推荐 pull 模式并开发重试/补偿机制。 - RocketMQ的消息重试机制是什么?
RocketMQ消息重试机制是指: - 消息发送失败,会自动进行重试,重试间隔可配,超过最大重试次数消息发送终止。
- 消息消费失败,Consumer会定期从失败位置重试,重试次数可配,超过最大重试次数则丢弃消息。
消息重试机制可以尽量避免消息丢失,保证高可靠性。同时也可以避免重复消费,保证Exactly-Once语义。
RocketMQ的重试机制为开发者处理失败场景提供了便利,省去了大量失败重试的开发成本。 - RocketMQ的事务消息的应用场景是什么?
RocketMQ的事务消息主要适用于分布式事务场景,典型的应用场景有: - 电商交易下单:下单后发送Prepare消息,支付成功后发送Commit消息完成下单,支付失败后发送Rollback消息取消下单。
- 账务系统账目更新:发送Prepare消息表示账目变更意向,确认后发送Commit消息完成变更,回滚发送Rollback消息。
- 库存系统库存扣减:发送Prepare消息表示库存扣减意向,确认后发送Commit消息完成扣减,回滚则发送Rollback消息回滚库存。
- 订单生成:发送Prepare消息表示开始生成订单,生成成功发送Commit消息完成,失败则发送Rollback消息。
所以事务消息适用于需要保证最终数据一致性的分布式场景,通过消息最终Commit或Rollback来决定数据的最终状态。 - RocketMQ的顺序消息适用场景是什么?
RocketMQ的顺序消息主要适用于以下场景: - 订单生成:保证订单ID有序生成。
- 账单生成:保证账单流水号有序。
- 日志采集:保证不同服务器的日志有序聚合。
- 大范围ID生成:需要全局有序的ID生成系统。
所以顺序消息适用于需要根据消息生成顺序进行消费的场景, RocketMQ可以通过queue ID来保证不同生产者的消息能有序消费。 - RocketMQ的Broker支持哪些机制?
RocketMQ的Broker支持以下机制: - 主备复制:Broker主节点下线后,备节点自动切换为主节点。
- 定时任务:支持定时消息、文件清理等定时任务。
- 信息统计:支持统计 topic、Consumer 等信息。
- 过滤机制:支持基于 tag 或 sql92 的消息过滤。
- 延时机制:支持基于级别的消息延时。
- 批量机制:支持批量发送、拉取消息。
- 顺序机制:支持基于 queue ID 的消息有序。
- 重试机制:支持消息发送失败重试及消费失败重试。
- 高可用:支持主备部署、磁盘冗余等机制。
- 负载均衡:支持基于权重的Consumer负载均衡。
所以Broker具有高可靠、高可用、高性能等特点,是RocketMQ的核心组件。 - RocketMQ的Broker主从部署有何好处?
RocketMQ的Broker主从部署有以下好处: - 高可用:主Broker下线后,从Broker自动升为主Broker,业务不中断。
- 容灾备份:主Broker数据同步到从Broker,主节点故障可以从从节点恢复数据。
- 平滑升级:升级主Broker时可以先升级从Broker,然后切换主从关系,实现平滑升级。
- 读写分离:主Broker写消息,从Broker读消息,分散读压力。
- 监控支撑:可以对不同Broker的运行指标进行对比监控。
所以 Broker主从部署是RocketMQ实现高可用和高可靠的重要手段,为RocketMQ的稳定运行提供了重要保障。 - RocketMQ的事务消息与具有全局事务的消息系统有何不同?
与具有全局分布式事务的消息系统相比,RocketMQ的事务消息有以下不同: - RocketMQ事务消息不具备全局事务,每个消息只支持一个生产者和一个Broker之间的事务。不支持跨多个主题或Broker的分布式事务。
- RocketMQ事务消息不支持XA规范,不支持跟第三方数据库等进行分布式事务。只支持Producer和Broker之间的事务消息最终提交或回滚。
- RocketMQ事务消息不提供真正的数据横向一致性保证。只能保证Producer与Broker之间相关消息的状态一致,但无法跟数据源实时保持强 一致。
- RocketMQ事务消息提供的只是消息最终一致性,无法保证数据源的ACID特性。数据源的事务还需要应用自行控制。
所以,RocketMQ事务消息主要用于消息级别的最终一致性控制,无法提供全面且强力的分布式事务支持。真正的分布式事务还需要借助XA事务管理器等实现。 - RocketMQ的延时队列与定时任务有何区别?
延时队列:
消息发送时设置延时等级,过了指定时间消息变为可消费状态。
适用于周期性调度、等待事件触发后消费等场景。
由Broker的Timer任务扫描和控制消息变更状态,有一定延时不精确性。
定时任务:
通过Broker的ScheduledMessageService在指定时间拉取队列消费消息。
适用于固定频率的调度任务。
由ScheduledMessageService的Timer任务控制消息消费时间,可以实现较高精度的定时消费。
需要Consumer配合,才能真正实现消息的定时调度。
所以,延时队列侧重于消息的延迟投递和消费,定时任务更侧重于实现高精度的定时调度,两者可以结合使用实现更复杂的定时业务逻辑。延时队列由Broker自行控制,定时任务需要Consumer参与协作。 - RocketMQ的Broker支持哪些持久化方式?
RocketMQ的Broker支持以下持久化方式: - ASYNC_FLUSH: 异步刷盘,消息写入PageCache后立即返回,定期后台刷盘。低延迟但可能消息丢失。
- SYNC_FLUSH: 同步刷盘,消息写PageCache后立即刷盘并返回。无消息丢失但延迟较高。
- TRANSFER_QUEUE:使用单独线程异步刷盘,主线程立即返回。 then 刷盘失败消息重试,最终保证持久化。
- MAPPED_FILE: 使用固定大小文件循环写,文件满后写入新文件。然后定期归档合并文件。
所以RocketMQ通过上述多种持久化方式实现消息的高可靠持久化,可以根据实际需要选择合适的持久化方式。一般推荐TRANSFER_QUEUE,既保证低延迟又实现消息零丢失。 - RocketMQ的Consumer端线程模型有何优劣?
RocketMQ的Consumer端支持以下线程模型: - 单线程:一个Consumer实例只有一个消费线程,吞吐量受限但简单。
- 固定线程数:一个Consumer设置固定的消费线程数,可以增大吞吐量,需要自己控制线程并发避免消息乱序。
- 动态线程:由RocketMQ根据队列积压情况自动调整消费线程数,吞吐量高且无需手动控制,但会有一定消息乱序。
所以不同的线程模型有以下优劣:
单线程:简单但吞吐量低。
固定线程:吞吐量高但需要自己控制线程并发。
动态线程:吞吐量高且自动调度,但会有少量消息乱序。
所以可以根据业务需求选择合适的线程模型。如果需要严格顺序只能选择单线程;如果可以容忍少量消息乱序,动态线程是较好选择。固定线程可自定义并发线程数平衡吞吐量和有序性。 - RocketMQ的Consumer如何保证消息不被重复消费?
RocketMQ的Consumer可以通过以下方式保证消息不被重复消费: - 消费前检查本地缓存或数据库是否已消费,如果消息ID已存在则跳过当前消息。
- 消费消息成功后,记录消息ID到本地缓存或数据库。
- 增量消费,每个Consumer实例每次只消费一定量消息,不会重复消费。
- 从上次消费断点开始消费,不会重复消费已消费过的消息。
- 采用广播模式,让固定的一个Consumer实例消费指定话题的消息。其他实例不消费。
- 根据消息的唯一键像Hash等分布消息,每个实例只消费自己的分区消息。
所以通过消息去重、消息分区、增量消费、断点续消费等方式可以避免RocketMQ消息被重复消费。但需要应用自行记录消费信息实现。RocketMQ仅提供消息存储和投递服务。
重复消费问题的根本解决还需要业务在消费端做好幂等性控制。RocketMQ的机制可以尽量避免重复消费的发生,但无法完全杜绝。 - RocketMQ的延时消息与Kafka的延时队列有何不同?
RocketMQ和Kafka的延时消息/队列有以下主要不同:
延时精度:
RocketMQ: 支持 1s ~ 24h,延时精度秒级,由Broker扫描定时调整消息状态。
Kafka: 支持毫秒级延时,基于时间戳排序写入特定的延时主题。
实现机制:
RocketMQ: 延迟消息写入普通主题,由Broker定时调度发布到ConsumeQueue。
Kafka: 消息写入指定的延时主题,根据时间戳顺序消费实现延时。
吞吐量:
RocketMQ: 定时扫描调度,吞吐量略低。单Broker支持百万级TPS。
Kafka: 不依赖定时扫描,吞吐量较高。单Broker支持上千万TPS。
消费方式:
RocketMQ: 消费普通主题的消息,消费方式不变。
Kafka: 消费指定延时主题的消息,需要根据时间戳顺序消费。
可靠性:
RocketMQ: 延时消息存储在CommitLog,可靠性高。
Kafka: 延时消息存储在普通主题,可靠性一般。
所以两者延时机制不同,Kafka延时更精确但依赖时间戳有序性,RocketMQ提供秒级延时但通过定时任务实现,相比更易于使用与理解。根据具体需求选择不同的框架。 - RocketMQ的事务消息与Kafka的事务消息有何不同?
RocketMQ和Kafka的事务消息有以下主要不同:
实现机制:
RocketMQ: 支持本地事务,通过Prepare/Commit/Rollback消息控制最终状态。
Kafka: 支持分布式事务,通过事务协调器控制跨主题和跨Consumer Group的事务状态。
事务范围:
RocketMQ: 生产者与单Broker的事务范围。
Kafka: 可以跨主题、跨群组、甚至跨Kafka集群的事务范围。
事务consistency:
RocketMQ: 消息最后一致性,不能保证数据源的强一致性。
Kafka: 依赖外部的数据库等来保证跨系统的数据一致性。
吞吐量:
RocketMQ: 事务消息吞吐量略低,单Broker支持上万TPS。
Kafka: 吞吐量较高,单Broker支持百万级TPS。
可靠性:
RocketMQ: 基于Broker HA和持久化,事务消息可靠性高。
Kafka: 依赖Zookeeper等来保证事务协调的高可用,可靠性较RocketMQ稍差。
所以RocketMQ提供简单的分布式事务消息最终一致性方案;Kafka依靠强大的事务协调服务实现了真正的分布式事务支持。根据需求选择不同的解决方案。 - RocketMQ的Broker如何实现高可用?
RocketMQ的Broker主要通过以下方式实现高可用: - 主备Broker:部署两个Broker,一个主一个备,主Broker故障会自动切换到备Broker。
- 无单点:Broker无依赖,直接部署多个Broker即可。不依赖任何中间件如Zookeeper。
- 定时任务高可用:Broker的定时任务信息存储在本地,主备Broker信息同步,故障转移后定时任务仍然执行。
- 磁盘冗余:Broker支持磁盘冗余部署,单块盘故障不会导致服务中断。
- 容灾恢复:主备Broker数据实时同步,主节点故障可以快速从备节点恢复数据实现容灾。
- 支持Rolling Upgrade:可以平滑的升级Broker版本,不影响运行多个不同版本的Broker。
所以RocketMQ通过去中心化设计、主备部署、数据同步、磁盘冗余等手段实现了Broker的高可用。平滑升级也避免了服务中断. - RocketMQ Broker主备切换工作机制是什么?
RocketMQ Broker主备切换机制是: - 主Broker启动时会在NameServer注册自身为主Broker。
- 备Broker启动时会在NameServer注册自身为备Broker,并指定对应主Broker。
- 备Broker会维持与主Broker的网络长连接,实时监控主Broker状态。
- 主Broker网络异常或JVM停止超过一定时间(默认30s),备Broker会取消主备关系,把自身注册为主Broker。
- 主Broker恢复后会发现已经有新的主Broker在运行,那么就会注册为备Broker,恢复主备关系。
所以工作机制是:根据NameServer注册的Broker角色以及主备Broker之间的心跳检测来自动进行故障转移和恢复,实现Broker高可用。
Broker角色变更时,会通知相关生产者和消费者切换到新主Broker,实现对客户端的透明转移。 - RocketMQ Broker何时会触发主备切换?
RocketMQ Broker主备切换会在以下情况下触发: - 主Broker进程JVM停止或退出,超过指定时间(默认30s)未恢复,备Broker会取消主备关系并注册为主Broker。
- 主Broker网络断开,备Broker检测不到主Broker的心跳超过指定时间(默认30s) ,会触发主备切换。
- 主Broker磁盘损坏或IO异常,操作系统不能重新挂载,人工确认主Broker不可恢复,可以手动触发主备切换。
- 主Broker长时间高负载或者处于不可用状态,人工确认需要切换,可以手动触发主备切换。
- 主Broker版本升级需要重启,可以先手动切换主备关系,升级主Broker,然后再切换回来,实现平滑升级。
所以主要在主Broker无法运行、网络故障和人工确认主Broker不可用等情况下会触发自动或手动主备切换,实现Broker高可用。 - RocketMQ Broker主备切换后,生产者和消费者是否需要变更?
在RocketMQ Broker主备切换后:
生产者:
生产者会收到Broker角色变更通知,自动更新发送主节点为新的主Broker。所以生产者可以透明的切换到新的主Broker,不需要人工修改配置。
消费者:
消费者需要手动更新消费主节点为新的主Broker。因为消费者消费进度信息存储在Broker,新的主Broker无法自动获取之前的消费进度。
所以消费者在Broker主备切换后,需要做以下操作: - 停止消费者,保存当前的消费进度 offsets 信息。
- 修改消费主节点配置为新的主Broker。
- 加载之前保存的 offsets 信息。
- 重启消费者,从 offsets 中断点继续消费。
因为消费者的消费进度由Broker控制和维护,所以Broker主备切换对消费者影响较大。生产者只需更新发送主节点而无需人工干预。
所以RocketMQ Broker主备切换机制保证了生产端的高可用与无感知,但消费端则需要手动操作实现平滑过渡。这也是RocketMQ高可用机制的一个小遗憾。
未来RocketMQ可考虑以下优化方案: - Broker异步复制消费进度到备Broker,主备切换时备Broker已有消费进度,消费者无需操作。
- 提供工具自动完成消费者的主节点切换、offsets迁移等工作,减少人工操作。
- 支持消费者连接多个Broker,主备切换时可以从任意可用的Broker消费,自动解决消费进度问题。
所以RocketMQ的高可用机制可以再进一步优化,最大程度减少人工干预和服务中断。这也是RocketMQ未来提高运维友好度的一个方向。 - RocketMQ Broker如何检测主备切换?
RocketMQ Broker主备切换通过以下方式检测: - Broker角色注册:Broker在NameServer注册自身角色,作为主备切换的判据依据。
- Broker心跳检测:主备Broker之间通过长连接进行心跳检测,心跳超时会触发主备切换。
- JVM停止检测:备Broker检测到主Broker的JVM停止会触发主备切换。
- 手动触发:人工确认主Broker不可用,可以通过Broker的管理命令触发主备切换。
工作机制是: - Broker启动时向NameServer注册自身角色,主Broker注册为MASTER,备Broker注册为SLAVE并指定对应主Broker。
- 主备Broker建立长连接,定期进行心跳检测。心跳间隔为3s,超过30s检测不到心跳会认为对应Broker不可用。
- 备Broker每10s检测一次主Broker的JVM进程,超过30s未恢复会触发主备切换。
- 人工确认主Broker故障或需要切换,可以通过
shutdown-broker
命令切换主备Broker角色,触发主备切换。 - Broker主备角色变更时,会通知NameServer并注册新角色,同时通知相关生产者和消费者,实现自动或手动的主备切换。
所以RocketMQ依靠Broker角色注册、心跳检测、JVM监控和手动确认等多种方式实现主备关系的维护及故障检测,触发主备切换实现高可用。 - RocketMQ的Broker切换期间,消息会丢失吗?
在RocketMQ的Broker主备切换期间,消息不会丢失,原因是: - RocketMQ采用异步刷盘方式持久化消息,消息写入页缓存后就返回,然后由后台线程异步刷盘。
- Broker也采用主备同步的方式,消息刷盘到主Broker的CommitLog后,会同步到备Broker的CommitLog。
- 所以如果主Broker在刷盘前宕机,消息会在备Broker的CommitLog中;如果主Broker刷盘后宕机,备Broker的CommitLog也会有同步过来的消息。
- Broker主备切换后,新的主Broker就可以从自己的CommitLog继续消费,不会有消息丢失。
具体工作机制是: - 生产者发送消息,主Broker返回成功后,消息被异步写入主Broker的PageCache。
- 主Broker的Flush线程定期将PageCache中消息刷盘到CommitLog。
- 刷盘成功后,主Broker会将新刷盘的CommitLog消息同步到备Broker。
- 备Broker收到主Broker同步过来的消息,写入自身的CommitLog。
- 如果主Broker在消息刷盘前宕机,消息会在备Broker的CommitLog;如果刷盘后宕机,消息也在备Broker同步过来的CommitLog。
- 新主Broker切换后直接从CommitLog读取消息,消费进度不会丢失,实现零消息丢失。
所以,通过异步刷盘、主备同步和新主Broker直接读取CommitLog消息等机制,RocketMQ实现了Broker主备切换期间的零消息丢失。这也是RocketMQ高可用设计的精髓之一。 - RocketMQ的NameServer有几台比较好?
RocketMQ的NameServer节点数目并不会直接影响RocketMQ的性能,但会影响NameServer的高可用性。
所以NameServer节点数目的选择需要权衡高可用性和运维成本: - 太少的节点(1~2个),虽然运维简单,但不利于高可用,NameServer单点故障会影响整个RocketMQ系统。
- 太多的节点(5个以上),可以实现较高的高可用性,但运维成本较大,节点越多系统越复杂。
所以建议的NameServer节点数量为: - 开发测试环境:1~2个节点。高可用性要求不高,便于调试。
- 生产环境:推荐3~4个节点。可以实现较好的高可用性覆盖,且运维成本还可控。
- 大规模生产环境:4~6个节点。系统规模较大,需要较高的高可用性支持,可以适当增加节点数。
节点数增加也需要考虑NameServer之间的负载均衡方式: - 不启用负载均衡:简单但容易压力集中,不推荐。
- DNS轮询:简单有效,需要保证每个NameServer配置相同,推荐。
- LVS或F5等硬件负载均衡:运维稍微复杂,效果好,也是推荐方案。
所以,RocketMQ NameServer节点数目的选择需要综合考虑高可用性要求和运维成本,3~6个节点配合DNS轮询或硬件负载均衡是比较典型的产品生产方案。但每个公司的具体情况也不同,需要结合自身实际情况选择最优方案。 - RocketMQ的NameServer支持主备模式吗?如何实现?
RocketMQ的NameServer支持主备部署模式,主要通过以下方式实现: - NameServer无状态,所以主备NameServer的数据可以实时同步,无需备节点等待主节点故障触发主备切换。
- NameServer启动时可以指定对应主节点,作为主节点的slave节点启动。这样主节点故障后slave节点自动变为主节点。
- NameServer之间也通过长连接进行心跳检测,心跳超时会触发主备切换。心跳时间间隔和超时时间 settings 与Broker相同。
- 人工也可以通过NameServer的管理命令行触发NameServer主备切换。
具体的工作机制是: - 启动NameServerA,在命令行指定角色为master,启动成功。
- 启动NameServerB,在命令行指定对应主节点NameServerA,以slave角色启动。
- NameServerA和NameServerB建立长连接,开始进行心跳检测。
- NameServerB定期检测NameServerA的JVM进程,确认其运行状态。
- 如果NameServerA故障,超过30s未恢复,NameServerB会取消slave角色,注册为master。
- NameServerA恢复后发现NameServerB为主节点,则注册为NameServerB的slave,恢复主备关系。
- 人工也可以通过
shutdown-namesrv
命令切换NameServer的主备角色,触发故障转移。
所以,RocketMQ的NameServer通过心跳检测、JVM监控和手动触发等方式实现了主备部署和故障转移,提高了NameServer的高可用性。
与Broker的主备机制相似,但NameServer作为注册中心,更加轻量简单。所以主备切换对生产者和消费者也无感知,实现了对整个RocketMQ系统的高可用支持。 - 如何手动触发RocketMQ的NameServer主备切换?
在RocketMQ的NameServer主备部署下,可以通过以下步骤手动触发主备切换: - 停止当前的主NameServer,执行以下命令:
bash
sh bin/mqshutdown namesrv - 当前的主NameServer停止后,备NameServer会自动取消slave角色,注册为master。
- 人工确认备NameServer已经成为主节点,可以启动之前的主NameServer。
- 之前的主NameServer启动后,会发现现有新的主NameServer,则会注册为slave从节点。
- 此时NameServer的主备关系已切换完成。
具体的流程是: - 停止NameServerA(主),NameServerB(从)仍在运行。
- NameServerB检查到NameServerA宕机,30s内未恢复,会自动变更角色为master。
- 确认NameServerB已成为主节点,启动NameServerA。
- NameServerA启动发现NameServerB为主节点,则注册为NameServerB的slave,恢复从节点角色。
- 此时,NameServer的主备关系已切换,NameServerB为主,NameServerA为从。
这种手动触发的主备切换方式,可以用于以下情况: - 主NameServer长时间高负载或故障,人工确认需要切换,提高系统可用性。
- NameServer主节点升级重启,人工先切换主备,等待升级完成后再切回,实现NameServer无感知升级。
- 测试环境验证NameServer的主备切换和恢复机制。
所以RocketMQ提供了简单手动的主备切换方式,方便运维人员根据实际情况选择主备NameServer,满足各种场景的需求 - RocketMQ NameServer进行主备切换后,生产者和消费者需要修改配置吗?
在RocketMQ的NameServer主备切换后:
生产者:
生产者注册NameServer时采用主备NameServer列表方式,主备切换后生产者会自动选择新的主NameServer,所以生产者无需修改配置。
消费者:
消费者注册NameServer也采用主备NameServer列表方式,但消费者需要手动指定消费主NameServer,所以主备切换后需要修改配置。
具体需要做如下修改: - 停止当前消费者。
- 修改消费者配置文件,将nameServerAddress指向新的主NameServer。
- 重启消费者。
- 消费者连接新的主NameServer,消费进度会自动回溯,无消息丢失。
所以生产者可以无感知的切换到新的主NameServer,但消费者需要手动修改配置并重启实现切换。原因是:
生产者:发送消息不依赖NameServer的状态,只需选择一个可用的NameServer发送即可。
消费者:消费进度需要存储在NameServer,新的主节点无法获取之前的消费进度,所以需要手动指定新的主节点。
这也是RocketMQ NameServer高可用方案的一个小遗憾,未来可以考虑以下优化: - NameServer主备之间同步消费进度信息,故障转移后新的主节点已有消费进度,消费者无感知。
- 优化消费者配置,将nameServerAddress配置为主备列表,消费者自动选择新的主节点,无需手动修改配置。
- 支持消费者连接多个NameServer,主备切换后自动从任意可用节点获取消费进度,避免手动修改配置。
所以,通过NameServer的数据同步、消费端智能重连等机制优化后,RocketMQ的NameServer高可用可以实现对全系统的无感知切换,大幅减少人工运维干预,提高系统稳定性。这也是RocketMQ未来提高运维友好性的方向之一。 - RocketMQ的Broker和NameServer who先启动 who后启动?
在RocketMQ的集群部署中,Broker和NameServer的启动顺序如下: - 先启动NameServer。因为Broker在启动时需要向NameServer注册,所以NameServer必须先启动。
- 再启动Broker。Broker启动成功后会向NameServer注册自己的角色信息,建立主备关系。
- 再启动生产者和消费者。生产者和消费者在启动时需要从NameServer获取Broker列表,所以Broker和NameServer必须先启动。
所以正确的启动顺序是:NameServer --> Broker --> 生产者/消费者
如果启动顺序错误,会导致对应的组件 startup 失败: - Broker先于NameServer启动:Broker在启动时无法找到NameServer,会一直重试直到连接NameServer成功,延长Broker的启动时间。
- 生产者/消费者先于Broker/NameServer启动:生产者和消费者在启动时获取不到Broker信息,会启动失败,需要等待Broker和NameServer启动后手动重启。
- NameServer和Broker任一方先宕机:生产者/消费者在运行时会自动感知,暂停发送或消费消息,待NameServer和Broker全部恢复后自动恢复运行。
所以正确的启动顺序对RocketMQ集群的运行至关重要。如果组件启动顺序错误,不但会影响组件的启动效率,还可能导致组件启动失败。
而NameServer或Broker的宕机,生产者和消费者可以自动感知并暂停运行, components 全部恢复后自动恢复,这体现了RocketMQ的高可用性设计。
总结来说,RocketMQ集群部署的启动顺序为:
NameServer -> Broker -> 生产者/消费者
组件的宕机会导致依赖该组件的其他组件暂停运行,待其恢复后自动恢复。这种错误容忍机制大大简化了RocketMQ的运维工作,提高了系统的稳定性。 - RocketMQ的事务消息允许跨主题吗?
RocketMQ的事务消息不支持跨主题。主要原因是: - RocketMQ的事务消息是通过本地事务消息(Prepare、Commit、Rollback 消息)在同一主题内控制最终消息状态,不涉及跨主题的协调。
- RocketMQ的消息生产和消费都是基于主题进行的,每个主题独立维护消费进度和消费者列表等信息,无法跨主题协调。
- 引入跨主题事务支持会大大增加系统的复杂性,降低性能。目前RocketMQ更关注极高性能和大规模的场景。
- 跨主题事务可以通过应用程序在业务层面实现,RocketMQ提供的本地事务支持已经足够应付大部分场景。
所以,RocketMQ的事务消息机制主要面向单主题场景,通过简单的Prepare-Commit/Rollback消息实现 Producer 与 Broker 之间的本地事务控制,无法支持跨主题的分布式事务。
如果应用需要跨主题或分布式事务,推荐在业务层面通过调用第三方的分布式事务框架(如XA)来实现,然后通过RocketMQ提供的普通消息机制来发布消息。这种应用与RocketMQ解耦的方式最大限度的发挥了RocketMQ的高性能特点,也避免了提高RocketMQ系统复杂度的弊端。
总结来说,RocketMQ的设计哲学是专注于做好消息中间件本职工作,为用户提供极高性能和高可靠的消息服务。超出消息中间件业务范围的功能,推荐应用层面通过标准协议与其他系统
这里总结一下RocketMQ事务消息相关的内容: - RocketMQ的事务消息不支持跨主题,只支持在同一主题内控制消息最终状态。
- RocketMQ的事务消息通过半消息(Prepare/Commit/Rollback)在Producer与Broker之间实现本地事务控制。
- 生产者发送Prepare消息后判定回滚,需要发送Rollback消息撤销Prepare消息。如果判定提交,需要发送Commit消息提交Prepare消息。
- Broker收到Prepare消息后,会将消息持久化并等待后续的Commit或Rollback消息。收到Commit消息后将消息标记为可消费,收到Rollback消息后将Prepare消息删除。
- 消息消费者只能消费处于可消费状态的消息,无法消费Prepare消息。
- 事务消息的消息 bodysize 最大为5M,消息索引(Keys)最大长度为128Byte,这些限制略小于普通消息。
- 事务消息的吞吐量会略低于普通消息,延迟也会略高,这个是实现本地事务带来的性能损耗。
- 生产者需要设置消息类型为Transactional消息,并实现本地事务控制逻辑。消费者消费方式与普通消息相同,无须特殊设置。
- 事务消息适用于消息发送后需要本地事务控制的场景,如本地数据操作后消息确认会或回滚等。不适合需要分布式事务支持的场景。
所以总体来说,RocketMQ的事务消息机制比较简单,主要面向单Broker/主题的本地事务场景,通过半消息的方式实现Producer与Broker的事务控制,满足大部分应用需求。尽管在性能和功能上都略逊于普通消息,但已能胜任大多数事务消息使用场景。
对于复杂的分布式事务,还是推荐应用层面采用XA事务框架,然后通过RocketMQ的普通消息机制发布消息,这种方式可以最大限度的发挥RocketMQ的性能,也避免提高RocketMQ的系统复杂度。 - RocketMQ的Broker主备部署时,如何选择主备Broker?
在RocketMQ的Broker主备部署中,主备Broker的选择需要考虑以下因素: - 机器性能:主节点负载较大,所以主节点机器性能更高更稳定的Broker更适合作为主节点。备节点可以选择稍差的机器,起到容灾备份的作用。
- 网络位置:主节点网络位置更为稳定和高速的Broker更适合作为主节点。如果网络出现问题,可以快速切换至备节点。
- 机房位置:主备节点设置在不同机房可以提高容灾能力。当机房出现断电等极端情况时,可以实现异地主备切换。
- 消息类型:主题包含重要的控制类消息,那么消息量更大、服务能力更强的Broker更适合作为主节点。
- 流量比例:某主题消息量占较大比例,其主节点应选择整体性能和流量处理能力更强的Broker。
- 时间点:Broker上线时间和版本相近的Broker更适合作为主备节点,可以避免由于版本差异带来的问题。
所以,Broker主备选择需要综合考虑机器性能、网络位置、机房位置、消息类型、流量比例和Broker版本等多方面因素。重点是要保证主节点处于最佳服务状态,提高系统可用性与稳定性。而备节点可以适当放松要求,主要服务于故障转移和容灾备份。
推荐的主备选择方式是:
主节点:性能好、网络稳定、流量大的机器,优先选择新上线的高版本Broker。
备节点:性能一般、网络较稳定的机器,可兼容主节点版本的Broker。如果有异地机房较好,可以设置异地备份。
通过综合判断各个因素,选择最优的Broker作为主节点,再选择稍差但具备容灾能力的Broker作为备节点,这种主备选择方案可以在追求高可用的同时,也兼顾到成本控制,实现最佳效益。这也是RocketMQ Broker主备部署设计的精髓所在。 - RocketMQ的Broker主备部署时,主备Broker如何实现数据同步?
在RocketMQ的Broker主备部署中,主备Broker的数据同步主要通过以下方式实现: - 异步刷盘与双写:生产者发送消息成功后,主Broker会先异步刷盘到PageCache,然后定时刷盘到CommitLog。刷盘成功后,消息会同时写到备Broker的CommitLog,实现主备数据同步。
- 消息重放:如果主Broker在消息刷盘前宕机,消息会丢失。主节点恢复后,会从备Broker的CommitLog读取丢失的消息,再重放到主节点,防止消息丢失。
- 定时同步:除消息外,消费队列、订阅信息、路由信息等元数据也需要同步。主Broker会定时读取元数据变更,同步到备Broker。
- 同步检测:主备Broker会定时检测同步延迟监控,如果同步长时间未进行或同步延迟过高,会主动触发同步操作,保证主备数据强一致。
具体工作机制是: - 消息发送成功后,主Broker异步刷盘到PageCache,返回成功。
- 后台Flush线程定时将PageCache消息刷盘到CommitLog。刷盘成功后,同步消息到备Broker的CommitLog。
- 如果主Broker在消息刷盘前宕机,会从备Broker的CommitLog读取消息,重新写入主Broker恢复数据。
- 主Broker定时读取元数据变更,同步到备Broker,保证元数据一致。
- 主备Broker定时检测同步延迟,超过阈值会触发强制全量同步,防止同步数据过于滞后。
- 人工也可以触发主备数据同步,用于特殊场景。采用rocketmq-console控制台即可触发。
所以,RocketMQ主要通过异步刷盘、双写、定时全量同步和同步检测等机制实现主备Broker的数据强一致。这种同步机制可以最大限度的降低同步开销,同时也保证主备数据实时一致,为Broker的高可用切换奠定基础。 - RocketMQ的Broker支持同城双主部署吗?如果支持,它的工作机制是什么?
RocketMQ的Broker支持同城双主部署,其主要工作机制是: - Broker在启动时可以指定部署模式为同城双主,然后各自注册到NameServer,建立主备关系。
- 同城双主情况下,生产者和消费者可以连接任意一个主节点写入和读取消息。
- 两个主节点之间通过数据同步(异步刷盘与双写)保证消息强一致。如果任一节点宕机,另一节点可直接提供服务,无需进行主备切换。
- 每个主节点独立负责消息的重发和堆积清理,各自记录消费进度和消费组信息等元数据。元数据的变化通过定时同步保证最终一致。
- 两个主节点通过长连接进行心跳检测。如果某节点30s内未恢复,则表明已彻底宕机,对方节点将注册为单主,等待宕机节点恢复重建双主关系。
- 人工也可以通过命令触发某一主节点退出同城双主,变更为单主提供服务。待两边同步数据后可再将两边设置回同城双主。
具体工作流程是: - Broker1和Broker2的部署模式配置为同城双主,建立主备关系。
- Broker1与Broker2通过异步刷盘与双写同步消息,通过定时同步保证元数据最终一致。
- Broker1或Broker2任一方宕机,对方能直接继续服务。宕机方恢复后通过同步恢复双主关系。
- 30s心跳超时判定对方彻底宕机,自身变更为单主注册到NameServer。
- 人工命令可以临时退出同城双主,服务中断期间数据同步,再恢复同城双主。
所以RocketMQ的同城双主机制通过数据同步与故障检测实现两主节点强一致与高可用,可以无感知的切换主节点,提高系统整体可用性。这种部署模式适用于对系统高可用性要求极高的场景,可以最大限度的减少单点故障对系统的影响。
但同城双主也增加了系统复杂度,且主节点之间的同步也会带来一定性能损耗,所以也需要综合权衡部署成本与实际需求,选择最佳方案。 - RocketMQ同城双主部署时,如何处理消息重发和消费进度?
在RocketMQ的同城双主部署中,消息重发和消费进度的处理方式如下:
消息重发: - 每个主节点独立负责消息重发,根据各自的发送响应时间判断消息是否超时需要重发。
- 如果消息在一个主节点超时重发,另一主节点的消息状态依然正常,则重发完成后,两个主节点的消息状态会暂时不一致。
- 两个主节点通过定时数据同步,会最终将重发消息的状态同步到对方主节点,保证消息状态最终一致。
- 消息重发时,每个主节点会各自执行,不会互相影响。所以短暂的不一致状态不会影响消费。
消费进度: - 每个主节点各自记录并管理消费组在各自上的消费进度,这两个消费进度在日常会存在一定差异。
- 消费者可以连接任一主节点读取消息,读取到的消费进度也对应比较高的那个主节点。
- 两个主节点会定时拉取对方的消费进度变更情况,调整各自的消费进度到最新的位置。但消费进度同步也有一定延迟。
- 如果消费者断连重连时连接了另一主节点,可能会出现“重复消费”或“消息跳跃”的情况,但重连后消费进度会快速同步回正常状态。
所以,在同城双主部署下,消息重发和消费进度管理比较复杂。每个主节点各自执行并独立管理,但通过定时同步保证最终数据一致。
短暂的不一致状态可能会导致“重复消费”或“消息跳跃”的情况出现,但影响范围较小,重连后会自动恢复。这也是同城双主部署相比单主部署带来的一定性能损耗的原因,需要在设计时综合考虑。
但就高可用性而言,同城双主部署的优势则十分明显,它可以最大限度的避免单点故障对消息服务的影响,是实现极致高可用的最佳手段。这也是同城双主部署即便带来一定复杂度,但仍广受欢迎的原因所在。 - RocketMQ的消息过滤策略有哪些?
RocketMQ支持多种消息过滤策略,主要包括: - SQL92语法过滤:基于SQL92语法的消息主题与标签过滤,语法如:
TopicName BETWEEN "T1" AND "T2"
AND
tags[0] IN ("TagA", "TagB")
这种过滤方式可以实现基于主题、标签及其逻辑组合的复杂过滤逻辑,是RocketMQ消息过滤的主流方式。 - 消息TAG过滤:每个消息可以设置多个TAG,消费者订阅消息时可以指定TAG进行过滤。只有TAG匹配的消息会被消费。
这种过滤方式简单高效,适用于TAG数量少、过滤逻辑简单的场景。 - 消息主题过滤:消费者可以指定主题进行过滤。只订阅指定主题的消息。
这是最简单的过滤方式,主要用于隔离不同业务的消息。 - 消息KEY过滤:消费者可以指定KEY进行过滤。只消费指定KEY的消息实例。
这种过滤方式可以实现对同一业务的消息进行细粒度过滤。 - 自定义过滤器:用户可以实现自定义过滤器,并在订阅消息时设置。RocketMQ会调用过滤器的方法对消息进行过滤。
这种过滤方式最为灵活,可以实现复杂的自定义过滤逻辑。用户只需实现RocketMQ规定的接口,并设置到订阅信息即可。
所以,RocketMQ提供了SQL语法过滤、TAG过滤、主题过滤、KEY过滤和自定义过滤器等多种方式对消息进行过滤。用户可以根据场景选择一种或多种过滤方式,也可以组合使用实现复杂的过滤逻辑。
这些灵活且功能完备的消息过滤策略,使RocketMQ可以适应各种场景的过滤需求,是其作为企业级消息中间件的重要特点之一。
尤其SQL92语法过滤,它采用标准的SQL语法,简单易学,而且可以实现复杂的逻辑过滤,是RocketMQ消息过滤的最佳选择。所以大多数场景,建议优先考虑SQL92语法进行消息过滤。 - RocketMQ的消息过滤实现原理是什么?
RocketMQ的消息过滤实现主要依赖以下几点: - 消息属性:每个消息都有主题、标签、KEY和业务字段等属性,这些属性是消息过滤的判断条件。
- 过滤模式:消费者在订阅消息时可以设置SQL语句、TAG、KEY等过滤模式来指定过滤条件。
- 过滤模式解析:RocketMQ会解析过滤模式,转换为等效的过滤逻辑判断。如SQL语句会转换为过滤表达式树等。
- 消息存储:RocketMQ的消息都是持久化存储在CommitLog和ConsumeQueue中,这使得消息过滤不依赖发送端。
- 消息扫描:消费者会定时扫描CommitLog和ConsumeQueue中的消息,对每个消息调用过滤逻辑进行判断。
- 订阅关系:消费者订阅与主题、Broker的订阅关系存储在Broker上,消息扫描时会检测消息属性与订阅关系进行过滤。
- 消息索引:ConsumeQueue采用多维索引机制,可以根据主题、标签、KEY等快速检索消息,这为高效过滤奠定基础。
具体的过滤流程是: - 消费者订阅消息时设置过滤模式,RocketMQ解析过滤模式生成过滤逻辑。
- RocketMQ存储消息到CommitLog和ConsumeQueue,并建立消费者订阅关系。
- 消费者定时扫描存储的消息,对每条消息调用过滤逻辑进行判断。
- 过滤逻辑会检测消息属性与订阅关系,判断消息是否匹配过滤条件。
- 匹配的消息会返回给消费者,不匹配的消息丢弃。
- 消费者循环扫描和判断,直到读取全部匹配消息。
所以,RocketMQ消息过滤主要依靠丰富的消息属性、灵活的过滤模式、高效的消息索引和持久化的消息存储实现。它将大部分过滤逻辑推到Broker端执行,大幅减轻生产者与消费者的负载,这种设计更加符合大规模消息场景需求。
这种基于消息属性与索引的分布式过滤机制是RocketMQ的一大创新,使其可以轻松支撑亿级消息量的过滤与精准投递,这也是其成为业界消息中间件翘楚的关键技术因素之一。
RocketMQ的主从配置与高可用,容灾相关面试题: - RocketMQ的Broker支持何种主从部署模式?
RocketMQ的Broker支持单主单从、单主多从、多主多从等部署模式。其中单主单从用于基本高可用,单主多从用于重要业务的高可用,多主多从用于核心业务的极致高可用与容灾。 - RocketMQ master-slave部署时如何选择master和slave?
Broker主从部署时,主节点选择性能好、流量大、网络稳定的Broker,从节点选择性能稍差但具备容灾能力的Broker。主要考虑机器性能、网络稳定性、流量大小等因素。
从节点可以部署在异地机房,提高容灾能力。主从版本最好相近,方便数据同步。 - RocketMQ的master-slave数据同步机制是什么?
RocketMQ主从数据同步主要通过异步刷盘和双写、定时全量同步和心跳检测实现。
消息发送成功后,先刷盘到PageCache,然后定时刷盘到CommitLog并同步到从节点CommitLog。主节点宕机可从从节点回复数据。
元数据变更通过定时全量同步到从节点。心跳检测监控同步延迟,超过阈值触发强制全量同步。 - RocketMQ的Broker支持同城双主部署吗?如果支持,它的工作机制是什么?
RocketMQ支持同城双主部署。工作机制是:
两个主节点同城部署,通过数据同步保持强一致。生产和消费可以连接任意主节点。
任一主节点宕机,另一主节点直接服务,无需主备切换。
主节点通过心跳检测彼此状态,30s心跳超时判定对方宕机,自己变为单主。
人工命令可以临时设置单主,等待数据同步后恢复同城双主。
同城双主提高系统高可用性,但也增加复杂度,影响性能。需要权衡。 - RocketMQ同城双主部署时,如何处理消息重发和消费进度?
同城双主下,每个主节点独立负责消息重发,通过定时同步消息状态保证最终一致。
每个主节点各自管理消费进度,通过定时同步进度差异。消费者连接任一主节点,会出现“重复消费”和“消息跳跃”,但重连后会恢复。
所以同城双主下,消息重发和消费进度较复杂,但通过定时同步实现最终一致,短暂不一致影响较小,重连后自动恢复。
这也是同城双主相比单主略大性能损耗的原因,在设计时需要综合考虑。但同城双主的高可用优势明显,值得在高要求场景采用。 - RocketMQ的Broker如何实现消息无损和高吞吐?
RocketMQ的Broker实现消息无损和高吞吐的主要方式是: - 消息持久化:将消息持久化存储在PageCache、CommitLog和ConsumeQueue,防止消息丢失。
- 异步刷盘:消息发送成功后,先异步刷盘到PageCache,后台定时Flush刷盘到CommitLog,提高吞吐。
- 零拷贝:消费者直接读取PageCache和ConsumeQueue中的消息,避免无谓的数据拷贝,提高吞吐。
- 批量消息:支持批量发送和批量消费消息,提高网络和磁盘IO利用率,增加吞吐。
- 预分配文件:预分配较大的CommitLog文件,写入消息时顺序填充,避免频繁文件切分导致的性能损耗。
- 零复制传输:消费者从Broker读取消息后,Broker不再维护消费进度,避免额外的ACK处理开销,提高吞吐。
- 优化磁盘IO:CommitLog采用时间顺序写入和ConsumeQueue采用LSM树结构,优化磁盘IO模式,减少随机IO。
- 页缓存池:维护一定量的页缓存,写入消息从缓存池取空页写入,避免向OS申请页带来的性能损耗。
- 过期消息清理:定期清理过期消息,释放磁盘空间和消费队列资源,以保证高可用资源供后续消息使用。
所以,RocketMQ主要通过持久化存储、异步刷盘、零拷贝、批量传输、预分配文件、零复制ACK、优化磁盘IO、页缓存池和过期消息清理等机制实现消息无损和极高吞吐。
这些技术手段的综合运用,使RocketMQ可以轻松支撑亿级别的消息吞吐与无损性,是其成为业界翘楚的技术基石。任何消息中间件,只有达到RocketMQ这种吞吐规模与消息可靠性,才具备支撑大规模业务的能力。
这也是RocketMQ被广泛应用于金融、电商、物流等领域的技术原因所在。高吞吐、高可用、高可靠是RocketMQ的三大核心价值,这也正是企业级消息中间件的正确定位。 (已编辑)
新消息
11:13
RocketMQ面试题1:
RocketMQ的Broker角色和职责是什么?
RocketMQ的Broker主要有以下角色和职责: - Broker角色:
- Master:主节点Broker,负责消息读写和服务提供。
- Slave:从节点Broker,从主节点同步数据,主节点宕机时接替服务。
- Master Slave:既是主节点又是从节点,用于同城双主部署,提高高可用性。
- Broker职责:
- 存储:Broker负责存储消息到CommitLog和ConsumeQueue。
- 接入:Broker负责接收生产者的消息发送请求和消费者的消息拉取请求。
- 路由:Broker负责根据主题路由消息到正确的Queue。
- 过滤:Broker负责根据消费者设置的过滤条件过滤消息。
- 重发:Broker负责检测消息发送超时并进行消息重发。
- 落盘:Broker定时将内存消息刷盘到磁盘,保证消息持久化。
- 发送回执:Broker负责根据消息发送结果生成回执并返回给生产者。
- 监控:Broker负责监控自己的运行状态和垃圾回收等。
- 同步:主从Broker通过同步保证主从数据强一致。
- 切换:主节点宕机后,从节点切换为主节点继续提供服务。
所以,RocketMQ的Broker主要作为消息存储、转发和计算的角色,负责存储、路由、过滤、重发、同步切换等核心职能。
它通过Master、Slave和Master Slave等角色,可以自由组合实现单主单从、单主多从、多主多从等不同的高可用部署模式。
这种高可扩展和高可靠的Broker角色设计,使RocketMQ可以支撑大规模消息场景的高吞吐和高可用需求。
Broker的这些核心职责也构成了RocketMQ高性能、高可用的技术基石,值得深入研究与学习。
RocketMQ面试题汇总