腾讯面试:大厂必问消息队列场景面试题

今天,我将那些大厂必问的消息队列的场景问题为大家整理出来,本文将跟大家一起来探讨如何回答这些问题。

为什么要使用消息队列?

保证消息有序,一个topic只能有一个partition吗?(消息顺序)

业务突然增长,导致消息消费不过来怎么办?(消息积压)

生产者收到写入成功响应后消息一定不会丢失吗?(消息丢失)

高并发场景下怎么保证消息不会重复消费?(重复消费)

如何保证消息的可靠性?

各大消息队列中间件对比及使用场景

为什么要使用消息队列?

总结一下,主要三点原因:解耦、异步、削峰。面试的时候,用自己的语言将这三点讲述出来就可以了。

  1. 解耦:比如,用户下单后,订单系统需要通知库存系统,假如库存系统无法访问,则订单减库存将失败,从而导致订单操作失败。订单系统与库存系统耦合,这个时候如果使用消息队列,可以返回给用户成功,先把消息持久化,等库存系统恢复后,就可以正常消费减去库存了。
  2. 异步:将消息写入消息队列,非必要的业务逻辑以异步的方式运行,不影响主流程业务。
  3. 削峰:消费端慢慢的按照数据库能处理的并发量,从消息队列中慢慢拉取消息。在生产中,这个短暂的高峰期积压是允许的。比如秒杀活动,一般会因为流量过大,从而导致流量暴增,应用挂掉。这个时候加上消息队列,服务器接收到用户的请求后,首先写入消息队列,如果消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。

保证消息有序,一个topic只能有一个partition吗?(消息顺序)

这个场景是针对 kafka 的,一个 Topic,一个 Partition,一个 Consumer,但是这样会导致内部单线程消费,单线程吞吐量太低,一般不会用这个。

针对保证消息有序性的问题,解决方法就是保证生产者入队的顺序是有序的,出队后的顺序消费则交给消费者去保证。

方法一:

拆分 queue,使得一个 queue 只对应一个消费者。

由于 MQ 一般都能保证内部队列是先进先出的,所以把需要保持先后顺序的一组消息使用某种算法都分配到同一个消息队列中。然后只用一个消费者单线程去消费该队列,这样就能保证消费者是按照顺序进行消费的了。

但是消费者的吞吐量会出现瓶颈。如果多个消费者同时消费一个队列,还是可能会出现顺序错乱的情况,这就相当于是多线程消费了

方法二:

对于多线程的消费同一个队列的情况,可以使用重试机制:比如有一个微博业务场景的操作,发微博、写评论、删除微博,这三个异步操作。

如果一个消费者先执行了写评论的操作,但是这时微博都还没发,写评论一定是失败的,等一段时间。等另一个消费者,先执行发微博的操作后,再执行,就可以成功。

业务突然增长,导致消息消费不过来怎么办?(消息积压)

消息堆积往往是生产者的生产速度与消费者的消费速度不匹配导致的。

有可能就是消费者消费能力弱,渐渐地消息就积压了,也有可能是因为消息消费失败反复复重试造成的,也有可能是消费端出了问题,导致不消费了或者消费极其慢。

一般这个时候,只能临时紧急扩容了,具体操作步骤和思路如下:

  1. 先修复 consumer 的问题,确保其恢复消费速度,然后将现有 consumer 都停掉;
  2. 新建一个 topic,partition 是原来的 10 倍,临时建立好原先 10 倍的 queue 数量;
  3. 然后写一个临时的分发数据的 consumer 程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的 10 倍数量的 queue;
  4. 接着临时用 10 倍的机器来部署 consumer,每一批 consumer 消费一个临时 queue 的数据。这种做法相当于是临时将 queue 资源和 consumer 资源扩大 10 倍,以正常的 10 倍速度来消费数据;
  5. 等快速消费完积压数据之后,得恢复原先部署的架构,重新用原先的 consumer 机器来消费消息。

生产者收到写入成功响应后消息一定不会丢失吗?(消息丢失)

一个消息从生产者产生,到被消费者消费,主要经过这 3 个过程:

因此如何保证 MQ 不丢失消息,可以从这三个阶段阐述:

生产者保证不丢消息,存储端不丢消息,消费者不丢消息

生产者保证不丢消息

生产端如何保证不丢消息呢?确保生产的消息能到达存储端。

如果是 RocketMQ 消息中间件,生产者要想发消息时保证消息不丢失,可以:

采用同步方式发送,send 消息方法返回成功状态,就表示消息正常到达了存储端 Broker。

如果 send 消息异常或者返回非成功状态,可以重试。

可以使用事务消息,RocketMQ 的事务消息机制就是为了保证零丢失来设计的。

存储端不丢消息

如何保证存储端的消息不丢失呢? 确保消息持久化到磁盘。大家很容易想到就是刷盘机制。

刷盘机制分同步刷盘和异步刷盘

生产者消息发过来时,只有持久化到磁盘,RocketMQ 的存储端 Broker 才返回一个成功的 ACK 响应,这就是同步刷盘。它保证消息不丢失,但是影响了性能。

