消息队列常见面试题目

一,为什么选择RocketMq

特性RabbitMQActiveMQRocketMQKafka
协议支持AMQP、STOMP、MQTT、HTTPAMQP、STOMP、OpenWire、MQTT自定义协议(Remoting)自定义协议(基于 TCP)
消息模型队列(点对点)、发布/订阅(通过 Exchange 绑定)队列(点对点)、发布/订阅(Topic)队列(点对点)、发布/订阅(Topic)发布/订阅(Topic + Partition)
吞吐量中等(万级 QPS)低(万级以下)高(十万级 QPS)极高(百万级 QPS)
延迟低(微秒级)中等(毫秒级)低(毫秒级)较高(毫秒级,依赖批量消费)
消息持久化支持(内存、磁盘)支持(KahaDB、JDBC)支持(CommitLog 磁盘持久化)支持(磁盘持久化,默认 7 天)
事务支持支持(轻量级事务,性能较低)支持(XA 分布式事务)支持(分布式事务消息)支持(0.11+ 版本提供事务)
消息顺序性单队列有序单队列有序单队列严格有序(分区内有序)单分区有序(全局无序)
消息确认机制ACK(自动/手动)ACK(自动/手动)ACK(同步/异步)Offset 提交(自动/手动)
集群模式主从模式(镜像队列)或 Federation 跨集群同步主从模式(共享存储)或 Network of Brokers主从模式(多副本同步) + NameServer 路由分区多副本(Leader-Follower)+ ZooKeeper 协调
扩展性中等(依赖集群配置)低(集群性能受限)高(水平扩展 Topic 分区)极高(分区可动态扩展)
社区生态活跃(Erlang 社区主导)活跃度下降(Apache 项目)活跃(阿里开源,Apache 顶级项目)极活跃(LinkedIn 开源,Apache 顶级项目)
典型应用场景企业级消息中间件、实时通信、任务分发传统企业应用(JMS 规范)、小型系统电商交易、金融支付(高可靠、顺序消息)日志收集、流处理、大数据管道
优势灵活的路由规则、多协议支持支持 JMS 规范、轻量级部署高吞吐、低延迟、强顺序性超高吞吐、持久化能力强、生态完善
劣势集群扩展复杂、吞吐量一般性能低、社区维护不足配置复杂、生态相对较小延迟较高、运维复杂
备注适合复杂路由场景(如死信队列、优先级队列)ActiveMQ Artemis 是新一代版本(性能提升)支持消息轨迹、延迟消息、事务消息与 Flink、Spark 等流处理框架深度集成 

为什么选择rocketmq作为讲解的呢,因为有高吞吐,可以应对大部分应对电商秒杀、支付订单等高并发场景。跨服务的最终一致性(如订单与库存)。Java生态友好,文档丰富,运维成本低。

二,他有什么优缺点

优点

