消息队列——经典5连问——你能抗几道?

面试归来,问几道牛逼UNIX C/C++笔试题 1、从N个数中选出n个最大的数,写出思路和实现。 《编程之美》上有讲这个算法的设计与思路。我这里简单写几个思路:(a)如果N能在主存中一次读入,则先进行快排,然后再取前n个数。算法复杂度:O(NlogN).(b)如果N非常大,假设不能一次读入内存,并且n不是很大的话,可以维护一个n个元素的有序队列,队列中都是每个元素都是已经读入的数中的前n大的数字。每读入一个数就跟这n个已 阅读详情
  • 面试题1:说说你对消息队列的理解,消息队列为了解决什么问题?
  • 追问1:消息队列有什么优缺点
  • 面试题2:对于消息中间机,你们是怎么做技术选型的?
  • 面试题3:如何确保消息正确地发送至 RabbitMQ?如何确保消息接收方消费了消息?
  • 追问1:如何保证MQ消息的可靠传输?

面试题1:说说你对消息队列的理解,消息队列为了解决什么问题?

我们公司业务系统一开始体量较小,很多组件都是单机版就足够,后来随着用户量逐渐扩大,我们程序也采用了微服务的设计思想,把很多服务进行了拆分,但后来在一些秒杀抢票活动或高频业务中,服务依旧扛不住大量QPS,因此我们引入了消息队列来优化该类问题。

消息队列应用的场景大致分为三类:解耦、异步、削峰。

解耦

消息队列类似设计模式中的观察者模式(Observer)或发布-订阅模式(Pub-Sub)。生产者生成和发送消息到消息队列,消费者从消息队列中取走消息进行处理,称为消费,使用消息队列将“生产者”和“消费者”之间的操作关联解耦,易于扩展。

比如系统A为支付系统,一开始用户支付完调用日志记录系统B记录就完了,后来内容越来越多,支付完成要调用加积分系统C、短信通知系统D、优惠券系统E等等…

这个场景中,A 系统跟其它各种乱七八糟的系统严重耦合,A 系统产生一条支付成功的数据,很多系统接口都需要 A 系统调用把支付成功的数据发送过去。A 系统程序员要时刻考虑这些问题:

  • 其他系统如果挂了该咋办?是不是直接程序抛异常了?
  • 一天到晚加业务,每次都重新部署?领导是不是狗?

那如果引入 MQ,A 系统产生一条数据,发送到 MQ 里面去,每个子系统加上对消息队列中支付成功消息的订阅,持续监听就可以了,哪个系统需要数据自己去 MQ 里面消费。如果新系统需要数据,直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可。

这样下来,A系统压根儿不需要去考虑要给谁发送数据,不需要维护这个代码,也不需要考虑人家是否调用成功、失败超时等情况,我只负责把支付成功的信息放到MQ里就行了,至于能否正常加积分、能否正常短信通知,管我鸟事!~~可见,通过一个 MQ,Pub/Sub 发布订阅消息这么一个模型,A 系统就跟其它系统彻底解耦了。

面试官:哦,那我听出来了,你这是喜欢甩锅啊!来,简历还你。

数据一致性

这个其实是分布式服务本身就存在的一个问题,不仅仅是消息队列的问题,但是放在这里说是因为用了消息队列这个问题会更明显。

就像咱们上面说的,你支付成功的服务自己保证自己的逻辑成功处理了,你成功发了消息,但是短信系统,积分系统等等这么多系统,他们成功还是失败你就不管了?当然不行,这样坑队友的行为,狄大人都帮不了你~

怎么办?那就把所有的服务都放到一个事务里,所有都成功成功才能算这一次下单是成功的,要成功一起成功,要失败一起失败。

异步

A 系统接收一个请求,需要在自己本地写库,还需要在 BCD 三个系统写库,自己本地写库要 3ms,BCD 三个系统分别写库要 300ms、400ms、200ms。最终请求总延时是 3 + 300 + 400 + 200 = 903ms,接近 1秒,用户感觉搞个毛线?慢的一批。

一般互联网类的企业,对于用户直接的操作,一般要求是每个请求都必须在 200 ms 以内完成,对用户几乎是无感知的,如果1秒足以说明该系统不可用,垃圾系统。