异步刷盘的话,只要消息写入 PageCache 缓存,就返回一个成功的 ACK 响应。这样提高了 MQ 的性能,但是如果这时候机器断电了,就会丢失消息。

消费者不丢消息

消费者执行完业务逻辑,再反馈会 Broker 说消费成功,这样才可以保证消费阶段不丢消息。

高并发场景下怎么保证消息不会重复消费?(重复消费)

首先,对于正常业务而言消息重复是不可避免的。

正常情况下,消费者在消费消息后,会给消息队列发送一个确认,消息队列接收后就知道消息已经被成功消费了,然后就从队列中删除该消息,也就不会将该消息再发送给其他消费者了。

不同消息队列发出的确认消息形式不同,RabbitMQ 是通过发送一个 ACK 确认消息。

但是因为网络故障,消费者发出的确认并没有传到消息队列,导致消息队列不知道该消息已经被消费,然后就再次消息发送给了其他消费者,从而造成重复消费的情况。

重复消费问题的解决思路是:保证消息的唯一性,即使多次传输,也不让消息的多次消费带来影响,也就是保证消息等幂性。

具体办法:

在消息生产时,MQ 内部针对每条生产者发送的消息生成一个唯一 id,作为去重和幂等的依据(消息投递失败并重传),避免重复的消息进入队列。

在消息消费时,要求消息体中也要有一全局唯一 id 作为去重和幂等的依据,避免同一条消息被重复消费

如何保证消息的可靠性?

关于消息丢失的情况也就是这三种情况,消息到 MQ 的过程中搞丢,MQ 自己搞丢,MQ 到消费过程中搞丢。针对不同的情况,用不同的解决方法,用自己的语言叙述即可。

生产者到 RabbitMQ:事务机制和 Confirm 机制,注意:事务机制和 Confirm 机制是互斥的,两者不能共存,会导致 RabbitMQ 报错。

RabbitMQ 自身:持久化、集群、普通模式、镜像模式。

RabbitMQ 到消费者:basicAck 机制、死信队列、消息补偿机制。

各大消息队列中间件对比

单机吞吐量

比 RabbitMQ 低

2.6w/s

11.6w/s

17.3w/s

29w/s

开发语言

Java

Erlang

Java

Scala/Java

C

成熟度

成熟

成熟

开源版本不够成熟

比较成熟

只有 C、PHP 版本成熟

订阅模式

点对点(p2p)、广播(发布-订阅)

direct、topic、Headers、fanout

基于 topic/messageTag 以及按照消息类型,属性进行正则匹配的发布订阅模式

基于 topic 以及按照 topic 进行正则匹配的发布订阅模式

点对点(p2p)

持久化

支持少量堆积

支持少量堆积

支持大量堆积

支持大量堆积

不支持

顺序消息

不支持

不支持

支持

支持

不支持

性能稳定性

一般

较差

很好

集群模式

支持简单集群模式,比如‘主-备’,对高级集群模式支持不好

支持简单集群,‘复制’模式,对高级集群模式支持不好

常用多对‘Master-Slave’模式,开源版本需手动切换 Slave 变成 Master

天然的‘Leader-Slave’无状态集群,每台服务器既是 Master 也是 Slave

不支持

管理界面

一般

较好

一般

各个消息中间件对比适用场景

ActiveMQ:

  • 特点:可靠性、持久化、多种消息模式(点对点、发布-订阅、请求-回复)。
  • 适用场景:适合任务队列、工作流、异步通信、RPC、事件驱动架构等场景。

RabbitMQ:

  • 特点:易用性、灵活性、可靠性、多种消息模式(点对点、发布-订阅、请求-回复)。
  • 适用场景:适合任务队列、工作流、异步通信、RPC、事件驱动架构等场景。

RocketMQ:

  • 特点:高吞吐量、分布式、强一致性、消息顺序保证、支持消息队列和广播消息、多种消息协议(例如:HTTP、MQTT)。
  • 适用场景:适合大规模分布式系统、金融行业消息中间件、实时流处理、消息通知、事件驱动架构等场景。

Apache Kafka:

  • 特点:高吞吐量、持久化、可伸缩性、分布式、多副本复制、消息顺序保证。
  • 适用场景:适合大规模数据流处理、实时流式处理、日志收集、事件驱动架构等场景。

ZeroMQ:

  • 特点:轻量级、低延迟、高性能、无服务器架构、支持多种消息传输协议(如:发布-订阅、请求-回复、推送-拉取)。
  • 适用场景:适合高频交易、低延迟通信、大规模分布式应用、实时数据传输、微服务通信等场景。
全部评论
mark收藏
点赞 回复 分享
发布于 2025-07-10 14:31 河北

相关推荐