1, ​​高吞吐与低延迟​​,单机支持 ​​10万级 TPS​​ 的吞吐量,适用于电商、金融等高并发场景。
2. ​​高可用性与可靠性​​,基于 ​​主从架构(Master-Slave)​​ 和 ​​多副本同步机制​​,支持自动故障切换(
3,​​事务消息支持​​,提供​​完整的事务消息机制​​(两阶段提交),确保本地事务与消息发送的原子性。
4,源码是java的,可以进行二次开发。
5,消息堆积量比较大,不会因为消息堆积量过大导致服务失效。

缺点

1,客户端支持语言不多。

2,JMS接口没实现。

3,监控工具有限,需要第三方工具。

4,兼容性一般。

三,消息队列的模型?

队列模型

一个生产者可以向某个队列发送消息,一个队列可以存多个生产者消息,一个队列有多个消费者消费。

发布/订阅模型

发布/订阅模型​​则采用主题(Topic)作为消息的中介,生产者向主题发布消息,多个消费者通过订阅主题来接收消息副本。此模式支持​​消息广播​​,例如新闻推送场景中,一条新闻会被所有订阅用户接收。

四,RocketMq的架构

RocketMq使用的模型是发布/订阅模型,他的架构如下:

1. Message(消息)​​


​​定义​​:消息是 RocketMQ 中最基本的数据单元,包含业务数据(消息体)和元数据(如 Topic、Tag、Key 等属性)。
​​作用​​:生产者将业务数据封装为消息发送到 Broker,消费者从 Broker 拉取消息进行消费。
​​关键属性​​:
​​Topic​​:消息所属的主题,用于分类和路由。
​​Tag​​:消息的二级标签,用于细粒度过滤(如区分订单的创建、支付等操作)。
​​Key​​:消息的唯一标识(用户自定义),通常用于查询或去重。

​​2. Topic(主题)​​


​​定义​​:Topic 是消息的逻辑分类,生产者发送消息到指定 Topic,消费者订阅 Topic 以接收消息。
​​作用​​:实现 ​​发布/订阅模型​​ 的基础,支持消息的广播或负载均衡消费。
​​特点​​:
​​消息隔离​​:不同 Topic 的消息相互独立(如 订单Topic 和 库存Topic)。
​​多消费者模式​​:一个 Topic 可被多个 Consumer Group 订阅,每个 Group 独立消费全量消息。
​​分区机制​​:Topic 可划分为多个队列(MessageQueue),提升并发处理能力。
​​

3. Tag(标签)​​


​​定义​​:Tag 是 Topic 下的二级分类,用于对同一 Topic 中的消息进行更细粒度的过滤。
​​作用​​:消费者可以基于 Tag 选择性消费消息,避免全量接收 Topic 数据。
​​使用场景​​:
订单 Topic 中,通过 Tag 区分 创建订单、支付订单、取消订单 等操作。
日志 Topic 中,通过 Tag 区分 INFO、ERROR、DEBUG 等级别。
​​语法​​:消息发送时指定 Tag,消费者订阅时通过 TagA || TagB 格式过滤(支持 SQL92 表达式)。

​​4. Group(组)​​

RocketMQ 中有两种 Group 类型:生产者组​​ 和 消费者组​​。

​​(1) Producer Group​​
​​一组生产相同 Topic 消息的生产者集合。

​​(2) Consumer Group​​
一组消费相同 Topic 消息的消费者集合。
​​


​​消费模式​​:


​​集群模式​​:每条消息仅被 Group 内的一个消费者消费(默认)。
​​广播模式​​:每条消息被 Group 内的所有消费者消费。
 

五,如何保证消息不丢失呢?

生产:

在生产阶段,主要通过请求确认机制,来保证消息的可靠传递。

同步发送 + 重试机制:
使用 send() 同步发送消息,并捕获发送结果(SendResult)。若发送失败,开启重试机制(默认重试 2 次)。同步发送的时候,要注意处理响应结果和异常。如果返回响应 OK,表示消息成功发送到了 Broker,如果响应失败,或者发生其它异常,都应该重试。

存储:

Broker 收到消息后,若未持久化就宕机,导致消息丢失。

1、消息只要持久化到 CommitLog(日志文件)中,即使 Broker 宕机,未消费的消息也能重新恢复再消费。
2、Broker 的刷盘机制:同步刷盘和异步刷盘,不管哪种刷盘都可以保证消息一定存储在 pagecache 中(内存中),但是同步刷盘更可靠,它是 Producer 发送消息后等数据持久化到磁盘之后再返回响应给 Producer。

同步刷盘概念:当数据写入内存后,​​必须等待数据成功写入磁盘​​,才会返回成功响应。

异步刷盘概念:当数据写入内存后,​​立即返回成功响应​​,磁盘写入操作由后台线程异步完成。

如图:

消费:

等业务代码完成之后,再发送消费确认,因为偏移量没有确认的话,你再去拉取,还是那个消息。

六,如何保证消息的顺序执行?

顺序消息主要分成两种:

全局顺序消息(严格顺序)

所有消息按照严格先后顺序被生产和消费(性能较低)
实现方式:所有消息发送到同一个队列(MessageQueue)
适用场景:金融交易、库存扣减等强一致性场景


分区顺序消息(局部顺序)

同一业务ID的消息保证顺序,不同业务间无需顺序
实现方式:相同业务ID的消息发送到同一队列
适用场景:订单状态流转、物流状态更新等场景

局部顺序具体执行:
Producer端保证顺序

使用MessageQueueSelector接口自定义路由逻辑,根据业务ID(如订单ID)哈希到固定队列。

SendResult sendResult = producer.send(msg, 
    (mqs, msg, arg) -> {
        int index = arg.hashCode() % mqs.size();
        return mqs.get(index);
    }, 
    "业务ID");

Broker端存储顺序

每个队列在Broker中对应一个物理文件,消息严格按接收顺序追加到文件末尾(CommitLog顺序写)

Consumer端顺序消费

每个队列在同一时刻只能被一个消费者线程处理,消费者使用MessageListenerOrderly监听器

七,延时消息说一下,优缺点是?

概念:

        延迟消息是消息队列(如 RocketMQ)提供的一种特殊消息类型,允许消息在发送后延迟一段时间(如 30 分钟)再被消费者消费。其核心目的是将定时任务逻辑从业务代码中剥离,由消息队列系统自动触发延迟投递,简化开发流程。

其实本质上:消息队列的“定时器”功能,替代传统方案(如数据库轮询、线程睡眠 Thread.sleep 等)

不支持任意级别,支持18个指定级别

延迟级别12345...18
时间1s5s10s30s1m...2h

机制:

存储:延迟消息存入特殊 Topic(SCHEDULE_TOPIC_XXX),每个延迟级别对应一个队列。
定时扫描:Broker 启动后台线程,按延迟级别轮询队列,到期后将消息转移到目标 Topic 供消费。
投递精度:因依赖轮询机制,可能存在微小误差(通常毫秒级)。

实例代码
Message msg = new Message("OrderTopic", "订单超时关闭".getBytes());
// 设置延迟级别为 4(对应 30 秒)
msg.setDelayTimeLevel(4);
producer.send(msg);
优点:


解耦业务与定时逻辑
延时消息将业务逻辑与定时任务解耦,无需业务层自行实现定时调度(如数据库轮询或线程休眠),简化代码复杂度。

高可靠性
RocketMQ 的延时消息和普通消息一样,支持持久化存储、重试机制和事务特性,保证消息不丢失。

预定义延迟级别
RocketMQ 提供 18 个固定的延迟级别,覆盖常见业务场景,开箱即用。

可扩展性
虽然不支持任意时间精度,但可通过修改 Broker 配置自定义延迟级别(如增加 15m、30m 等),满足多数需求。

缺点:


延迟时间不灵活
不支持精确到秒级的任意时间延迟(如 7 秒或 3 天),需通过业务层绕道实现(

潜在消息堆积
延时消息存储在特定 Topic(SCHEDULE_TOPIC_XXX),若大量使用且延迟时间较长,可能占用存储资源,影响 Broker 性能。

投递时间误差
延时消息的投递依赖 Broker 定时扫描,可能存在微小延迟(通常毫秒级),对超敏感场景需谨慎。

八,消息挤压问题

消息积压通常由 生产者速率过快 或 消费者处理能力不足 引起。

解决方法:

消费者扩容:如果当前 Topic 的 Message Queue 的数量大于消费者数量,就可以对消费者进行扩容,增加消费者,来提高消费能力,尽快把积压的消息消费玩。添加消费者同时,也要添加队列。

降级处理:跳过非关键消息,或仅处理最新数据(如设置消息TTL)

批量消费:启用批量消费模式,减少网络和事务开销。

修改持久化操作:将同步操作(如写数据库)改为异步(如写入内存队列,由其他线程处理)。

提升消费速度:优化消费者代码(如减少DB操作)/

消息转储:将积压消息转移到其他存储(如HDFS),后续离线处理。

九,死信队列?

死信队列是 RocketMQ 中用于存储无法被正常消费的消息的专用队列。当消息经过多次重试仍无法被消费者成功处理时,RocketMQ 会自动将这些消息转移到死信队列中,避免因单条消息的失败阻塞整个消费流程。

触发条件:

消息在消费者端重试次数达到阈值(默认重试 16 次,超过后进入死信队列)。

消息因业务逻辑问题(如数据格式错误)被消费者主动标记为失败。

设置最大重试次数:
// 消费者设置最大重试次数(默认16)
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("group");
consumer.setMaxReconsumeTimes(10); // 修改为最多重试10次

这个是官方文档的图片:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值