如果这里使用了消息队列,那么 A 系统连续发送 3 条消息到 MQ 队列中,假如耗时 5ms,A 系统从接受一个请求到返回响应给用户,总时长是 3 + 5 = 8ms,对于用户而言,其实感觉上就是点个按钮,8ms 以后就直接返回了,体验感很好

削峰

比如我们系统有代售抢票业务,平时每天QPS也就50左右,A 系统风平浪静。结果每次一到春运抢票,每秒并发请求数量突然会暴增到10000以上。但是系统是直接基于 MySQL 的,大量的请求直接打到 MySQL,比如一般MySQL能抗2000条请求,现在每秒10000 条 SQL,可能就直接把 MySQL 给打死了,导致系统崩溃。但是高峰期一过就又没人了,QPS回到50,对整个系统几乎没有任何的压力。

如果这里使用 MQ,每秒 1w 个请求写入 MQ,A 系统每秒钟最多处理 2000 个请求,因为 MySQL 每秒钟最多处理 2k 个。A 系统从 MQ 中慢慢拉取请求,每秒钟就拉取 2k 个请求,不要超过自己每秒能处理的最大请求数量就 ok了,这样下来,哪怕是高峰期的时候,A 系统也不会挂掉。当然了,用户的响应时间肯定会受影响,毕竟秒杀嘛,只要把前多少条请求处理好,其余的抢票失败就行了。

另外,MQ 每秒钟 1w 个请求进来,只处理 2k 个请求出去,结果会导致在中午高峰期,可能有几十万甚至几百万的请求积压在 MQ 中。

这个短暂的高峰期积压是 ok 的,因为高峰期过了之后,每秒钟就 50 个请求进 MQ,但是A 系统依然会按照每秒 2k 个请求的速度在处理。所以说,只要高峰期一过,A 系统就会快速将积压的消息给消费掉。

追问1:消息队列有什么优缺点

  • 系统可用性降低

系统引入的外部依赖越多,越容易挂掉。本来你就是 A 系统调用 BCD 三个系统的接口就好了,人 ABCD 四个系统好好的,没啥问题,你偏加个 MQ 进来,万一 MQ 挂了咋整,MQ 一挂,整套系统崩溃的,你不就完了?如何保证消息队列的高可用?

  • 系统复杂度提高

硬生生加个 MQ 进来,你怎么保证消息一定被消费?如何避免消息重复投递或重复消费?数据丢失怎么办?怎么保证消息传递的顺序性?

  • 一致性问题

A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。

面试题2:对于消息中间机,你们是怎么做技术选型的?

目前市面上比较主流的消息队列中间件主要有,Kafka、ActiveMQ、RabbitMQ、RocketMQ 等。

ActiveMQ和RabbitMQ这两由于吞吐量的原因,只有业务体量一般的公司在用,RabbitMQ由于是erlang语言开发的,我们都不了解,因此扩展和维护成本都很高,查个问题都头疼。

Kafka和RocketMQ一直在各自擅长的领域发光发亮,两者的吞吐量、可靠性、时效性等都很可观。

我们通过图表看看这几个消息中间机的对比:

大家其实一下子就能看到差距了,就拿吞吐量来说,早期比较活跃的ActiveMQ 和RabbitMQ基本上不是后两者的对手了,在现在这样大数据的年代吞吐量是真的很重要。

面试题3:如何确保消息正确地发送至 RabbitMQ?如何确保消息接收方消费了消息?

发送方确认模式

将信道设置成confirm模式(发送方确认模式),则所有在信道上发布的消息都会被指派一个唯一的ID。

一旦消息被投递到目的队列后,或者消息被写入磁盘后(可持久化的消息),信道会发送一个确认给生产者(包含消息唯一ID)。

如果RabbitMQ发生内部错误从而导致消息丢失,会发送一条Nack(not acknowledged,未确认)消息。

发送方确认模式是异步的,生产者应用程序在等待确认的同时,可以继续发送消息。当确认消息到达生产者应用程序,生产者应用程序的回调方法就会被触发来处理确认消息。

接收方确认机制

消费者接收每一条消息后都必须进行确认(消息接收和消息确认是两个不同操作)。只有消费者确认了消息,RabbitMQ才能安全地把消息从队列中删除。

这里并没有用到超时机制,RabbitMQ仅通过Consumer的连接中断来确认是否需要重新发送消息。也就是说,只要连接不中断,RabbitMQ给了Consumer足够长的时间来处理消息。保证数据的最终一致性;

