首页
题库
公司真题
专项练习
面试题库
在线编程
面试
面试经验
AI 模拟面试
简历
求职
学习
基础学习课
实战项目课
求职辅导课
专栏&文章
竞赛
搜索
我要招人
发布职位
发布职位、邀约牛人
更多企业解决方案
AI面试、笔试、校招、雇品
HR免费试用AI面试
最新面试提效必备
登录
/
注册
Hpp_
齐齐哈尔大学 Java
发布于浙江
关注
已关注
取消关注
m
@一路向前y:
RabbitMQ面试题
目录什么是 rabbitmq?使用rabbitmq的场景(优点)消息队列有什么缺点?rabbitmq的构造交换机的类型消息怎么路由?消息分发机制如何确保消息正确地发送至RabbitMQ? 如何确保消息接收方消费了消息?消息基于什么传输?如何保证消息不被重复消费(幂等性问题)或重复投递?如何保证消息不丢失,进行可靠性传输?如何保证消息的有序性?如何处理消息堆积情况?几千万条数据在MQ里积压了七八个小时如何保证消息队列的高可用?什么是 rabbitmq?RabbitMQ:是在AMQP(高级消息队列协议)基础上完成的,服务器端用Erlang语言编写,是当前最主流的消息中间件之一使用rabbitmq的场景(优点)流量消峰:订单系统使用消息队列做缓冲,把一秒内下的订单分散成一段时间来处理,这时有些用户可能在下单十几秒后才能收到下单成功的操作应用解耦:比如物流系统因为发生故障,需要几分钟来修复。在这几分钟的时间里,物流系统要处理的内存被缓存在消息队列中,用户的下单操作可以正常完成异步处理消息队列有什么缺点?系统可用性降低:多加了个MQ进来系统复杂度提高:重复消费,处理消息丢失等问题rabbitmq的构造生产者Publisher:生产消息,就是投递消息的一方。消息一般包含两个部分:消息体(payload)和标签(Label)消费者Consumer:消费消息,也就是接收消息的一方。消费者连接到RabbitMQ服务器,并订阅到队列上。消费消息时只消费消息体,丢弃标签。Broker服务节点:表示消息队列服务器实体。一般情况下一个Broker可以看做一个RabbitMQ服务器。Queue:消息队列,用来存放消息。一个消息可投入一个或多个队列,多个消费者可以订阅同一队列,这时队列中的消息会被平摊(轮询)给多个消费者进行处理。Exchange:交换器,接受生产者发送的消息,根据路由键将消息路由到绑定的队列上。Routing Key: 路由关键字,用于指定这个消息的路由规则,需要与交换器类型和绑定键(Binding Key)联合使用才能最终生效。Binding:绑定,通过绑定将交换器和队列关联起来,一般会指定一个BindingKey,通过BindingKey,交换器就知道将消息路由给哪个队列了。Connection :网络连接,比如一个TCP连接,用于连接到具体brokerChannel: 信道,AMQP 命令都是在信道中进行的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为建立和销毁 TCP 都是非常昂贵的开销,所以引入了信道的概念,以复用一条 TCP 连接,一个TCP连接可以用多个信道。客户端可以建立多个channel,每个channel表示一个会话任务。Message:消息,由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。Virtual host:虚拟主机,用于逻辑隔离,表示一批独立的交换器、消息队列和相关对象。一个Virtual host可以有若干个Exchange和Queue,同一个Virtual host不能有同名的Exchange或Queue。最重要的是,其拥有独立的权限系统,可以做到 vhost 范围的用户控制。当然,从 RabbitMQ 的全局角度,vhost 可以作为不同权限隔离的手段交换机的类型direct:消息中的路由键(RoutingKey)如果和 Bingding 中的 bindingKey 完全匹配,交换器就将消息发到对应的队列中。是基于完全匹配、单播的模式fanout:把所有发送到fanout交换器的消息路由到所有绑定该交换器的队列中,fanout 类型转发消息是最快的topic:通过模式匹配的方式对消息进行路由,将路由键和某个模式进行匹配,此时队列需要绑定到一个模式上routing_key 不能随意写,必须满足一定的要求,它必须是一个单词列表,以点号分隔开,这些单词可以是任意单词,比如说:"stock.usd.nyse"单词列表最多不能超过 255 个字节替换符:(*)可以代替一个单词(#)可以替代零个或多个单词当一个队列绑定键是#,那么这个队列将接收所有数据,就有点像 fanout,如果队列绑定键当中没有#和*出现,那么该队列绑定类型就是 directheaders:不依赖于路由键进行匹配,是根据发送消息内容中的headers属性进行匹配,除此之外 headers 交换器和 direct 交换器完全一致,但性能差很多,目前几乎用不到了消息怎么路由?生产者生产发送消息声明交换器和队列以及相关属性,通过绑定键(binding key)将交换器和队列绑定起来Producer 先连接到 Broker,建立连接 Connection,开启一个信道 channelProducer 发送消息到 Broker,其中包含路由键(routing key)、交换器等信息交换器根据接收到的路由键查找匹配的队列如果找到,将消息存入对应的队列,如果没有找到,会根据生产者的配置丢弃或者退回给生产者关闭信道消费者接收消息Producer 先连接到 Broker,建立连接 Connection,开启一个信道 channel向 Broker 请求消费相应队列中消息,可能会设置响应的回调函数等待 Broker 回应并投递相应队列中的消息,接收消息消费者确认收到的消息,发送ack确认RabbitMQ从队列中删除已经确定的消息关闭信道消息分发机制轮训分发RabbitMQ默认采用的轮训分发,当一个消费者处理速度快一个慢的时候不适用不公平分发通过设置参数 channel.basicQos(1);实现不公平分发策略使得能者多劳预值分发当消息被消费者接收后,但是没有确认,此时这里就存在一个未确认的消息缓冲区,用于存储非被确认的消息,该缓存区的大小是没有限制的通过使用basic.qos方法设置“预取计数”值定义通道上允许的未确认消息的最大数量如何确保消息正确地发送至RabbitMQ? 如何确保消息接收方消费了消息?发送方确认模式:将信道设置成confirm模式(发送方确认模式),则所有在信道上发布的消息都会被指派一个唯一的ID。一旦消息被投递到目的队列后,或者消息被写入磁盘后(可持久化的消息),信道会发送一个确认给生产者(包含消息唯一 ID)。如果 RabbitMQ发生内部错误从而导致消息丢失,会发送一条nack(notacknowledged,未确认)消息。发送方确认模式是异步的,生产者应用程序在等待确认的同时,可以继续发送消息。当确认消息到达生产者应用程序,生产者应用程序的回调方法就会被触发来处理确认消息接收方确认机制:消费者接收每一条消息后都必须进行确认(消息接收和消息确认是两个不同操作)。只有消费者确认了消息,RabbitMQ才能安全地把消息从队列中删除这里并没有用到超时机制,RabbitMQ仅通过Consumer的连接中断来确认是否需要重新发送消息。也就是说,只要连接不中断,RabbitMQ给了Consumer足够长的时间来处理消息。保证数据的最终一致性消息基于什么传输?由于TCP连接的创建和销毁开销较大,且并发数受系统资源限制,会造成性能瓶颈。RabbitMQ使用信道的方式来传输数据。信道是建立在真实的TCP连接内的虚拟连接,且每条TCP连接上的信道数量没有限制如何保证消息不被重复消费(幂等性问题)或重复投递?数据库唯一主键去重:主键是不能冲突的,重复的数据无法插入引入Redis解决重复消费问题利用Redis,首先系统生成全局唯一的 id,用set操作放入Redis中如订单信息id,消费后存储在Redis中,如果下次再来,先查看Redis中是否存在如果存在,即此消息已经被消费过(后续不做消费处理)如果不存在,即未消费,此时再将此id存入Redis中,进行后续的逻辑操作如何保证消息不丢失,进行可靠性传输?三个角度来分析:生产者丢数据、消息队列丢数据、消费者丢数据生产者丢数据:RabbitMQ提供事务机制(transaction)和确认机制(confirm)两种模式来确保生产者不丢消息事务机制:发送消息前,开启事务(channel.txSelect()),然后发送消息,如果发送过程中出现什么异常,事务就会回滚(channel.txRollback()),如果发送成功则提交事务(channel.txCommit())该方式的缺点是生产者发送消息会同步阻塞等待发送结果是成功还是失败,导致生产者发送消息的吞吐量降下降 channel.txSelect try { // 发送消息 } catch(Exception e){ // 回滚事务 channel.txRollback; //再次重试发送这条消息 .... } //提交事务 channel.txCommit;确认机制:生产环境常用的是confirm模式。生产者将信道 channel 设置成 confirm 模式,一旦 channel 进入 confirm 模式,所有在该信道上发布的消息都将会被指派一个唯一的ID,一旦消息被投递到所有匹配的队列之后,rabbitMQ就会发送一个确认给生产者(包含消息的唯一ID),这样生产者就知道消息已经正确到达目的队列了。如果rabbitMQ没能处理该消息,也会发送一个Nack消息给你,这时就可以进行重试操作Confirm模式最大的好处在于它是异步的,一旦发布消息,生产者就可以在等信道返回确认的同时继续发送下一条消息,当消息最终得到确认之后,生产者便可以通过回调方法来处理该确认消息消息队列丢数据: 处理消息队列丢数据的情况,一般是开启持久化磁盘。持久化配置可以和生产者的 confirm 机制配合使用,在消息持久化磁盘后,再给生产者发送一个Ack信号。这样的话,如果消息持久化磁盘之前,即使 RabbitMQ 挂掉了,生产者也会因为收不到Ack信号而再次重发消息消息持久化:发送消息的时候将 deliveryMode 设置为 2,将消息设置为持久化的,此时 RabbitMQ 就会将消息持久化到磁盘上去队列持久化:创建queue的时候,将queue的持久化标志durable在设置为true,代表是一个持久的队列,这样就可以保证 rabbitmq 持久化 queue 的元数据,但是不会持久化queue里的数据消费者丢数据:消费者丢数据一般是因为采用了自动确认消息模式。该模式下,虽然消息还在处理中,但是消费中者会自动发送一个确认,通知 RabbitMQ 已经收到消息了,这时 RabbitMQ 就会立即将消息删除。这种情况下,如果消费者出现异常而未能处理消息,那就会丢失该消息采用手动确认消息,设置 autoAck = False,等到消息被真正消费之后,再手动发送一个确认信号,即使中途消息没处理完,但是服务器宕机了,那 RabbitMQ 就收不到发的ack,然后 RabbitMQ 就会将这条消息重新分配给其他的消费者去处理但是 RabbitMQ 并没有使用超时机制,RabbitMQ 仅通过与消费者的连接来确认是否需要重新发送消息,也就是说,只要连接不中断,RabbitMQ 会给消费者足够长的时间来处理消息需要考虑的情况:如果消费者接收到消息,在确认之前断开了连接或取消订阅,RabbitMQ 会认为消息没有被消费,然后重新分发给下一个订阅的消费者,所以存在消息重复消费的隐患如果消费者接收到消息却没有确认消息,连接也未断开,则RabbitMQ认为该消费者繁忙,将不会给该消费者分发更多的消息如何保证消息的有序性?方法一:拆分queue,使得一个queue只对应一个消费者由于MQ一般都能保证内部队列是先进先出的,所以把需要保持先后顺序的一组消息使用某种算法都分配到同一个消息队列中。然后只用一个消费者单线程去消费该队列,这样就能保证消费者是按照顺序进行消费的了但是消费者的吞吐量会出现瓶颈。如果多个消费者同时消费一个队列,还是可能会出现顺序错乱的情况,这就相当于是多线程消费了方法二:对于多线程的消费同一个队列的情况,可以使用重试机制:比如有一个微博业务场景的操作,发微博、写评论、删除微博,这三个异步操作,如果一个消费者先执行了写评论的操作,但是这时微博都还没发,写评论一定是失败的,等一段时间。等另一个消费者,先执行发微博的操作后,再执行,就可以成功如何处理消息堆积情况?几千万条数据在MQ里积压了七八个小时出现该问题的原因:消息堆积往往是生产者的生产速度与消费者的消费速度不匹配导致的。有可能就是消费者消费能力弱,渐渐地消息就积压了,也有可能是因为消息消费失败反复复重试造成的,也有可能是消费端出了问题,导致不消费了或者消费极其慢临时扩容,快速处理积压的消息:先修复 consumer 的问题,确保其恢复消费速度,然后将现有的 consumer 都停掉;临时创建原先 N 倍数量的 queue ,然后写一个临时分发数据的消费者程序,将该程序部署上去消费队列中积压的数据,消费之后不做任何耗时处理,直接均匀轮询写入临时建立好的 N 倍数量的 queue 中;接着,临时征用 N 倍的机器来部署 consumer,每个 consumer 消费一个临时 queue 的数据等快速消费完积压数据之后,恢复原先部署架构 ,重新用原先的 consumer 机器消费消息。这种做法相当于临时将 queue 资源和 consumer 资源扩大 N 倍,以正常 N 倍速度消费恢复队列中丢失的数据:如果使用的是 rabbitMQ,并且设置了过期时间,消息在 queue 里积压超过一定的时间会被 rabbitmq 清理掉,导致数据丢失,这种情况下,实际上队列中没有什么消息挤压,而是丢了大量的消息,所以就不能说增加 consumer 消费积压的数据了这种情况可以采取 “批量重导” 的方案来进行解决。在流量低峰期,写一个程序,手动去查询丢失的那部分数据,然后将消息重新发送到mq里面,把丢失的数据重新补回来MQ长时间未处理导致MQ写满的情况如何处理:如果消息积压在MQ里,并且长时间都没处理掉,导致MQ都快写满了,这种情况肯定是临时扩容方案执行太慢这种时候只好采用 “丢弃+批量重导” 的方式来解决了。首先,临时写个程序,连接到mq里面消费数据,消费一个丢弃一个,快速消费掉积压的消息,降低MQ的压力,然后在流量低峰期时去手动查询重导丢失的这部分数据如何保证消息队列的高可用?RabbitMQ 是基于主从(非分布式)做高可用性的,RabbitMQ 有三种模式:单机模式、普通集群模式、镜像集群模式单机模式:一般没人生产用单机模式普通集群模式:就是在多台机器上启动多个 RabbitMQ 实例,每个机器启动一个。我们创建的 queue,只会放在其中一个 RabbitMQ 实例上,但是每个实例都同步 queue 的元数据(元数据是 queue 的一些配置信息,通过元数据,可以找到 queue 所在实例)。消费的时候,如果连接到了另外一个实例,那么那个实例会从 queue 所在实例上拉取数据过来优点:普通集群模式主要用于提高系统的吞吐量,可以通过添加更加的节点来线性的扩展消息队列的吞吐量,就是说让集群中多个节点来服务某个 queue 的读写操作缺点:无高可用性,queue所在的节点宕机了,其他实例就无法从那个实例拉取数据;RabbitMQ 内部也会产生大量的数据传输镜像集群模式:
点赞 7
评论 1
全部评论
推荐
最新
楼层
暂无评论,快来抢首评~
相关推荐
今天 10:25
蚌埠坦克学院 嵌入式软件开发
龙旗科技Linux驱动开发 一面试题
1. 做一个自我介绍,重点讲一下你的项目经历参考回答方式:基本信息:我叫XXX,XX大学XX专业,预计XX年毕业,主修嵌入式系统方向技术背景:熟练掌握C/C++、Linux系统编程、数据结构算法,有X年的学习/实习经验项目经历: 项目一:基于STM32的智能监测系统,负责传感器驱动和数据采集模块,使用DMA+RTOS实现多任务调度,解决了实时性问题项目二:嵌入式通信系统,设计了可靠的通信协议,实现了CRC校验和超时重传机制个人特点:学习能力强,能快速上手新技术,对底层驱动开发有浓厚兴趣,能吃苦耐劳控制在2-3分钟2. volatile关键字的作用是什么?什么场景下使用?答案要点:1. vola...
嵌入式面试八股文全集
点赞
评论
收藏
分享
01-31 13:34
腾讯_Android客户端开发
字节飞书 安卓三面
自我介绍快手低端机性能优化专项中,你负责的具体工作是什么?提出了哪些优化策略?安卓系统的 AOT 编译是什么时候执行的?强制 AOT 编译如何提升 APP 运行性能?Glide 图片加载库的三级缓存机制中,活动缓存和内存缓存的区别是什么?缓存 key 是如何计算的?快手智能音量调节需求的核心逻辑是什么?如何通过传感器数据替代麦克风权限获取环境音量?计算音量分贝值的公式和关键步骤是什么?音频采样率、编码格式等参数的作用是什么?安卓 Activity 的生命周期有哪些关键钩子函数?onStart 和 onResume 的区别是什么?如果 APP 耗电严重,如何排查和优化?安卓后台更新功能如何实现?...
查看26道真题和解析
点赞
评论
收藏
分享
01-16 11:36
西北工业大学 C++
组长说外包不能吃零食
平时跟组长打打闹闹的,以为他把我当自己人,直到我伸手去拿魔芋爽,组长说外包不能吃零食
哞客37422655...:
外包工位用警戒线围起来
找实习记录
点赞
评论
收藏
分享
01-28 14:23
西北大学 安卓
我用Notion+AI整理面经,2周从迷茫到拿3个offer
春招在即,无论是26届,还是即将找实习的27、28届。都会面临一个问题:去网上看了很多公司面经,面试时一个都想不起来。今天我教你用Notion建立面经管理系统,再配合AI做分析,让你从从容容,游刃有余。减少求职的压力。 1.在Notion中新建表格用来记录面试进度和刷题进展。如下图:这样可以清楚的展示你的面试进度以及你今天要复习什么,打开后面的面经链接就可以了。附上表格模板: 面经数据库(主表格) ├─ 基础信息 │ ├─ 公司 │ ├─ 岗位 │ └─ 面试日期 ├─ 技术考察 │ ├─ 高频题 │ ├─ 考察重点 │ └─ 难度评级(1-5星) └─ 我的准备 ├─ 准备状态 ├─ 复习次...
查看2道真题和解析
点赞
评论
收藏
分享
评论
点赞成功,聊一聊 >
点赞
收藏
分享
评论
提到的真题
返回内容
全站热榜
更多
1
...
AI 应用开发学习全景路线图
1.6W
2
...
大厂到底想要什么样的人???
4941
3
...
害怕被嘲笑就不去做了吗?
4331
4
...
2026的你,应该知道哪些AI面试题?
2132
5
...
面试官视角聊聊,AI大模型产品到底是做什么的?
1825
6
...
我用AI做了个小游戏,来玩!
1468
7
...
测试/测开方向刷题经验分享
1416
8
...
后端 offer选择
983
9
...
字节财经业务一面凉经
950
10
...
如何用AI快速制作Web版Galgame
776
创作者周榜
更多
正在热议
更多
#
在大厂上班是一种什么样的体验
#
4258次浏览
64人参与
#
找工作的破防时刻
#
251502次浏览
1951人参与
#
程序员找工作至少要刷多少题?
#
8807次浏览
143人参与
#
你投递的公司有几家约面了?
#
157737次浏览
995人参与
#
论秋招对个人心气的改变
#
5620次浏览
104人参与
#
我的AI电子员工
#
26073次浏览
159人参与
#
OPPO求职进展汇总
#
770796次浏览
5396人参与
#
为了减少AI幻觉,你注入过哪些设定?
#
1693次浏览
53人参与
#
刚入职的你踩过哪些坑
#
4025次浏览
89人参与
#
程序员能干到多少岁?
#
5553次浏览
89人参与
#
一张图晒一下你的AI员工
#
2765次浏览
61人参与
#
牛客AI体验站
#
3010次浏览
82人参与
#
我现在比当时_,你想录用我吗
#
3505次浏览
63人参与
#
想辞职但是不敢的原因
#
20113次浏览
88人参与
#
ai智能作图
#
624584次浏览
5627人参与
#
AI Coding的使用心得
#
2187次浏览
57人参与
#
关于春招/暑期实习,你想知道哪些信息?
#
3708次浏览
82人参与
#
牛客租房专区
#
146648次浏览
1463人参与
#
晒晒你司的新年福利
#
3806次浏览
67人参与
#
虾皮求职进展汇总
#
373292次浏览
2792人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务