阿里一面,说说你知道消息中间件的应用场景有哪些?

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介: 阿里一面,说说你知道消息中间件的应用场景有哪些?

1、前言



又到了金三银四的时候,大家都按耐不住内心的躁动,我在这里给大家分享下之前面试中遇到的一个知识点(MQ的应用场景),如有不足,欢迎大佬们指点指点。


消息中间件应用背景


提高系统性能首先考虑的是数据库的优化,但是数据库因为历史原因,横向扩展是一件非常复杂的工程,所有我们一般会尽量把流量都挡在数据库之前。不管是无限的横向扩展服务器,还是纵向阻隔到达数据库的流量,都是这个思路。阻隔直达数据库的流量,缓存组件和消息组件是两大杀器。


2、MQ简介



MQ:Message queue,消息队列,是指保存消息的一个容器。

现在常用的MQ组件有activeMQ、rabbitMQ、rocketMQ、kafka,虽然不同的MQ都有自己的特点和优势,但是,不管是哪种MQ,都有MQ本身自带的一些特点。


常用消息队列比较


image.png


3、MQ特点



先进先出


先进先出,是队列最明显的特点。消息队列的顺序在入队的时候就基本已经确定了,一般是不需人工干预的。而且,最重要的是,数据是只有一条数据在使用中。 这也是MQ在诸多场景被使用的原因。


发布订阅


发布订阅是一种很高效的处理方式,如果不发生阻塞,基本可以当做是同步操作。这种处理方式能非常有效的提升服务器利用率,这样的应用场景非常广泛。


持久化


持久化确保MQ的使用不只是一个部分场景的辅助工具,而是让MQ能像数据库一样存储核心的数据,保证MQ的可靠性。


分布式


在现在大流量、大数据的使用场景下,只支持单体应用的服务器软件基本是无法使用的,支持分布式的部署,才能被广泛使用。而且,MQ的定位就是一个高性能的中间件。


4、应用场景



消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋、海量日志数据同步、分布式事务等问题,实现高性能,高可用,可伸缩和最终一致性架构。


4.1 应用解耦


场景说明:在一般购物场景中,用户下单后,订单系统一般需要通知库存系统,在以前是通过接口调用进行通知。


image.png


通过接口调用的缺点:订单系统与库存系统耦合度高,容易出现雪崩事故,假如库存系统无法访问,则订单减库存将失败,从而导致订单失败,当调用量到一定程度后,会导致订单系统集群访问时间变长。


引入应用消息队列后的方案


image.png


订单系统:在用户下单后,订单系统完成本地持久化处理后将消息写入消息队列,写入成功后返回用户订单下单成功。


库存系统:订阅MQ中下单的消息,获取下单信息,库存系统根据下单信息,进行库存增或减操作。


该方案的关键步骤:


在下单时库存系统即使不能正常使用,也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了,只要达成最终一致性即可。实现订单系统与库存系统的应用解耦。


4.2 异步消息


场景说明:一般用户注册后,需要给用户发送注册邮件和短信。以前的步骤可分为:串行的方式、并行方式。


1.串行方式:将用户注册信息写入数据库,写入成功后先发送注册邮件,再发送注册短信。只有以上三个任务全部完成后,才返回给客户端成功信息。


image.png


2.并行方式:将用户注册信息写入数据库,写入成功后同时发送注册邮件和注册短信。以上三个任务完成后,才返回给客户端成功信息。相对于串行而言,并行的方式可以提高处理的时间。


image.png


问题分析:


假设三个业务节点每个使用50毫秒钟,不考虑网络等其他开销,则串行方式的时间是150毫秒,并行的时间可能是100毫秒。

因为CPU在单位时间内处理的请求数是一定的,假设CPU1秒内吞吐量是100次。则串行方式1秒内CPU可处理的请求量是7次(1000/150)。并行方式处理的请求量是10次(1000/100)

如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。


将发送注册邮件和注册短信的步骤通过消息队列解耦:


image.png


由以上架构可知,用户的响应时间相当于是注册信息写入数据库的时间,也就是50毫秒。注册邮件,发送短信写入消息队列后,直接返回,因此写入消息队列的速度很快,基本可以忽略,因此用户的响应时间可能是50毫秒。因此架构改变后,系统的吞吐量提高到每秒20 QPS。比串行提高了3倍,比并行提高了两倍。


4.3 流量削锋


流量削锋消息队列中也是普遍应用,一般在秒杀或团抢活动中使用广泛。


场景说明:秒杀活动,一般会因为流量过大,导致流量暴增,应用或者数据库挂掉。为解决这个问题,一般需要在应用前端加入消息队列。


架构如下:


image.png



加入消息队列的好处:


1.可以控制活动的人数

2.可以缓解短时间内高流量压垮应用


用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。

秒杀业务根据消息队列中的请求信息,再做后续处理。


4.4 海量日志数据同步


场景说明:在微服务体系下,项目往往是集群部署,那么就需要一个统一日志平台来查询各个实例的日志,但集群中的日志信息往往都是海量数据,单一的日志采集工具不能满足业务的需要,因此需要将消息队列用在日志处理中,比如Kafka的应用,解决大量日志传输的问题。


架构简化如下:


image.png


架构说明:


1.日志采集客户端,负责日志数据采集,定时写受写入Kafka队列

2.Kafka消息队列,负责日志数据的接收,存储和转发

3.日志处理应用:订阅并消费kafka队列中的日志数据


4.5 分布式事物


分布式事务又分为强一致,弱一致,和最终一致性