追问1:如何保证MQ消息的可靠传输?

以我们常用的RabbitMQ为例,消息不可靠的情况可能是消息丢失,劫持等原因;

丢失又分为:生产者丢失消息、消息队列丢失消息、消费者丢失消息;

生产者丢失消息:从生产者弄丢数据这个角度来看,RabbitMQ提供confirm模式来确保生产者不丢消息;

confirm模式用的居多:一旦channel进入confirm模式,所有在该信道上发布的消息都将会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列之后;RabbitMQ就会发送一个ACK给生产者(包含消息的唯一ID),这就使得生产者知道消息已经正确到达目的队列了;

如果rabbitMQ没能处理该消息,则会发送一个Nack消息给你,你可以进行重试操作。

消息队列丢数据:消息持久化。

处理消息队列丢数据的情况,一般是开启持久化磁盘的配置。

持久化配置和confirm机制配合使用,在消息持久化磁盘后,再给生产者发送一个Ack信号。

这样,如果消息持久化磁盘之前,rabbitMQ阵亡了,那么生产者收不到Ack信号,生产者会自动重发。

面试官:那你说说如何避免消息重复投递或重复消费?消息是基于什么传输的?
我:今天累了,不想说了,下次吧~
面试官:???
我:对了,简历给我来。
面试官:嘶~
我:怎么,玩不起了?

累了,不想说了,下次吧~
面试官:???
我:对了,简历给我来。
面试官:嘶~
我:怎么,玩不起了?

Unity URP半透明物体渲染避坑指南:双面渲染与深度写入的实战技巧 本文深入探讨了Unity URP中半透明物体自交叠渲染问题的核心根源与解决方案。针对模型自身交叠导致的排序错误,文章提供了双面渲染与深度写入两种实战技巧,详细分析了其实现原理、性能开销及适用场景,帮助开发者根据项目需求选择最优方案,有效提升玻璃、水体等材质的视觉表现。 阅读详情

相关推荐

自动化学报Ctex+texstudio配置方法

自动化学报Latex的模板win10使用方法(CTEX+texstudio)

zxy15924462502的博客 7379

Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day31】—— 消息队列1

百日闭关修炼,每日三道高频面试题。一起冲进大厂!今天是消息队列1,看什么看?快上车!

陈哈哈的菜园子 1万+

SD - WAN:企业出海的网络加速器

例如,一家中国的跨境电商企业,在欧美市场的促销活动期间,借助 SD - WAN 技术,即使面对海量订单数据的交互,也能确保欧美客户在浏览商品、下单支付时感受到近乎本地网络的流畅体验,大大提升了客户满意度,稳住了销售增速。企业无需在海外本地部署大量冗余服务器,只需依托云台,借助 SD - WAN 快速稳定的网络连接,即可轻松实现业务拓展,进一步精简运营架构,提升整体效能。在未来,随着技术的不断演进和企业出海需求的持续增长,SD - WAN 将持续赋能,助力更多企业在全球市场扬帆远航,书写辉煌篇章。

idcicp_com的博客 448

消息队列 相关面试题

消息队列 相关面试题

qq_45818776的博客 1423

FreeModbus V1.6主机模式实战:如何在STM32上实现Modbus RTU主从一体通信

本文详细介绍了如何在STM32平台上利用FreeModbus V1.6开源协议栈实现Modbus RTU主从一体通信。文章深入剖析了V1.6版本主机模式的架构设计,提供了从硬件配置、串口与定时器移植到FreeRTOS操作系统适配的完整实战指南,并分享了数据缓冲区管理、多线程协同及高级调试技巧,为构建稳定可靠的工业通信网关提供了系统化解决方案。

weixin_29194255的博客 375

别再折腾老教程了!树莓派4B/5最新系统(Raspberry Pi OS Bookworm)红外遥控配置,用gpio-ir驱动一次成功

本文详细介绍了树莓派4B/5在最新Raspberry Pi OS Bookworm系统下配置红外遥控的完整指南,摒弃过时的lirc-rpi驱动,采用现代gpio-ir驱动方案。从硬件连接到软件配置,提供10分钟快速上手指南,涵盖驱动加载、信号测试、按键映射及高级应用场景,帮助用户高效完成红外遥控配置。

