面试官:说出八种消息队列的应用场景。啊?八种?

简介: 本文来源于公众号:胖滚猪学编程。转载请注明出处! 一个风度翩翩,穿着格子衬衣的中年男子,拿着一个满是划痕的mac向她走来,看着铮亮的头,胖滚猪心想,这肯定是尼玛顶级架构师吧!完了要挂了。 结果面试官第一个问题,就让胖滚猪内心暗喜 面试官:消息队列这东西,你还熟悉吧?消息队列在企业中的应用场景有哪些? (这么基础的问题,手到擒来好吗?原来阿里不过如此。

本文来源于公众号:胖滚猪学编程。转载请注明出处!

_1

一个风度翩翩,穿着格子衬衣的中年男子,拿着一个满是划痕的mac向她走来,看着铮亮的头,胖滚猪心想,这肯定是顶级架构师吧!完了

结果面试官第一个问题,就让胖滚猪内心暗喜

面试官:消息队列这东西,你还熟悉吧?消息队列在企业中的应用场景有哪些?

(这么基础的问题,手到擒来好吗?原来阿里不过如此。)

胖滚猪:嗯嗯,还挺熟悉的,可以用于流量削峰、应用解耦、异步处理。

面试官:就这三种吗?能不能再多说几个应用。起码八种吧。

(胖滚猪火冒三丈,尼玛八种哪来的?玩我呢?但是出于礼貌,还是毕恭毕敬的回答面试官)

胖滚猪:额。。有这么多吗?不好意思,一时之间想不起来了呢。

面试官:哎。。大家都知道的我们不屑,就想听听不一样的。回家去吧

胖滚猪内心挫败,平时五毛钱都舍不得花的抠猪,豪掷100大洋打了飞车来到导师胖滚熊家里求助。

_2

胖滚熊:我先给你归纳了消息队列八种场景,如图所示,接下来我们再仔细说说每种场景的应用方案。

image

首先还是要介绍一下流量削峰、应用解耦、异步处理的具体应用,虽然网上文章到处都有,不过毕竟它们是老大,老大不出场小二也不敢乱动。如果你很熟悉了,可以直接跳过!

应用解耦:

某电商系统架构如图,用户下单之后首先进入订单系统,之后订单系统又将订单信息发送给物流系统和短信系统:
image
码农胖滚猪很快就写完了相关代码:

        OrderInfo orderInfo = new OrderInfo();
        //省略组装订单信息
        sendToMessage(orderInfo);//发送给短信系统
        sendToLogistics(orderInfo);//发送给物流系统

一切就这么平安无事过了大半月,领导又要搞啥实时大屏,实时展示当天订单量,于是订单系统又要将订单信息发送给实时大屏系统
image

也没关系,码农胖滚猪又改了订单系统的代码,重新上线:

        OrderInfo orderInfo = new OrderInfo();
        //省略组装订单信息
        sendToMessage(orderInfo);//发送给短信系统
        sendToLogistics(orderInfo);//发送给物流系统
        sendToRealTimeSys();//发送给实时分析系统

随着公司业务的壮大,订单信息又要发送给监控系统、数据挖掘系统。。。这会胖滚猪不淡定了“到底何时是个头呀!”

不仅如此,一旦下游某个系统异常,直接导致订单系统也异常了,时常收到顾客的投诉 “你们这电商系统!不用了!”

嗨,胖滚猪,早知如此何必当初呢?在1.0版本你就不应该让系统之间相耦合呀!如图:

image

订单系统只管将订单信息发到消息队列中,其他系统都从消息队列中拿数据。这样一来:

1、订单系统再也不用关心谁要用了,即使增加、减少下游系统或是下游系统需求如何变化,订单服务都无需做任何更改,实现了订单服务与下游服务的解耦!可以一个人自由飞翔了~
2、其他系统即便挂了或者请求超时,都跟订单系统无关,只跟消息队列有关。

哇,这样真是太爽了!和花钱一样爽!

异步处理

最近胖滚猪负责的用户系统一直被投诉,原因是太慢了!点击确认注册之后要1s才返回结果。你看看人家阿里的系统,点击注册10ms就可以返回结果了!

可是胖滚猪表示很无能为力,注册之后要写数据库、要发短信、还要发邮件,你让我怎么快呢?阿里的机器比我们好,才比我们快的!
image

嗨,胖滚猪,你可别把锅甩给机器啊,明明是你自己的设计缺陷呐,看我给你改改:
image

这样是不是觉得清爽了很多呢??

注册是主要的业务,而发短信和邮件通知用户已经注册成功是非主要的业务,甚至无关紧要,何必让无关的东西影响主要的东西呢?
假设三个业务节点每个使用100ms,不考虑网络等其他开销,则串行方式的时间是300ms,并行的时间可能是150ms。
透心凉心飞扬,这回省了不少时间,可以用来撩妹了。

流量削峰

胖滚猪在公司平安无事的呆了大半年,睡觉从没被电话骚扰,直到2020.5.20这天,xx明星po出结婚照,瞬间几千万的流量,撑爆了微博,而明星同款520T恤的热卖,也瞬间压垮了胖滚猪的电商系统。

胖滚猪好吃好喝大半年,没想到好日子还是终结了,半夜爬起来处理服务器故障,第二天无精打采的,太难受了。。

嗨,胖滚猪,早知如此,当初就应该考虑仔细呀!一个电商系统,秒杀场景是迟早会出现的!

上下游对于事情的处理能力是不同的。比如,Web前端每秒承受上千万的请求,并不是什么神奇的事情。但数据库的处理能力却十分有限,即使使用SSD加分库分表,单机的处理能力仍然在万级。由于成本的考虑,我们不能奢求数据库的机器数量追上前端。所以,利用中间系统转储两个系统的通信内容,并在下游系统有能力处理这些消息的时候,再处理这些消息,是一套相对较通用的方式。

我们需要设计一套足够健壮的架构来将后端的服务保护起来。设计思路是,使用消息队列隔离网关和后端服务,以达到流量控制和保护后端服务的目的。

我再给你画张图吧:
image

这样一来,用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。而业务系统根据消息队列中的请求信息,再做后续处理。

这种设计的优点是:能根据下游的处理能力自动调节流量,达到“削峰填谷”的作用

任务依赖

胖滚猪的公司有了高大上的数据中台,其中一个子系统叫做数据同步,只需要在前端页面勾选表,就可以自助化完成mysql到hive的同步。

但其中有个节点是工单审核。在同步系统中发起表同步申请,首先会调用工单系统,领导层在工单系统审核成功后,同步系统才可以完成接下来的同步任务。最开始,胖滚猪是这么设计的:

image

同步系统启了一个定时任务,每五分钟去查一下工单系统的接口,拿到审核结果。这种做法完全可行。

可是业务人员小甲不干了,小甲是个急性子,他觉得太慢了!提个需求:必须要准实时!即领导审核成功后你要马上给我同步!

这时候,胖滚猪又想到了消息队列,灵机一动,有了2.0优化版本:

image

这下,小甲这种急性子也不用不耐烦了,只要领导一批准,马上同步系统就会开始工作!

广播

胖滚猪加入产品中心的第一天,就给了它一个任务:产品中心需要频繁发布产品变更,而关心产品的系统多达10来个。每次变更,都要联调一次新接口,实在是太!麻!烦!了!

胖滚猪分析了一下,这就好像你妈喊你吃饭、还要喊你爸吃饭、喊你爷吃饭,她需要单独给你们每个人发微信通知,有点麻烦。可是如果她直接在家族群@你们,就把消息广播给大家了!

同理,产品系统相当于也要实现一个广播的功能,产品变动之后需要广播给其他系统。有了之前的经验,很快想到了可以用消息队列来实现。

在这里,消息队列就像我们的微信群一样,有了消息队列,我们只需要关心消息是否送达了队列,至于谁关心它谁希望去订阅,是下游的事情,无疑极大地减少了开发和联调的工作量。

数据采集

胖滚猪又接了个数据采集的活,1、需要实时收集日志、2、需要实时采集业务库binlog。

经过一番调研,胖滚猪明白了,采集binlog一般用到canal、采集日志一般可以用Flume和Logstash。

那么采集之后数据丢到哪儿呢?胖滚猪看了看官方架构图,咦,又有熟悉的消息队列,原来消息队列也可以用来数据采集呀!

image

image

所有主流的采集工具,都支持落地到Kafka等消息队列。也就是说,消息队列在数据采集这一块,也有举足轻重的作用。当然了,也不是必须要选择消息队列,要根据具体场景来选择。如果要对接流计算任务,或者多个系统都需要用到采集到的数据,那么选消息队列就没错了;如果只是想单纯存储起来,比如一些日志,那么可以不用消息队列。

连接流计算任务和数据

用消息队列(主要指Kafka)来连接流计算任务和数据,这在大数据领域是非常通用的一个架构了。火爆的流计算框架,Flink和Spark都优先选择Kafka作为数据源头并提供了完美的支持。

我们看一下oppo的架构图、简直了。三次用到Kafka!这地位无敌了!为啥oppo要三次用到Kafka呢?我相信根据上面的应用场景和优势你完全可以自行分析出来!

image

消息通讯

最后说一下消息通讯。。消息队列可以应用在消息通讯中,比如聊天室。

你可能会吐槽,你这不废话吗?凑数呢?我当然知道消息队列可用于消息通讯,小学生看名字都知道!

额,其实我只是想说明一下消息队列在消息通讯的两种场景罢了:点对点模型和发布订阅模型。

点对点通讯:系统 A 发送的消息只能被系统 B 接收,其他任何系统都不能读取 A 发送的消息。日常生活的例子比如电话客服就属于这种模型:同一个客户呼入电话只能被一位客服人员处理,第二个客服人员不能为该客户服务。
image

发布 / 订阅模型:与上面不同的是,它有一个主题(Topic)的概念,这个模型可能存在多个发布者向相同的主题发送消息,而订阅者也可能存在多个,它们都能接收到相同主题的消息。生活中的报纸订阅就是一种典型的发布 / 订阅模型。
image

劲酒虽好,可不要贪杯哦

消息队列确实有着非常广泛的应用,但它也有缺点!劲酒虽好,可不要贪杯哦,贪杯会出问题的哦!

  • 消息队列会带来一定的延迟问题;
  • 降低了数据的一致性;如果要保证强一致性则需要高代价的补偿,如分布式事务、对账。
  • 有数据丢失的风险;比如宕机重启,如果要保证高可用需要额外的机制如双活容灾。

因此:

  • 不适合要求实时响应的系统、
  • 不适合要求数据强一致性的系统(比如直接和钱有关系的系统 银行转账 第三方支付)、
  • 不适合不能容忍数据丢失的系统

本文来源于公众号:胖滚猪学编程。用漫画形式让编程so easy and interesting!欢迎关注

相关文章
|
7月前
|
机器学习/深度学习 SQL 分布式计算
Spark核心原理与应用场景解析:面试经验与必备知识点解析
本文深入探讨Spark核心原理(RDD、DAG、内存计算、容错机制)和生态系统(Spark SQL、MLlib、Streaming),并分析其在大规模数据处理、机器学习及实时流处理中的应用。通过代码示例展示DataFrame操作,帮助读者准备面试,同时强调结合个人经验、行业趋势和技术发展以展现全面的技术实力。
573 0
|
7月前
|
前端开发 JavaScript Java
面试官:什么是防抖和节流?如何实现?应用场景?
面试官:什么是防抖和节流?如何实现?应用场景?
115 0
|
7月前
|
消息中间件 监控 大数据
Kafka消息队列架构与应用场景探讨:面试经验与必备知识点解析
【4月更文挑战第9天】本文详尽探讨了Kafka的消息队列架构,包括Broker、Producer、Consumer、Topic和Partition等核心概念,以及消息生产和消费流程。此外,还介绍了Kafka在微服务、实时数据处理、数据管道和数据仓库等场景的应用。针对面试,文章解析了Kafka与传统消息队列的区别、实际项目挑战及解决方案,并展望了Kafka的未来发展趋势。附带Java Producer和Consumer的代码示例,帮助读者巩固技术理解,为面试做好准备。
653 0
|
4月前
|
Java
【Java基础面试九】、说一说自动装箱、自动拆箱的应用场景
这篇文章介绍了Java中的自动装箱和自动拆箱概念:自动装箱允许将基本类型赋值给对应的包装类对象,而自动拆箱允许将包装类对象赋值给基本类型,从而简化了两者之间的转换过程。
【Java基础面试九】、说一说自动装箱、自动拆箱的应用场景
|
4月前
|
JavaScript
【Vue面试题十九】、Vue常用的修饰符有哪些有什么应用场景?
这篇文章详细介绍了Vue中的修饰符,包括表单修饰符、事件修饰符、鼠标按键修饰符、键值修饰符和`v-bind`修饰符,解释了它们各自的功能和应用场景,并通过代码示例展示了如何在实际开发中使用这些修饰符来简化事件处理和提高代码的可读性及效率。
【Vue面试题十九】、Vue常用的修饰符有哪些有什么应用场景?
|
5月前
|
监控 安全 Java
Java面试题:描述Java反射机制及其应用场景,并讨论其优缺点。
Java面试题:描述Java反射机制及其应用场景,并讨论其优缺点。
51 1
|
5月前
|
存储 设计模式 Java
Java面试题:解释代理模式的概念,并举例说明其应用场景。
Java面试题:解释代理模式的概念,并举例说明其应用场景。
64 0
|
5月前
|
设计模式 Java 数据库连接
Java面试题:简述工厂模式的种类及其应用场景,你能举个例子吗?
Java面试题:简述工厂模式的种类及其应用场景,你能举个例子吗?
35 0
|
5月前
|
监控 网络协议 Java
Java面试题:解释Java NIO与BIO的区别,以及NIO的优势和应用场景。如何在高并发应用中实现NIO?
Java面试题:解释Java NIO与BIO的区别,以及NIO的优势和应用场景。如何在高并发应用中实现NIO?
76 0
|
5月前
|
Java 数据库
Java面试题:请解释Java中的输入输出(I/O)流?详细说明应用场景
Java面试题:请解释Java中的输入输出(I/O)流?详细说明应用场景
35 0