1.强一致


当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值。这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。根据 CAP 理论,这种实现需要牺牲可用性。


2.弱一致


系统并不保证续进程或者线程的访问都会返回最新的更新过的值。系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到。


3.最终一致


弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。DNS 是一个典型的最终一致性系统。


在分布式系统中,同时满足“CAP定律”中的一致性、可用性和分区容错性三者是几乎不可能的。在互联网领域的绝大多数的场景,都需要牺牲强一致性来换取系统的高可用性,系统往往只需要保证“最终一致性”,只要这个最终时间是在用户可以接受的范围内即可,这时候我们只需要用短暂的数据不一致就可以达到我们想要效果。


场景说明:比如有订单,库存两个数据,一个下单过程简化为,加一个订单,减一个库存。 而订单和库存是独立的服务,那怎么保证数据一致性。


远程调用最郁闷的地方就是,结果有3种,成功、失败和超时。 超时的话,成功失败都有可能。一般的解决方案,大多数的做法是借助mq来做最终一致。


实现最终一致


image.png


通过上面的架构可能会想到这些问题:


本地先执行事务,执行成功了就发个消息过去,消费端拿到消息执行自己的事务。

比如a,b两个服务,服务a异步调用服务b,如果服务b失败了,或者成功,或者超时,那么怎么用mq让他们最终一致呢?


参照于本地事务的概念可将该场景分为三种情况解决:


1.第一种情况:假设a,b都正常执行,那整个业务正常结束;

2.第二种情况:假设b超时,那么需要MQ给b重发消息(b服务要做幂等),如果出现重发失败的话,需要看情况,是中断服务,还是继续重发,甚至人为干预;

3.第三种情况:假设a,b之中的一个失败了,失败的服务利用MQ给其他的服务发送消息,其他的服务接收消息,查询本地事务记录日志,如果本地也失败,删除收到的消息(表示消息消费成功),如果本地成功的话,则需要调用补偿接口进行补偿(需要每个服务都提供业务补偿接口)。


需要特别注意


MQ这里有个坑,通常只适用于只允许第一个操作失败的场景,也就是第一个成功之后必须保证后面的操作在业务上没障碍,不然后面失败了前面不好回滚,只允许系统异常的失败,不允许业务上的失败,通常业务上失败一次后面基本上也不太可能成功了,要是因为网络或宕机引起的失败可以通过重试解决,如果业务异常,那就只能发消息给服务a让他们做补偿了吧?通常是通过第三方进行补偿,各个服务需要提供补偿接口,设计范式里通常不允许消费下游业务失败。


5、总结



MQ在分布式系统开发的场景下使用的越来越多,处理的业务能力也越来越强,所以掌握MQ的使用场景是很要必要的。通过掌握MQ,即可解决大多数业务场景,也可在面试中加分,提高自己的核心竞争力。


最后,外出打工不易,希望各位兄弟找到自己心仪的工作,虎年发发发!

也希望兄弟们能关注、点赞、收藏、评论支持一波,非常感谢大家!


目录
相关文章
|
3月前
|
安全 中间件 数据安全/隐私保护
中间件的定义,包括它的功能、应用场景以及优势。
中间件是位于操作系统和应用软件间的系统软件,提供数据交换、应用集成、流程管理和安全保障等服务。常用于分布式系统、微服务架构和企业级应用,实现高效、低耦合的系统运行。其优势在于降低开发成本、提升系统性能、简化扩展和维护。中间件推动了软件技术的发展和创新。
467 1
|
29天前
|
缓存 监控 安全
中间件在Python Web框架中的角色与应用场景
【7月更文挑战第21天】中间件在Python Web开发中作为服务器与应用间的软件层,拦截、处理请求和响应,无需改动应用代码。它扩展框架功能,复用跨应用逻辑,加强安全,优化性能。如Django中间件处理请求/响应,Flask通过WSGI中间件实现类似功能,两者均在不触及核心代码前提下,灵活增强应用行为,是现代Web开发关键组件。
26 0
|
2月前
|
缓存 监控 中间件
探究Django中间件的神奇:功能、应用场景和核心方法
在Django中,中间件是一个强大的概念,它们提供了一种灵活的方式来处理请求和响应。本文将探讨Django中间件的基本概念、常见应用场景以及中间件类中的父类和核心方法。
|
3月前
|
存储 缓存 中间件
中间件Cache-Aside策略特别适合“读多”的应用场景
【5月更文挑战第8天】中间件Cache-Aside策略特别适合“读多”的应用场景
23 2
|
消息中间件 运维 Java
rabbitMQ消息中间件的延时队列以及死信队列的使用和应用场景
rabbitMQ消息中间件的延时队列以及死信队列的使用和应用场景
|
3月前
|
消息中间件 存储 负载均衡
消息中间件的选择:RabbitMQ是一个明智的选择
消息中间件的选择:RabbitMQ是一个明智的选择
81 0
|
2月前
|
消息中间件 存储 中间件
【消息中间件】详解三大MQ:RabbitMQ、RocketMQ、Kafka
【消息中间件】详解三大MQ:RabbitMQ、RocketMQ、Kafka
149 0
|
1月前
|
消息中间件 编解码 Docker
Docker部署RabbitMQ消息中间件
【7月更文挑战第4天】Docker部署RabbitMQ消息中间件
161 3
|
1月前
|
消息中间件 监控 负载均衡
中间件RabbitMQ性能瓶颈
【7月更文挑战第13天】
87 11