热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

面试精讲之面试考点及大厂真题分布式专栏13项目中为什么要使用消息队列

13项目中为什么要使用消息队列学习从来无捷径,循序渐进登高峰。——高永祚引言上个章节把Redis夺命连环问掰扯完,面试还没有结束,消息

13项目中为什么要使用消息队列

 

 

学习从来无捷径,循序渐进登高峰。

—— 高永祚

 


引言

上个章节把Redis夺命连环问掰扯完,面试还没有结束,消息队列同样是面试中必问的,分布式构建三把斧:缓存+异步+数据分组,从这节开始进入异步解决方案-消息队列

生活中的队列:超市买菜排队付款,出去玩排队上飞机。
图片描述

(图片来源:https://medium.com/)

 

计算机系统中的队列:

凡是可以“排队”去做的事情,都可以使用消息队列。网上买东西同样也需要“排队付款”,但是有人说,我点确认付款后马上就显示成功了,没感觉到排队呀?其实在后台系统中是排了,只不过排队的时间对于人来说有点短,可能1-2秒就结束了,但是对于计算机来说,这1-2秒的时间很长了。大型分布式系统建设中,消息队列主要解决应用耦合、异步消息、流量削锋等问题。实现高性能、高可用、可伸缩和最终一致性架构。是大型分布式系统不可缺少的中间件。消息发布者只管把消息发布到 MQ 中而不用管谁来取,消息使用者只管从 MQ 中取消息而不管是谁发布的。这样发布者和使用者都不用知道对方的存在。

Web应用程序毫无疑问有大量的代码执行HTTP请求/响应周期的一部分。这适用于更快的任务耗费数百毫秒内或更少。然而,有些处理,还需要耗时更多甚至最终会是一两秒钟缓慢的同步执行,在如此长时间的调用流转中,肯定有一些调用是可以不同步的,如下单送积分,用户下单是最主要的,送积分的操作可以异步去做,订单支付成功给用户的短信通知,返回支付订单进入下一环节更重好,短信通知可以异步去发送,为了应对诸如此类的异步操作,消息队列这门技术应运而生。
图片描述


 


1.面试官:你在项目中使用过消息队列吗?公司使用什么消息框架。

我:


我了解的常用消息队列中间件框架


  1. ActiveMQ:由 Apache 出品的一款开源消息中间件。
  2. RabbitMQ:Rabbit科技有限公司开发,使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。
  3. RocketMQ:阿里巴巴自主开发,是淘宝内部的交易系统使用了淘宝自主研发的Notify消息中间件,使用MySQL作为消息存储媒介,可完全水平扩容。
  4. Kafka:最初是由领英开发,并随后于2011年初开源,并于2012年10月23日由Apache Incubator孵化出站。

这其中Kafka天生就是分布式设计队列的消息理论上可以分摊到无数服务节点上。同等硬件环境下 Kafka 的性能大大超过传统的 ActiveMQ、RabbitMQ等MQ实现,这是 Kafka 炙手可热的重要原因,我们使用的就是Kafka搭建的集群。

Tip:这只是一个开始,面试官可能顺着你的话题开始聊Kafka了,Kafka的特性我在后面单独讲一节,继续展开讲消息队列基础知识。


 


2.面试官:哪些业务场景使用了消息队列?

问题分析:
在我刚刚工作接触编程的时候,做的项目都是单机部署,一套框架走天下,根本没有机会使用到消息中间件,真正参与大型互联网公司的分布式系统后豁然开朗,原来系统之间通讯是这么轻松愉快。所以如果要拿到大厂offer,至少要了解一个消息框架。

我:

“一百字的定义,不如一句话的实例”

我在公司的核心部分负责的是订单核心系统(具体什么订单系统自行yy一个)。
图片描述

这是一个完整的外卖订单流程。

从普通用户的角度来看,一个外卖订单从下单后,会经历支付、商家接单、配送、用户收货、售后及订单完成多个阶段。

以技术的视角来分解的话,每个阶段依赖于多个子服务来共同完成,比如下单会依赖于购物车、订单预览、确认订单服务,这些子服务又会依赖于底层基础系统来完成其功能,总之就是一个订单从提单到完成,要经历一个非常庞杂的流程。

一个服务所需要处理的工作越少,其性能自然越高。可以通过将部分操作异步化来减少需要同步进行的操作,进而提升服务的性能。异步化有两种方案。


  1. 使用消息队列:异步操作通过接收消息完成。
  2. 使用多线程:将异步操作放在单独线程中处理,避免阻塞服务线程。

比如,日志收集,采集日志是系统中经常被需要的功能,业务系统(如订单系统)流量高,数量极大,响应时间要求高,如果想收集订单日志,收集日志的动作必然不可以影响订单主流程,采集日志过程就可以使用消息队列模型设计。
图片描述

再比如,收银系统,确认收款成功,通过MQ通知给物流系统发货,这些独立系统之间的通讯都需要使用MQ。

再比如,消费积分,用户每消费一笔给用户增加一定积分,京东豆,信用卡积分,在一个正规大厂的架构设计中,可以100%的确定订单系统和积分/奖励系统是耦合在一起的,那怎么通知积分系统给用户加积分?这个时候MQ就登场了。

面试官打断了我…


 


3.面试官:那为什么不能使用线程池开启多线程呢,可同样达到异步的效果?

问题分析: 千万不能被面试官所迷惑,他是想要你给出使用消息队列有什么好处。

我:

这个就要从使用消息队列有什么好处说起了,我总结了以下几点:


使用消息队列有什么好处:


  1. 异步处理模式

    比如上面说的日志收集功能,订单系统是消息发送者,一行代码发送一条日志消息而无须如何等待。消息发送者将消息发送到一条虚拟的通道(主题 或 队列)上,日志存储服务作为消息接收者监听该通道,这样做的好处就是收集日志不会阻碍主流程,日志积压在消息队列里,日志服务可以慢慢消化,也无需很高的性能。

    至于为什么不使用多线程来做,这就是我要说的第2点。

  2. 应用系统解耦

    订单服务和日志存储服务显然是两个服务,微服务时代,根据单一职责原则,订单系统只负责订单相关的工作,日志收集服务只负责收集日志,如果把这两件事通过线程池揉在一起,系统见界限就不明显了,做不到完全解耦。

  3. 流量削峰

    当在线api接口在应对高峰流量时,比如“秒杀”互动流量激增时,如果日志服务接口处理能力有限,可以先将日志消息积压在队列里,后台慢慢处理,防止日志服务被打挂。

  4. 发布/订阅(Producer–consumer)

    一条消息,可以广播给任意个收听方,Producer只负责发送消息 Message,Consumer可随意订阅 Message。就像广播一样,是系统之间跨机房跨机器通讯的主要手段。

    场景:电商系统中,订单服务和支付服务往往是分开部署在不同机房,订单系统确认订单,给用户跳转到支付页面,支付成功后,支付系统广播一条 Message,用户xxx已经确认付款,订单订阅了此消息,将要订单状态改成已支付,物流系统收到支付成功消息开始发货,整个流程,系统之间可以通过MQ通讯。
    图片描述


面试官欣慰地笑了,似乎对我对回答很满意,我似乎也猜到他接下来要问什么了,关于“使用消息队列有什么缺点”,不如我一次痛快讲完。


我:

凡事都有两面性,不能考虑到消息队列的优点,分布式环境下,消息中间件的介入后会为系统提高复杂度,对应就会需要解决方案,使用消息中间件会带来什么问题呢?


 


使用消息队列有什么缺点:


  1. 消息丢失问题: 任何系统不能保证万无一失,比如 Producer 发出了10000条消息,Consumer 只收到了 9999 个消息,万有1失,Consumer 能否接受丢一条?如果是订单成功短信可以接受丢一条,就是有一个顾客没有通知到已经发货,但货还是发出去了,如果是支付系统,用户已经付款却因为消息丢失没有通知到订单或物流系统,那恐怕顾客要找你麻烦了。
  2. 消息重复问题:如 Producer 发出了10000条消息,Consumer 只收到了 10001 条消息,有一条是重复的,业务能否接受一条重复的消息,这个是作为系统设计者要考虑的问题。
  3. 消息的顺序问题:如 Producer 发送顺序是123,Consumer 收到的消息是132,要考虑消费端是否对顺序敏感。
  4. 一致性问题: 如消息丢失问题真的发生且无法找回,会造成两个系统的数据最终不一致,如果消息延迟,会造成短暂不一致。

面试官:小伙子你考虑地非常全面,关于消息队列的基础就问到这。(面试官彻底被我折服)。

Tip:

针对上面的问题都是消息中间件系统带来的常见困扰,是否需要解决完全依赖业务场景,如果问题对系统产生影响低可以接受,可以忽略,如何解决,每种消息中间件系统设计方案也有所不同,还需要考虑从业务上解决,如消息重复问题,如果 Consumer 不能接受重复消息,那 Consumer 的接口可以设计成“幂等”,这样就不怕重复消息给系统造成影响。


 


总结

本文主要针对消息队列的概念和使用做了讲解,消息队列同缓存一样,几乎是互联网系统建设中不可缺少的,面试也会被考察,通常会从以下几个方面进行考察:


  1. 你熟悉哪些消息中间件,各自有什么优缺点。
  2. 为什么使用消息中间件?
  3. 消息队列使用场景。
  4. 使用消息中间件有什么缺点,如何解决。

推荐阅读
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 云原生应用最佳开发实践之十二原则(12factor)
    目录简介一、基准代码二、依赖三、配置四、后端配置五、构建、发布、运行六、进程七、端口绑定八、并发九、易处理十、开发与线上环境等价十一、日志十二、进程管理当 ... [详细]
  • Java工程师书单(初级,中级,高级)
    简介怎样学习才能从一名Java初级程序员成长为一名合格的架构师,或者说一名合格的架构师应该有怎样的技术知识体系,这是不仅一个刚刚踏入职场的初级程序员也是工作一两年之后开始迷茫的程序 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 本文介绍了OkHttp3的基本使用和特性,包括支持HTTP/2、连接池、GZIP压缩、缓存等功能。同时还提到了OkHttp3的适用平台和源码阅读计划。文章还介绍了OkHttp3的请求/响应API的设计和使用方式,包括阻塞式的同步请求和带回调的异步请求。 ... [详细]
  • Unity3D引擎的体系结构和功能详解
    本文详细介绍了Unity3D引擎的体系结构和功能。Unity3D是一个屡获殊荣的工具,用于创建交互式3D应用程序。它由游戏引擎和编辑器组成,支持C#、Boo和JavaScript脚本编程。该引擎涵盖了声音、图形、物理和网络功能等主题。Unity编辑器具有多语言脚本编辑器和预制装配系统等特点。本文还介绍了Unity的许可证情况。Unity基本功能有限的免费,适用于PC、MAC和Web开发。其他平台或完整的功能集需要购买许可证。 ... [详细]
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
  • 本文总结了初学者在使用dubbo设计架构过程中遇到的问题,并提供了相应的解决方法。问题包括传输字节流限制、分布式事务、序列化、多点部署、zk端口冲突、服务失败请求3次机制以及启动时检查。通过解决这些问题,初学者能够更好地理解和应用dubbo设计架构。 ... [详细]
  • 像跟踪分布式服务调用那样跟踪Go函数调用链 | Gopher Daily (2020.12.07) ʕ◔ϖ◔ʔ
    每日一谚:“Acacheisjustamemoryleakyouhaven’tmetyet.”—Mr.RogersGo技术专栏“改善Go语⾔编程质量的50个有效实践” ... [详细]
  • [翻译]微服务设计模式5. 服务发现服务端服务发现
    服务之间需要互相调用,在单体架构中,服务之间的互相调用直接通过编程语言层面的方法调用就搞定了。在传统的分布式应用的部署中,服务地 ... [详细]
  • 浅析对象 VO、DTO、DO、PO 概念
    作者|CatQi链接|cnblogs.comqixuejiap4390086.html前言由于此订阅号换了个皮肤,导致用户接受文章不及时。读者可以打开订阅号「Web项 ... [详细]
  • 朱晔的互联网架构实践心得S1E7:三十种架构设计模式(上)【下载本文PDF进行阅读】设计模式是前人通过大量的实践总结出来的一些经验总结和最佳实践。在经过多年的软件开发实践之后,回过头 ... [详细]
author-avatar
minimiai_559
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有