高频
1.消息不丢失机制
-
核心要点:需要从Producer、Broker、Consumer三个层面展开
- Producer端:同步发送+重试机制(send(msg,timeout)、事务消息保证最终一致性)
- 提供同步发送消息方式,等待broker处理结果(同步发送,阻塞线程等broker响应、异步发送,等执行完任务后,在回调执行处理结果、OneWay发送:只负责发送请求,不等待应答。)
- 发送消息如果失败或超时,则重新发送。
- broker提供多master模式,即使某台broker宕机了,保证消息可以投递到另外一台正常的broker上。(ms
- Broker端:同步刷盘(flushDiskType=SYNC_FLUSH)+ 主从同步(brokerRole=SYNC_MASTER)
- 提供同步刷盘策略(消息到broker后,先存到pageCache,根据broker设置的刷盘策略是否立即刷盘; 如果为异步,borker不会等待消息落盘就返回producer成功,若broker突然宕机,则会丢失部分页的消息)
- 提供主从模式,同时主从支持同步双写(若borker只设置了同步刷盘,如主broker磁盘损坏,消息也会丢失;所以设置一个salve来同步master的消息,当master和salve的消息都落盘成功之后,broker才会当消息投递成功,保证消息不丢失)
- Consumer端: 手动ACK(ConsumerConcurrentlyStatus.RECONSUME_LATER) + 消息幂等性设计(如数据库唯一键、Redis去重) *
- Producer端:同步发送+重试机制(send(msg,timeout)、事务消息保证最终一致性)
-
面试追问:若主节点宕机且异步复制未完成,如何避免消息丢失?
- 需配置同步复制(SYNC_MASTER),牺牲部分性能换取数据强一致。
2.事务消息实现原理
- 半消息机制:消息先存为"预备状态"(对Consumer不可见),本地事务执行后发送Commit/Rollback
- 事务回查:Broker定时会查Producer确认事务状态,默认重试15次,间隔逐步增加
- 典型场景:订单支付超时回滚、库存扣减与消息发送原子性
3.顺序消息保证
- 实现方式: 通过MessageQueue选择算法(如Hash取模)确保同一业务ID消息发送到同一队列
- 消费端限制:需使用 MessagelistenerOrderly 监听器,且单线程消费队列
- 常见误区:全局顺序 vs 分区顺序(实际99%场景用分区顺序,性能更高)
中频
延迟队列的实现
- 底层机制:基于定时消息(18个固定延迟级别,如1s/5s/10s,不支持自定义时间)
- 替代方案:若需精确时间,可通过外部存储(如Redis)+ 定时任务补偿实现
- 应用场景: 订单超时关闭、优惠券到期提醒
死信队列(DLQ)处理
- 触发条件:消息重试16次后仍失败自动进入死信队列
- 处理策略:独立消费者订阅DLQ进行人工干预/日志分析
- 监控要点:私信队列堆积告警配置(通过RocketMQ控制台或Prometheus)
消息堆积处理方案
- 临时扩容:增加Consumer实例数(需保证队列数>=消费者数)
- 批量消费:调整 consumeMessageBatchMaxSize 参数提升吞吐
- 降级策略:跳过非核心消息或仅消费最新消息(CONSUME_FROM_LAST_OFFSET)
低频但重要考点(30%概率,技术深度考察)
Broker高可用设计
- 多副本同步:同步复制(SYNC_MASTER) vs 异步复制(ASYNC_MASTER)
- 故障转移:主节点宕机后,消费者自动切换到从节点消费(需配置SlaveReadEnable=true)
零拷贝与高性能原理
- CommitLog顺序写:所有消息追加写入单一文件,减少磁盘寻址
- 内存映射(mmap):通过MappedByteBuffer实现文件内存映射,减少数据拷贝
NameServer无状态设计
- 对比Zookeeper:无强一致性要求,通过心跳维护Broker列表,降低复杂度
- 路由发现:客户端定时拉取路由信息(默认30秒),非实时推送
消息队列的作用:
异步 解耦 削峰
RecoketMQ
- 发布者Publisher: 消息的生产者
- 订阅者Subscriber: 消费者
- 主题Topic:存放消息的容器
为什么一个主题中要维护多个队列?为了提高并发能力。
RocketMQ 通过使用在一个Topic中配置多个队列并且每个队列维护每个消费者组的消费位置,实现了主题模式/发布订阅模式。
RocketMQ的架构
- NameServer: 注册中心,提供两个功能:Broker管理和路由信息管理。 Broker会将自己的信息注册到NamerServer中,此时NameServer中存放了了Broker的路由信息表, 消费者和生产者就从NamServer中获取路由表按照路由表的信息对应的Broker进行通信(并且生产者和消费者会定期查询)
- Broker: 负责消息的存储、投递和查询以及服务高可用保证。 消息队列服务器,生产者到broker, 消费者从broker拉取消息并消费。 一个Topic分布在多个Broker中, 一个Broker可以配置多个Topic,多对多的关系。
- Producer: 消息发布的角色,支持分布式集群方式部署,生产者。
- Consumer: 消费消息的角色,以push推,pull拉两种模式对消息进行消费。同时也支持集群方式和广播方式的消费,提供实时消费订阅机制。 消费者。
如何保证顺序消费
- RocketMQ在主题上是无序的,只有在队列层面才是有序的。
- 普通顺序:消费者通过同一个消费队列收到的消息是有顺序的,不同消息队列的消息可能是无顺序的。 在Broker重启的情况下不会保证消息顺序性(短暂时间)
- 严格顺序:消费者收到的所有消息军师有序的。即使在异常情况下也会保证消息的顺序性。
1. RocketMQ Producer消息发送流程详解
-
初始化-> 构建-> 发送-> 容错-> 扩展、
-
初始化与配置
- Producer启动时,通过配置的NameServer地址(集群)获取Broker路由信息; 定期从NameServer拉去Topic队列分布(Broker+Queue), 并本地缓存。
-
消息构建
- 创建Message对象,指定字段:
- topic:消息分类主题
- Tags: 二级过滤标签
- Keys: 业务唯一标识
- Body: 消息内容
- 创建Message对象,指定字段:
-
队列选择和负载均衡:
- 根据MessageQueueSelector策略选择目标队列,默认策略:
- 轮询(Round Robin):均匀分布消息到不同队列
- 自定义策略: 例如按照业务ID哈希选择队列(用于顺序消息)
- 根据MessageQueueSelector策略选择目标队列,默认策略:
-
消息发送模式:
- 同步发送:等待Broker返回ACK,确保消息可靠(牺牲吞吐,强一致性场景)
- 异步发送:通过回调函数处理结果,提高吞吐(需处理网络异常)
- 单项发送:只管发送,不关心结果(日志等可容忍丢失场景)
-
Broker处理与高可用
- 主从架构:优先发送到Master节点,失败时切到Slave(需要配置Broker的
SYNC_MASTER模式) - 重试机制:自动重试(默认2次)或手动重试(如Broker不可用)
- 主从架构:优先发送到Master节点,失败时切到Slave(需要配置Broker的
-
事务消息(可选)
- 半消息(Half Message):先发送到Broker,但对消费者不可见
- 本地事务执行:执行本地业务逻辑,返回Commit/Rollback状态
- 二次提交:Broker根据事务结果提交或丢失消息。
-
高级特性支持:
- 顺序消息:相同Sharding Key(如订单ID)的消息发送到同一队列
- 延迟消息:通过预设延迟级别(如何message.setDelayTimeLevel(3))
- 批量发送:合并多条消息减少网络开销
RocketMQ Producer发送消息的流程分为四个阶段:首先,启动时连接NameServer获取Broker路由;其次,构建消息并基于负载均衡策略(如轮询)选择目标队列;然后通过同步、异步或单向模式发送到Broker,失败时自动重试或切换主从节点;最后,支持事务消息通过半消息+本地事务确保最终一致性。此外,顺序消息需指定Sharding Key保证同队列处理。”
2. RocketMQ消费消息是推模式还是拉模式
实现均基于拉去机制 首先,推模式(DefaultMQPushConsumer)通过
长轮询模拟推送效果,消费者客户端持续拉取消息并触发回调,实现高实时性,但需承担长连接资源开销。Broker主导,消费者被动接收。 其次,拉模式(LitePullConsumer)由消费者主动控制拉去节奏,适合精准调控或批量处理场景,但需自行管理偏移量与负载均衡。支持动态队列分配、消息过滤、适配复杂消费逻辑。
3. RocketMQ消息是如何存储的?
RocketMQ的消息存储是围绕高性能与可靠性展开,分为三层: 首先:所有消息顺序写入CommitLog文件,利用磁盘顺序写特性最大化吞吐; 其次,基于commitLog异步构建ConsumeQueue,为每个Topic队列维护轻量索引,实现消费位点快速跳转 同时,通过IndexFile提供消息Key的哈希索引,支持灵活查询 在高可用方面,通过同步/异步刷盘平衡性能与数据安全,结合主从复制(同步/异步)防止节点故障 最后,文件按时间(默认72小时)或磁盘水位(默认75%)清理,避免存储无限膨胀。这一设计在保证高吞吐的同时,通过分层索引与异步机制降低了读写冲突
- 同步刷盘:消息写入CommitLog后强制刷盘,保证不丢失,性能低
- 异步刷盘:依赖OS页缓存批量刷盘,高性能,宕机可能丢失未刷盘数据
- 主从复制:
- 同步复制:Master将消息复制到Slave后返回ACK,高可靠
- 异步复制:Master写入后立即返回ACK,异步复制到Slave,高性能。
4. RocketMQ消息积压问题如何解决
先定位根因,区分是生产突增、消费能力不足还是队列分配不均 紧急扩容消费者实例或队列数,调整消费并行度,推模式,增大consumeThreadMin和consumeThreadMax(消费者线程池);拉模式,提升拉去批次大小(pullBatchSize)或并发拉去线程数。 若积压严重,可创建临时消费者组跳过历史数据,或转储消息分批次重放。 最后通过限流、监控、私信队列等机制防止再次积压
- 限流降级:生产端限流(如令牌桶)、消费端熔断异常队列
- 监控告警:实时监控Cosumer Lag, 设置堆积阈值值告警
- 死信队列:将多次重试失败的消息转入死信队列,避免阻塞正常消费。
消息积压通常因生产快于消费、消费逻辑慢或资源瓶颈导致。处理步骤包括:
- 诊断:通过控制台或
mqadmin检查积压量和消费进度,定位瓶颈(如数据库慢)。 - 提升消费能力:增加消费者实例、优化线程数、批量消费或异步化逻辑。
- 调整配置:增加 Topic 队列数,优化 Broker 参数如异步刷盘。
- 处理重试:修复失败逻辑,清理死信队列。
- 临时措施:扩容资源、限流生产者或分流消息。
- 长期看,需做好容量规划、监控告警和幂等设计。例如,促销场景下可提前扩容消费者并优化数据库为批量操作。
RocketMQ 的队列模型和延迟消息功能也能有效支持积压处理。
5. RocketMQ如何保证消息不丢失
生产者使用
同步发送+重试机制确保消息到达Broker,事务消息通过半消息+状态回查解决分布式一致性问题 Broker端依赖同步刷盘保证消息持久化,结合主从同步复制防止节点故障 消费者手动提交Offset,避免自动化提交导致消息丢失,并通过重试队列和私信队列处理异常场景。 Broker的多副本机制和故障转移进一步保障高可用
- 同步刷盘:FlushDiskType.SYNC_FLUSH, 消息写入物理磁盘后返回ACK,通过MappedFileQueue.commit提交
- 异步刷盘:依赖OS页缓存批量刷盘,高性能,但宕机可能丢失数据
- 同步复制,BrokerRole.SYNC_MASTER:Master等待Slave写入成功后才返回ACK
- 手动ACK: 消费者处理完成后手动提交消费进度ConsumeConcurrentlyStatus.CONSUME_SUCCESS
- 重试队列与死信队列: 消费失败的消息进入重试队列,最多重试16次后,转入死信队列。
6. RocketMQ延迟消息是如何实现的
通过预定义级别+内部Topic路由+定时投递实现 首先,生产者设置消息的delayTimeLevel,Broker将其路由到内部Topic, SCHEDULE_TOPIC_XXX的对应对立 其次,ScheduleMessageService为每个级别启动定时器,到期后扫描队列,将消息恢复原始Topic/Queue重试投递。
-
延迟级别预定义:RocketMQ提供18个固定级别(默认1s,5s,10s,30,1m,...2h),通过配置delayLevel定义时间,不可自定义任意时长。
-
内部Topic路由:延迟消息被存储到内部 SCHEDULE_TOPIC_XXX, 每个延迟级别对应一个队列
-
定时任务调度:Broker启动ScheduleMessageService为每个延迟级别创建定时器(Timer),按延迟时间周期性扫描队列。到期消息恢复原始Topic/Queue,重新写入CommitLog, 变为可消费状态。
-
性能优化:定时任务使用TImer而非频繁轮询,减少CPU开销。 延迟消息存储复用CommitLog,避免额外存储成本。
7. RocketMQ 如何保证消息顺序
通过生产端队列选择+Broker顺序存储+消费端顺序处理 首先,生产者使用 MessageQueueSelector, 将同一Sharding Key的消息发送到同一个队列 其次, Broker的ConsumeQueue按顺序存储索引,确保队列内消息物理有序 最后,消费者通过 MessageListenerOrderly 监听器,以担心成处理队列消息,结合Broker端队列锁繁殖鬓消费。 注意,分区顺序消息的吞吐量取决于队列数量,需合理设计Sharding key避免热点
- 故障场景下的顺序保障:
- 消费失败重试:顺序消息消费失败时,默认重试次数为Interger.Max_VALUE,避免跳过消息导致乱序。
- Offset提交机制:严格按顺序提高Offset,确保消费进度与处理顺序一致。
8. RocketMQ 提供了那些消息过滤机制
rocketMQ提供两种消息过滤机制 第一层, Tag过滤通过精准匹配消息标签,利用CosumeQueue中Tag哈希快速筛选,适合分类场景,如区分订单装填 第二层,SQL过滤基于消息自定义属性,支持复杂表达式(如region='CN' AND price>100),通过Broker解析SQL语法树实现灵活筛选,但需权衡性能; 高频场景用Tag,复杂逻辑用SQL,且需Broker启用enablePropertyFilter.
9. RocketMQ 生产环境如何优化
系统层:调用JVM堆内存与GC策略,提高OS文件句柄和tCP链接性能 Broker层: 异步刷盘+PageCache提升写入吞吐,同步复制保障数据可靠,按磁盘水位清理文件 生产端:异步/批量发送减少网络开销,合理设置队列避免倾斜 消费端:增大消费线程并发,手动提交Offset防重复 高可用:Dledger多副本自动容灾,跨机房部署防单点故障
10. RocketMQ事务消息是如何实现的
通过两阶段提交+事务回查 第一阶段:生产者发送半消息到Broker的特殊Topic, RMQ_SYS_TRANS_HALF_TOPIC, 此时消息对消费者不可见 第二阶段:执行本地事务(如更新数据库),并返回COMMIT/ROLLBACK状态; 第三阶段:Broker根据状态提交(转存到业务Topic)或回滚(删除)消息; 若状态未确认(如生产者宕机),Broker 通过TransactionalMessageCheckService定时回查,调用checkLocalTransaction() 确认最终状态。
- 幂等性:生产者需保证本地事务与消息发送的幂等性(如唯一业务ID+去重表)