weixin_42520909的博客 442

面试遇到消息队列,不要怕,看这里

消息队列四大常见问题如何解决

Jesse的博客 3303

HDMI调试避坑指南:从AVI InfoFrame到通用控制包,这些DataIsland Packet细节千万别忽略

本文深入解析HDMI调试中DataIsland数据包的关键细节,包括AVI InfoFrame、通用控制包和音频时钟再生包(ACR)的配置与故障排查。通过实际案例和寄存器配置示例,帮助工程师快速定位显示异常、色彩失真和音频中断等问题,提升HDMI接口调试效率。

weixin_30897233的博客 637

Java 开发中 RabbitMQ 面试题(16 道)

这 16 道面试题涵盖了 RabbitMQ 的基本知识、API 应用和高级应用三个方面,旨在全面考察面试者对 RabbitMQ 的掌握程度,以及使用 RabbitMQ 开发应用程序的能力。从理解 RabbitMQ 的基本概念到使用 Java 代码编写 RabbitMQ 应用,再到实现延迟队列和消息重试等高级功能,这些题目能够帮助面试官深入了解面试者的技术水平和实践经验。

silenceallat的博客 1216

05 - matlab m_map地学绘图工具基础函数 - 设置比例尺指北针

本篇介绍下m_map中添加指北针(m_northarrow)、比例尺(m_ruler)和进行比例缩放(m_scale)的函数及其用法 。提供了 示例以便参考,罗列了 各函数可设属性。希望对绘图的你有所帮助。

weixin_43339605的博客 1948

linux arm64 Debian12移植操作手册

2023年6月10号Debian官方出了debian12 arm64版本的。如果需要完全适配这个系统的话,需要linux6.10版本。应客户的需求,需要在Debian11升级为Debian12版本。

qq_45147279的博客 2169

面试官:为啥要使用消息队列

