首页
题库
公司真题
专项练习
面试题库
在线编程
面试
面试经验
AI 模拟面试
简历
求职
学习
基础学习课
实战项目课
求职辅导课
专栏&文章
竞赛
我要招人
发布职位
发布职位、邀约牛人
更多企业解决方案
AI面试、笔试、校招、雇品
HR免费试用AI面试
最新面试提效必备
登录
/
注册
龚拓新
蚂蚁集团_研发工程师
发布于上海
关注
已关注
取消关注
@程序员大彬:
消息队列高频面试题(2022最新整理)
为什么要使用消息队列? 总结一下,主要三点原因:解耦、异步、削峰。 1、解耦。比如,用户下单后,订单系统需要通知库存系统,假如库存系统无法访问,则订单减库存将失败,从而导致订单操作失败。订单系统与库存系统耦合,这个时候如果使用消息队列,可以返回给用户成功,先把消息持久化,等库存系统恢复后,就可以正常消费减去库存了。 2、异步。将消息写入消息队列,非必要的业务逻辑以异步的方式运行,不影响主流程业务。 3、削峰。消费端慢慢的按照数据库能处理的并发量,从消息队列中慢慢拉取消息。在生产中,这个短暂的高峰期积压是允许的。比如秒杀活动,一般会因为流量过大,从而导致流量暴增,应用挂掉。这个时候加上消息队列,服务器接收到用户的请求后,首先写入消息队列,如果消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。 使用了消息队列会有什么缺点 系统可用性降低。引入消息队列之后,如果消息队列挂了,可能会影响到业务系统的可用性。 系统复杂性增加。加入了消息队列,要多考虑很多方面的问题,比如:一致性问题、如何保证消息不被重复消费、如何保证消息可靠性传输等。 常见的消息队列对比 对比方向 概要 吞吐量 万级的 ActiveMQ 和 RabbitMQ 的吞吐量(ActiveMQ 的性能最差)要比 十万级甚至是百万级的 RocketMQ 和 Kafka 低一个数量级。 可用性 都可以实现高可用。ActiveMQ 和 RabbitMQ 都是基于主从架构实现高可用性。RocketMQ 基于分布式架构。 kafka 也是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用 时效性 RabbitMQ 基于 erlang 开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。其他三个都是 ms 级。 功能支持 除了 Kafka,其他三个功能都较为完备。 Kafka 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用,是事实上的标准 消息丢失 ActiveMQ 和 RabbitMQ 丢失的可能性非常低, RocketMQ 和 Kafka 理论上不会丢失。 总结: ActiveMQ 的社区算是比较成熟,但是较目前来说,ActiveMQ 的性能比较差,而且版本迭代很慢,不推荐使用。 RabbitMQ 在吞吐量方面虽然稍逊于 Kafka 和 RocketMQ ,但是由于它基于 erlang 开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。但是也因为 RabbitMQ 基于 erlang 开发,所以国内很少有公司有实力做 erlang 源码级别的研究和定制。如果业务场景对并发量要求不是太高(十万级、百万级),那这四种消息队列中,RabbitMQ 一定是你的首选。如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。 RocketMQ 阿里出品,Java 系开源项目,源代码我们可以直接阅读,然后可以定制自己公司的 MQ,并且 RocketMQ 有阿里巴巴的实际业务场景的实战考验。RocketMQ 社区活跃度相对较为一般,不过也还可以,文档相对来说简单一些,然后接口这块不是按照标准 JMS 规范走的有些系统要迁移需要修改大量代码。还有就是阿里出台的技术,你得做好这个技术万一被抛弃,社区黄掉的风险,那如果你们公司有技术实力我觉得用 RocketMQ 挺好的 Kafka 的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms 级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。同时 kafka 最好是支撑较少的 topic 数量即可,保证其超高吞吐量。kafka 唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略这个特性天然适合大数据实时计算以及日志收集。 如何保证消息队列的高可用? RabbitMQ:镜像集群模式 RabbitMQ 是基于主从做高可用性的,Rabbitmq有三种模式:单机模式、普通集群模式、镜像集群模式。单机模式一般在生产环境中很少用,普通集群模式只是提高了系统的吞吐量,让集群中多个节点来服务某个 Queue 的读写操作。那么真正实现 RabbitMQ 高可用的是镜像集群模式。 镜像集群模式跟普通集群模式不一样的是,创建的 Queue,无论元数据还是Queue 里的消息都会存在于多个实例上,然后每次你写消息到 Queue 的时候,都会自动和多个实例的 Queue 进行消息同步。这样设计,好处在于:任何一个机器宕机不影响其他机器的使用。坏处在于:1. 性能开销太大:消息同步所有机器,导致网络带宽压力和消耗很重;2. 扩展性差:如果某个 Queue 负载很重,即便加机器,新增的机器也包含了这个 Queue 的所有数据,并没有办法线性扩展你的 Queue。 Kafka:partition 和 replica 机制 Kafka 基本架构是多个 broker 组成,每个 broker 是一个节点。创建一个 topic 可以划分为多个 partition,每个 partition 可以存在于不同的 broker 上,每个 partition 就放一部分数据,这就是天然的分布式消息队列。就是说一个 topic 的数据,是分散放在多个机器上的,每个机器就放一部分数据。 Kafka 0.8 以前,是没有 HA 机制的,任何一个 broker 宕机了,它的 partition 就没法写也没法读了,没有什么高可用性可言。 Kafka 0.8 以后,提供了 HA 机制,就是 replica 副本机制。每个 partition 的数据都会同步到其他机器上,形成自己的多个 replica 副本。然后所有 replica 会选举一个 leader 出来,生产和消费都跟这个 leader 打交道,然后其他 replica 就是 follower。写的时候,leader 会负责把数据同步到所有 follower 上去,读的时候就直接读 leader 上数据即可。Kafka 会均匀的将一个 partition 的所有 replica 分布在不同的机器上,这样才可以提高容错性。 MQ常用协议 AMQP协议 AMQP即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同开发语言等条件的限制。 优点:可靠、通用 MQTT协议 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议。 优点:格式简洁、占用带宽小、移动端通信、PUSH、嵌入式系统 STOMP协议 STOMP(Streaming Text Orientated Message Protocol)是流文本定向消息协议,是一种为MOM(Message Oriented Middleware,面向消息的中间件)设计的简单文本协议。STOMP提供一个可互操作的连接格式,允许客户端与任意STOMP消息代理(Broker)进行交互。 优点:命令模式(非topic/queue模式) XMPP协议 XMPP(可扩展消息处理现场协议,Extensible Messaging and Presence Protocol)是基于可扩展标记语言(XML)的协议,多用于即时消息(IM)以及在线现场探测。适用于服务器之间的准即时操作。核心是基于XML流传输,这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器不同。 优点:通用公开、兼容性强、可扩展、安全性高,但XML编码格式占用带宽大 其他基于TCP/IP自定义的协议:有些特殊框架(如:redis、kafka、zeroMq等)根据自身需要未严格遵循MQ规范,而是基于TCP\IP自行封装了一套协议,通过网络socket接口进行传输,实现了MQ的功能。 MQ的通讯模式 <stron> </stron>多点广播:MQ适用于不同类型的应用。其中重要的,也是正在发展中的是"多点广播"应用,即能够将消息发送到多个目标站点(Destination List)。可以使用一条MQ指令将单一消息发送到多个目标站点,并确保为每一站点可靠地提供信息。MQ不仅提供了多点广播的功能,而且还拥有智能消息分发功能,在将一条消息发送到同一系统上的多个用户时,MQ将消息的一个复制版本和该系统上接收者的名单发送到目标MQ系统。目标MQ系统在本地复制这些消息,并将它们发送到名单上的队列,从而尽可能减少网络的传输量。 发布/订阅(Publish/Subscribe)模式:发布/订阅功能使消息的分发可以突破目的队列地理指向的限制,使消息按照特定的主题甚至内容进行分发,用户或应用程序可以根据主题或内容接收到所需要的消息。发布/订阅功能使得发送者和接收者之间的耦合关系变得更为松散,发送者不必关心接收者的目的地址,而接收者也不必关心消息的发送地址,而只是根据消息的主题进行消息的收发。在MQ家族产品中,MQ Event Broker是专门用于使用发布/订阅技术进行数据通讯的产品,它支持基于队列和直接基于TCP/IP两种方式的发布和订阅。 集群(Cluster):为了简化点对点通讯模式中的系统配置,MQ提供 Cluster 的解决方案。集群类似于一个 域(Domain) ,集群内部的队列管理器之间通讯时,不需要两两之间建立消息通道,而是采用 Cluster 通道与其它成员通讯,从而大大简化了系统配置。此外,集群中的队列管理器之间能够自动进行负载均衡,当某一队列管理器出现故障时,其它队列管理器可以接管它的工作,从而大大提高系统的高可靠性 如何保证消息的顺序性? RabbitMQ 拆分多个 Queue,每个 Queue一个 Consumer;或者就一个 Queue 但是对应一个 Consumer,然后这个 Consumer 内部用内存队列做排队,然后分发给底层不同的 Worker 来处理。 Kafka 一个 Topic,一个 Partition,一个 Consumer,内部单线程消费,单线程吞吐量太低,一般不会用这个。 写 N 个内存 Queue,具有相同 key 的数据都到同一个内存 Queue;然后对于 N 个线程,每个线程分别消费一个内存 Queue 即可,这样就能保证顺序性。 如何避免消息重复消费? 在消息生产时,MQ内部针对每条生产者发送的消息生成一个唯一id,作为去重和幂等的依据(消息投递失败并重传),避免重复的消息进入队列。 在消息消费时,要求消息体中也要有一全局唯一id作为去重和幂等的依据,避免同一条消息被重复消费。 大量消息在 MQ 里长时间积压,该如何解决? 一般这个时候,只能临时紧急扩容了,具体操作步骤和思路如下: 先修复 consumer 的问题,确保其恢复消费速度,然后将现有 consumer 都停掉; 新建一个 topic,partition 是原来的 10 倍,临时建立好原先 10 倍的 queue 数量; 然后写一个临时的分发数据的 consumer 程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的 10 倍数量的 queue; 接着临时用 10 倍的机器来部署 consumer,每一批 consumer 消费一个临时 queue 的数据。这种做法相当于是临时将 queue 资源和 consumer 资源扩大 10 倍,以正常的 10 倍速度来消费数据; 等快速消费完积压数据之后,得恢复原先部署的架构,重新用原先的 consumer 机器来消费消息。 MQ 中的消息过期失效了怎么办? 如果使用的是RabbitMQ的话,RabbtiMQ 是可以设置过期时间的(TTL)。如果消息在 Queue 中积压超过一定的时间就会被 RabbitMQ 给清理掉,这个数据就没了。这时的问题就不是数据会大量积压在 MQ 里,而是大量的数据会直接搞丢。这个情况下,就不是说要增加 Consumer 消费积压的消息,因为实际上没啥积压,而是丢了大量的消息。 我们可以采取一个方案,就是批量重导。就是大量积压的时候,直接将数据写到数据库,然后等过了高峰期以后将这批数据一点一点的查出来,然后重新灌入 MQ 里面去,把丢的数据给补回来。 消息中间件如何做到高可用? 以Kafka为例。 Kafka 的基础集群架构,由多个broker组成,每个broker都是一个节点。当你创建一个topic时,它可以划分为多个partition,而每个partition放一部分数据,分别存在于不同的 broker 上。也就是说,一个 topic 的数据,是分散放在多个机器上的,每个机器就放一部分数据。 每个partition放一部分数据,如果对应的broker挂了,那这部分数据是不是就丢失了?那不是保证不了高可用吗? Kafka 0.8 之后,提供了复制多副本机制来保证高可用,即每个 partition 的数据都会同步到其它机器上,形成多个副本。然后所有的副本会选举一个 leader 出来,让leader去跟生产和消费者打交道,其他副本都是follower。写数据时,leader 负责把数据同步给所有的follower,读消息时,直接读 leader 上的数据即可。如何保证高可用的?就是假设某个 broker 宕机,这个broker上的partition 在其他机器上都有副本的。如果挂的是leader的broker呢?其他follower会重新选一个leader出来。 如何保证数据一致性,事务消息如何实现? 一条普通的MQ消息,从产生到被消费,大概流程如下: 生产者产生消息,发送带MQ服务器 MQ收到消息后,将消息持久化到存储系统。 MQ服务器返回ACk到生产者。 MQ服务器把消息push给消费者 消费者消费完消息,响应ACK MQ服务器收到ACK,认为消息消费成功,即在存储中删除消息。 举个下订单的例子吧。订单系统创建完订单后,再发送消息给下游系统。如果订单创建成功,然后消息没有成功发送出去,下游系统就无法感知这个事情,出导致数据不一致。如何保证数据一致性呢?可以使用事务消息。一起来看下事务消息是如何实现的吧。 生产者产生消息,发送一条半事务消息到MQ服务器 MQ收到消息后,将消息持久化到存储系统,这条消息的状态是待发送状态。 MQ服务器返回ACK确认到生产者,此时MQ不会触发消息推送事件 生产者执行本地事务 如果本地事务执行成功,即commit执行结果到MQ服务器;如果执行失败,发送rollback。 如果是正常的commit,MQ服务器更新消息状态为可发送;如果是rollback,即删除消息。 如果消息状态更新为可发送,则MQ服务器会push消息给消费者。消费者消费完就回ACK。 如果MQ服务器长时间没有收到生产者的commit或者rollback,它会反查生产者,然后根据查询到的结果执行最终状态。 如何设计一个消息队列? 首先是消息队列的整体流程,producer发送消息给broker,broker存储好,broker再发送给consumer消费,consumer回复消费确认等。 producer发送消息给broker,broker发消息给consumer消费,那就需要两次RPC了,RPC如何设计呢?可以参考开源框架Dubbo,你可以说说服务发现、序列化协议等等 broker考虑如何持久化呢,是放文件系统还是数据库呢,会不会消息堆积呢,消息堆积如何处理呢。 消费关系如何保存呢? 点对点还是广播方式呢?广播关系又是如何维护呢?zk还是config server 消息可靠性如何保证呢?如果消息重复了,如何幂等处理呢? 消息队列的高可用如何设计呢? 可以参考Kafka的高可用保障机制。多副本 -> leader & follower -> broker 挂了重新选举 leader 即可对外服务。 消息事务特性,与本地业务同个事务,本地消息落库;消息投递到服务端,本地才删除;定时任务扫描本地消息库,补偿发送。 MQ得伸缩性和可扩展性,如果消息积压或者资源不够时,如何支持快速扩容,提高吞吐?可以参照一下 Kafka 的设计理念,broker -> topic -> partition,每个 partition 放一个机器,就存一部分数据。如果现在资源不够了,简单啊,给 topic 增加 partition,然后做数据迁移,增加机器,不就可以存放更多数据,提供更高的吞吐量了吗。 ****
点赞 6
评论 0
全部评论
推荐
最新
楼层
暂无评论,快来抢首评~
相关推荐
10-14 14:05
西北工业大学 Java
滴滴一面面经
2025年10月14日 滴滴一面全程45分钟,无手撕。介绍一下你的项目。抢购场景下会面临高并发问题,你是如何处理并发的?如果系统每秒最多处理10个请求,但秒杀瞬间来了300个请求,你会如何设计系统来应对?在这种高并发秒杀场景下,如何避免超卖或少卖的问题?接口限流有哪些常见的策略或算法?热点数据既有查询又有更新,如何保证 Redis 缓存与数据库的一致性?请讲讲 ThreadLocal 的原理,以及使用时需要注意的问题(比如内存泄漏)。在项目中是否遇到过 SQL 查询性能问题?如何排查和优化慢查询?使用 EXPLAIN 分析 SQL 时,你主要关注哪些字段或指标?有一个表包含字段 id(int)...
点赞
评论
收藏
分享
昨天 15:50
同济大学 产品经理
讲真的,工作一年你就知道未来想要什么了
后知后觉,从去年七月毕业到现在入职快一年了。之前也听到前辈说过, “工作头一年,就能慢慢理解很多事”,以前确实也觉得这句话太虚,直到今天,在收钱吧工作的这一年,体会更加深刻。还觉得自己刚长大没几年呢,谁懂现在已经逐步过上了自己想要的生活了。记得刚毕业时还挺焦虑,担心会不会被各种毒打、被职场pua等等,直到今天,我真的挺庆幸在自己的努力下遇见了更值得的公司。刚入职的时候有专属的 mentor,从入职第一天的环境配置、权限申请,到后来的业务熟悉,再到如今独立承担很多重要项目,感觉这才是职场里比较友好的landing了。这一年其实也遇到很多困难的事情,种种下来的时候也都有过内耗,也很感谢我的前辈告诉...
点赞
评论
收藏
分享
10-12 09:59
已编辑
吉林大学 Java
各位大佬,百度发意向了,稳了吗😭
Gmail出了点问题,意向背景图没法显示,只有文字了想问问各位佬,发意向了稳吗,真想去百度
牛客79925948...:
百度求职进展汇总
点赞
评论
收藏
分享
09-01 16:09
门头沟学院 Java
兄弟们,美团是真不看笔试啊,30号笔试的时候和b站笔试冲突了,想了想美团可以顺延还是做了b站的,结果今天看了一下直接免笔试了😂
自来熟的放鸽子能手面...:
不看,0 0 0照样一周意向
投递美团等公司10个岗位
点赞
评论
收藏
分享
10-10 14:03
影石Insta360_深度学习算法工程师(准入职员工)
影石insta360内推,影石insta360内推码
工作氛围 大大小小的文档都可以申请权限,通过很快~学习前辈的文档能收获很多…实习生会参与周会、部门会、项目会等,深度参与正职们的工作,也可以看看其他组都在干些什么,有助于了解整个公司的运作模式😎公司整体年轻人很多,大家都很聊得来hhh到点下班mentor会催你走,尽管临近过年她们自己忙得晕头转向😵💫每个月有120min的迟到时间⏰真的很适合我…每个月都掐点用完2️⃣实习生薪资福利 💰薪资参考实习seng,个人认为对文科生来说蛮高的~加班会有餐补、车补等等(完没加过班,就没领过😂)✅日常有免费零食、咖啡等等,三八节七夕节这些节日还会发奖品。公司设备都可以借用,平时出去玩也可以借来拍~...
米哈游公司福利 4647人发布
点赞
评论
收藏
分享
评论
点赞成功,聊一聊 >
点赞
收藏
分享
评论
提到的真题
返回内容
全站热榜
更多
1
...
面试最后的反问环节,能问些什么?(附特供问题)
1.3W
2
...
从面试官的角度看待一场面试是怎么样的?
1.1W
3
...
最近面试回答不出来的题
8208
4
...
害,找工作哪有不上当的!
6529
5
...
从摆烂到OC,嵌入式人的血泪史
4757
6
...
作为普通家庭出身的我,为什么非大厂不可?
4317
7
...
双非硕的十月份秋招总结
4119
8
...
找到靠谱的公司,少走些弯路
3246
9
...
项目经历混乱?STAR法则手把手教你梳理(附真实案例分析过程)
3157
10
...
末9四段大厂实习|秋招收尾结束
2711
创作者周榜
更多
正在热议
更多
#
实习在多还是在精
#
12063次浏览
132人参与
#
反问环节如何提问
#
109436次浏览
2152人参与
#
爱玛科技集团求职进展汇总
#
32200次浏览
217人参与
#
你见过哪些工贼行为
#
7247次浏览
49人参与
#
我的求职进度条
#
7276次浏览
111人参与
#
找工作中的小确幸
#
18027次浏览
168人参与
#
实习下班不想学习,正常吗?
#
8931次浏览
115人参与
#
运营每日一题
#
103243次浏览
865人参与
#
秋招踩过的“雷”,希望你别再踩
#
36253次浏览
491人参与
#
设计人的面试记录
#
156785次浏览
1513人参与
#
校招谈薪一定要知道的事
#
6773次浏览
82人参与
#
远程面试的尴尬瞬间
#
194006次浏览
1253人参与
#
你觉得什么岗位会被AI替代
#
9957次浏览
131人参与
#
工作中,努力重要还是选择重要?
#
201985次浏览
2050人参与
#
顺丰求职进展汇总
#
60722次浏览
299人参与
#
选完offer后,你后悔学机械吗?
#
40417次浏览
243人参与
#
面试时最害怕被问到的问题
#
630563次浏览
8614人参与
#
社会教会你的第一课
#
106276次浏览
853人参与
#
浪潮求职进展汇总
#
18620次浏览
140人参与
#
实习生应该准时下班吗
#
291862次浏览
1613人参与
#
实习最想跑路的瞬间
#
83175次浏览
527人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务