2025-12-27 16:21
已编辑
门头沟学院 Java
bg:中下211本科,java后端,无竞赛,无基础,大一升大二暑假开始学java。五段实习:美团-小红书-腾讯-淘天-字节。面秋招的简历只有美团、小红书、淘天。刚刚发现我的秋招蚂蚁流程挂了,这是我最后一个流程,那么我的秋招就算彻底结束了,总结一下:字节ssp+,职级2-1。美团ssp,+2打了半小时微信电话极力挽留。快手ssp,但报了字节薪资后没有争取的想法了。小红书sp,今年小红书给的很高,但比字节2-1还是差很多。虾皮应该是小sp?对虾皮一点意向都没,纯拿来集邮了。淘天ssp(暑期转正),说不要我的三方,毕业前考虑好了随时可以不签三方选择淘天。挂了的流程:京东二面挂,估计学历被卡了。懂车帝一面挂,和面试官聊不来,不认同我的方案。拼多多hr面挂,问我低于预期还来不来,当时说不考虑了,估计觉得我不忠诚。蚂蚁hr面挂,聊的还行,但估计我不会去给我挂了吧。阿里控股一面挂,没面前就知道是kpi了,因为时间可选的很多,而且都是半小时,我也拿他刷我的kpi了。上面差不多是我的情况,下面是我想说的话。我觉得我不算特别突出优秀的那类人,但我多少也算是靠前的那一批人,即使这样,秋招也不算特别顺利,也有挂了的流程,但你能说是我的问题吗,我觉得大部分情况不是的,如果真的是我的问题,我不可能本科校招拿到2-1,所以很多面试挂了,问题不出在面试者身上,很多是看运气+眼缘+和面试官合不合得来。所以我觉得,学会察言观色,了解面试官的脾性,也是面试很重要的一个点。比如面试官是喜欢听长回答,还是听短回答,他更看重哪些点,每个面试官对这些的侧重都是不一样的,所以作为面试者,要学会察言观色,通过面试官开局的一两个问题以及你回答后他的表现,就要判断出来。像我现在其实面试开局个五分钟,我就基本能判断个七七八八了,然后我后面的回答就会有所变化。这是我想说的第一个点:不要为面试结果焦虑,有时候问题不出在你身上,但你可以学一些面试技巧,尽量提高你的面试通过率,这里说的面试技巧指的不是网上那种烂大街的,一两分钟短视频说什么提高你面试通过率的,而是你要在你自己的面试过程中不断总结经验,吸取教训,旁人教你的终究是有限的。另外想说下选offer的事,上面其实可以看出来,我秋招最后是选了字节的,还没签三方我就来提前实习感受业务了,当我签完三方又过了一个多月,我这些天又在想这个问题,字节真的是我想要的吗,我现在总结了一下字节的好坏,发现当时可能被字节的高薪资影响判断了,如果现在再选一次的话,我应该会选杭州的小红书,会生活的更舒服点。具体种种就不展开说了。然后虽然我现在也可以说去把小红书舔回来,去毁字节,但我觉得没必要这么做,我可以采用其他的措施去不就,比如规划好两年内就跳槽,跳到杭州,跳到更舒适的城市。我觉得大家选offer的时候,真的可以冷静下来多方面考虑,薪资、城市、组内氛围、业务、老板是否看重、组内情况、未来升职机会等等都是可以考虑的因素,虽然有的时候不管选哪个,都不会坏,但最好也别让自己后悔吧,即使真后悔了,我觉得也没必要过度美化没走过的路,想好补救措施即可。这是我想说的第二个点:冷静好好做选择,不管是offer还是其他。但人生容错率很大,即使选错了,也一定有补救措施。最后还想说一些成长上的东西,尤其是现在AI火热的时代。我觉得大家如果想提高自己,或者说在未来社招跳槽有竞争力,肯定是要学AI相关的东西的,不说要会多懂AI,至少也要了解基本概念,而且一定要学会用AI提效。我现在字节的mt和我说,他现在80%代码都是AI写的。而我最近也开始尝试用AI工具,感觉现在AI真的进步很多,挺聪明的了,我现在写需求基本都是先让AI写,我再人工review小改动一下就差不多了。我觉得「AI取代程序员」是个很远的话题,但是「AI取代不会用AI的程序员」,可能真的就是近两年的事了。而怎么去学习这块的内容,其实我也正在探索,我也是刚学AI的起步阶段,我觉得大家也要有自己的信息检索能力,而不是别人喂你什么,你才学什么,自己一个人就不会学了。这是我想说的第三个点:趁年轻,多学习提升自己,拥抱AI,不要原地踏步,原地踏步的程序员最容易被淘汰。大概就是这样吧,今天看蚂蚁流程发现挂了,前几天腾讯约面我也拒了,就想到自己的秋招/校招算彻底结束了,有感而发,随便聊了下。牛客以后应该不会更新,大家不用关注,熟悉我的朋友应该知道我在其他平台有号。我更喜欢以长视频的形式去做分享,感觉会更有体系,而不是网上那种一两分钟的零碎短视频的那种营销号去起号,我也推荐大家多去看高质量的长文章、长视频,我觉得收获的能更多。希望大家能收获满意的offer与未来。
CEXBB:刷到最后才发现原来是优雅✌🏻,我的Java引路人
2025年终总结
点赞 评论 收藏
分享
评论
5
32
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务