面试官:为啥要使用消息队列 面试官:你在系统里用过消息队列吗?(面试官在随和的语气中展开了面试) 候选人:用过的(此时感觉没啥) 面试官:那你说一下你们在项目里是怎么用消息队列的? 候选人:巴拉巴拉,“我们啥啥系统发送个啥啥消息到队列,别的系统来消费啥啥的。比如我 们有个订单系统,订单系统每次下一个新的订单的时候,就会发送一条消息到 ActiveMQ 里 面去,后台有个库存系统负责获取消息然后更新库存。” (部分同学在这里会进入一个误区,就是你仅仅就是知道以及回答你们是怎么用这个消息队列 的,用这个消息队列

王小明的专栏 463

【系统分析师】2009年真题:综合知识-答案及详解

在某银行业务的用例模型中,“取款”用例需要等到“存款”用例执行之后才能执行,两个用例之间的关系属于(1);“取款”和“存款”两个用例中都需 要执行查询余额的功能,将查询余额提取成独立的用例,那么“取款”和“存款” 用例与“查询余额”用例之间的关系属于(2)。(1)A. 关联关系 B. 扩展关系 C. 使用关系 D. 依赖关系 (2)A. 扩展关系 B. 使用关系 C. 依赖关系 D. 继承关系【参考答案】D、A雇员类含有计算报酬的行为,利用面向对象的(3),可以使得其派生类专职 雇员类和兼职雇员类计算报酬的

数据知道的博客 1万+

消息队列—经典5连问—你能抗几道?

作者:熬夜不加班链接:https://www.jianshu.com/p/2f57f4f43508面试题1:说说你对消息队列的理解,消息队列为了解决什么问题?追问1:消息队列有什么优缺点面...

架构师小秘圈 187

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Redis 随机问,看看你能坚持几道?

小A,我们先聊聊 Redis,你能简要介绍一下什么是 Redis 吗?当然,Redis 是一个开源的内存数据结构存储系统,用作数据库、缓存和消息代理。它支持多种数据结构,比如字符串、散列、列表、集合和有序集合等。Redis 的数据存储在内存中,可以持久化到磁盘,并且提供复制、Lua 脚本、LRU 驱逐、事务等功能。很好,那么你知道什么是跳表吗?跳表是一种基于链表的随机化数据结构,支持快速查找、插入和删除操作。它通过在链表上增加多级索引,实现类似平衡树的对数级别操作效率。那跳表的数据结构是什么样的?

yellowCodeRabbit的博客 851

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

吃透这几道MQ消息队列面试题,秒杀面试官...

几种常见的MQ面试题 相关视频参考(来自动力节点):https://www.bilibili.com/video/BV1Ap4y1D7tU 相关资料下载:http://www.bjpowernode.com/?csdn 为什么使用消息队列? 其实就是问问你消息队列都有哪些使用场景,然后你项目里具体是什么场景,说说你在这个场景里用消息队列是什么? 面试官问你这个问题,期望的一个回答是说,你们公司有个什么业务场景,这个业务场景有个什么技术挑战,如果不用 MQ 可能会很麻烦,但是你现在用了 MQ 之后带

Javanewspaper的博客 613

2020 Python 面试 100 问,你会几道?

来源公众号:zone7 链接:https://mp.weixin.qq.com/s/D__1dv3W6-8je__Hvd4I3w内容出自zone大佬耗时数月做的编程面试题小程序「编...

python爬虫人工智能大数据 4044

熟悉这几道 Redis 高频面试题,面试不用愁

1、说说 Redis 都有哪些应用场景? 缓存:这应该是 Redis 最主要的功能了,也是大型网站必备机制,合理地使用缓存不仅可以加 快数据的访问速度,而且能够有效地降低后端数据源的压力。 共享Session:对于一些依赖 session 功能的服务来说,如果需要从单机变成集群的话,可以选择 redis 来统一管理 session。 消息队列系统:消息队列系统可以说是一个大型网站的必备基础组件,...

平头哥的技术博文 8585

大厂面试官最爱追问的几道题,这回有答案了

最近一个哥们去面试字节跳动了,其中几个他印象深刻的面试题你们品品:1、React / Vue.js 之类的框架为什么需要给组件添加 key 属性,其作用是什么?2、如何判断当前代码是运行...

LuckyWinty的博客 400

《分享几道高频 Redis 高频面试题,面试不用愁》

1、说说 Redis 都有哪些应用场景? 缓存:这应该是 Redis 最主要的功能了,也是大型网站必备机制,合理地使用缓存不仅可以加 快数据的访问速度,而且能够有效地降低后端数据源的压力。 共享Session:对于一些依赖 session 功能的服务来说,如果需要从单机变成集群的话,可以选择 redis 来统一管理 session。 消息队列系统:消息队列系统可以说是一个大型网站的...

公众号【Java大蜗牛】 217

大厂面试必问!突围金三银四面试季!面试必问

我有话要说,请仔细看完 我发现一个现象,很多开发5年的程序员仍然停留在crud的阶段,这是什么原因? 最主要的原因就是基础很差,尤其对于JVM和并发编程这方面掌握的比较差,而JVM和并发编程就是非常非常重要的基础了,作为一个Java开发人员如果你连JVM和并发编程掌握的很差,那你是无法写出高质量的代码的,直白说,你就只能做crud的工作,理想的工作和薪资跟你是无缘的,同时也很容易被行业淘汰! 现在大厂面试肯定是从基础开始发问,下面我也贴出了阿里招聘Java开发人员的要求,可以详细的看一下,下面几道是阿里面试

167

面试官最爱追问的几道题,这回有答案了

最近一个哥们去面试字节跳动了,其中几个他印象深刻的面试题你们品品:1、React / Vue.js 之类的框架为什么需要给组件添加 key 属性,其作用是什么?2、如何判断当前代码是运行在...

祈澈菇凉 605

分享几道 Redis 高频面试题,面试不用愁

1、说说 Redis 都有哪些应用场景? 缓存:这应该是 Redis 最主要的功能了,也是大型网站必备机制,合理地使用缓存不仅可以加 快数据的访问速度,而且能够有效地降低后端数据源的压力。 共享Session:对于一些依赖 session 功能的服务来说,如果需要从单机变成集群的话,可以选择 redis 来统一管理 session。 消息队列系统:消息队列系统可以说是一个大型网站的必备基础组件,因为其具有业务 解耦、非实时业务削峰等特性。Redis提供了发布订阅功能和阻塞队列的..

m0_67322837的博客 344
上一篇: 实际应用中MySQL分库分表实践总结原理
下一篇: 关于equals()方法,jdk源码给出如下五点建议,你知道哪些?
Javaesandyou
博客等级 码龄5年 742粉丝 563原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值