系统架构中为什么要引入消息中间件?

“在本文的开头,我们将讨论消息中间件的高频访问问题,它也将涵盖MQ中间件的一些常见技术问题。如果面试官看了你的简历中使用MQ中间件的经历,可能会有以下问题:在你的公司的生产环境中使用了什么消息中间件?为什么要将消息中间件引入系统?引入消息中间件的优点和缺点是什么?好,让我们逐一分析。

一、你们公司生产环境用的是什么消息中间件?

首先,您可以说您的公司选择了哪种消息中间件,比如Rabbit MQ,然后可以对您选择的不同MQ中间件技术进行一些初步分析。例如:ActiveMQ是一个老式的新闻中间件。在中国,许多公司曾经广泛使用过它,并且拥有强大的功能。但问题在于,ActiveMQ不能支持Internet公司高并发性、高负载和高吞吐量的复杂场景,而且中国的Internet公司数量较少。此外,一些传统企业使用ActiveMQ进行异步调用和系统解耦。然后您可以说RabbitMQ,它具有支持高并发性、高吞吐量、高性能以及非常完美和方便的后台管理接口的优点。此外,他还支持集群、高可用性部署架构、高可靠消息支持和更好的功能。

此外,经过调查,大型RabbitMQ集群支持自身业务的案例更多,国内各种中小型互联网公司使用RabbitMQ的做法也更多。此外,RabbitMQ的开放源码社区非常活跃,通过频繁的迭代来修复发现的bug并对其进行优化,所以经过全面考虑,公司采用了RabbitMQ。但是RabbitMQ也有一些缺点,即它基于Erlang语言开发,因此更难分析内部源代码,更难对源代码进行深入定制和改造。毕竟,它需要更坚实的Erlang语言基础。然后我们可以讨论一下RocketMQ,它是Ali的开放源代码。它已经通过了Ali生产环境中高并发性和高吞吐量的测试。它还支持特殊的场景,如分布式事务。基于Java语言开发了RoCKMQ。它适合于源代码的深入阅读。有必要在源代码级别解决在线生产问题,包括二次开发和修改源代码。另一个是卡夫卡。Kafka的消息中间件特性明显小于上面提到的MQ中间件的特性。但是Kafka的优点是它被设计用于超高吞吐量的实时日志采集、实时数据同步、实时数据计算和其他场景。因此,卡夫卡被广泛应用于具有实时计算技术的大数据领域(如火花流、风暴、Fl.)。但它很少用于传统的MQ中间件使用场景。PS:如果您还没有在自己的计算机上部署上述MQ技术,并且没有编写一些HelloWorld经验,那么建议您首先到每种技术的官方网站上查找HelloWorld演示,并自己运行和播放。

二、为什么在你们系统架构中要引入消息中间件?

要回答这个问题,您应该首先讨论消息传递中间件的常见使用场景。
然后,根据您自己的系统的相应使用场景,我将讨论通过将消息中间件引入到您的系统中解决了哪些问题。

1)系统解耦

假设您有一个系统A,它产生核心数据,现在下游系统B和C需要该数据。

很简单。系统A只调用系统B和系统C的接口直接向它们发送数据。

整个过程,如下图所示。

但如果我们谈到系统D、系统E、系统F、系统G等等,那么其他十几个系统会慢慢需要这些核心数据吗?如下图所示。

别以为这是开玩笑。一个大型系统通常被划分为几十个甚至数百个子系统。每个子系统对应多个服务。这些系统和系统之间存在着复杂的关系。
如果系统产生核心数据,那么无数其他下游系统可能需要它来实现各种业务逻辑。
此时,如果您采用上述模式来设计系统体系结构,那么负责系统A的学生绝对会厌烦至死。
首先,有人来要求他向一个新系统H发送数据。系统A的学生必须修改代码,然后在代码中添加调用新系统H的过程。
稍后,旧的系统B将脱机,告诉系统A的学生:不要给我数据,然后系统A将再次修改代码,并停止给系统B。
那么,如果下游系统突然出现故障怎么办?系统A的调用代码中是否引发异常?系统A的学生收到警报说系统不正常,他不得不去注意哪个下游系统出故障了。

因此,在实际的系统架构设计中,如果都采用这种系统耦合方式,在某些情况下是绝对不合适的,并且系统耦合程度太严重。

而耦合不是核心链路的呼唤,而是一些非核心场景(如数据消耗)导致系统耦合,这将严重影响上下游系统开发和维护的效率。

因此,在上述系统架构中,MQ中间件可以实现系统解耦。

系统A将其核心数据之一发送给MQ,MQ的下游系统希望自己使用它,并且不需要就取消对数据的消耗,如下图所示。

2)异步调用

假设您有一个系统调用链接,系统A调用系统B,通常需要20ms;系统B调用系统C,通常需要200ms;系统C调用系统D,通常需要2秒,如下图所示。

现在最大的问题是用户的请求来得很慢,因为完成一个链接需要20ms+200ms+2000ms(2s)=2220ms,或者超过2秒。
但实际上,系统A在链路呼叫系统B和系统B呼叫系统C,这两个步骤加起来是220M。
由于引入了系统C调用系统D步骤,最终的链路执行时间超过2秒,这直接将链路调用性能降低了10倍,这是链路执行缓慢的罪魁祸首。
此时,我们可以考虑是否可以将系统D从链接中拉出来进行异步调用。事实上,许多业务场景都允许异步调用。
例如,当您订购外卖时,单击订单并支付,账户扣除钱,创建订单,并通知商家为您准备菜。
接下来,你需要骑车送餐吗?然后,寻找骑手的过程需要一个复杂的算法来实现调度,这非常耗时。
但事实上,在几十秒后完成骑手的调度是可以的,因为当你付钱的时候,它并不真的需要找到一个好的骑手,也不是必须的。
因此,我们能否采取步骤找到一个骑手送餐给您脱离链接,并使其异步,即使它被延迟了数十秒,但只要我们找到一个骑手送餐给您在一定的时间范围?
这是否允许您更快地在外卖点下订单?一旦付款成功,可以创建订单,扣除帐户,并通知商家立即为您准备菜肴。这个过程可能需要数百毫秒。
然后,后台异步可能需要几十秒才能找到骑手通过调度算法递送餐点,但是这个步骤不会快速影响我们的订购。
当然,我们不是说那些熟悉的外卖平台的技术框架必须以这种方式实现,而是使用生活中的一个常见示例来说明它。

所以上面的链接是一样的。如果业务流程支持异步,我们能否考虑将系统C对系统D的调用撤出以进行异步,而不是依次在链接中对调用进行同步?
以这种方式,实现的思想是系统A->系统B->系统C,它直接消耗220ms并获得成功。
然后,系统C向MQ中间件发送消息,MQ中间件被系统D使用,并缓慢异步以执行消耗2s的业务流程。这样,核心链路的性能直接提高了10倍。

整个过程,如下图所示。

3)流量削峰

假设你有一个系统,平时正常的时候每秒可能就几百个请求,系统部署在8核16G的机器的上,正常处理都是ok的,每秒几百请求是可以轻松抗住的。

但是如下图所示,在高峰期一下子来了每秒钟几千请求,瞬时出现了流量高峰,此时你的选择是要搞10台机器,抗住每秒几千请求的瞬时高峰吗?

如果瞬时峰值每天只有半小时,那么它直接减少到每秒数百个请求。如果在线部署许多机器,那么每台机器每秒可以处理几十个请求。那不是浪费机器资源吗?
大多数情况下,每秒数百个请求,一台机器就足够了,但是为了抵御每天的瞬时峰值,部署了10台机器,每天使用半小时,并且在其他时间浪费资源。

但是,如果部署一台机器,它会导致一个瞬间的高峰时间,这会淹没您的系统,因为绝对没有办法每秒承受数千个请求。
此时,我们可以使用MQ中间件来降低流量峰值。所有机器前面都装有一层MQ。通常每秒可以容易地接收数百个请求。
一旦达到瞬时峰值,每秒可以备份数千个请求,然后机器缓慢地处理和消耗。
当高峰期结束并且消耗持续时间稍长时,将消耗MQ中的积压数据。

这是MQ的典型应用,它使用有限的机器资源承载高并发请求。如果业务场景允许异步调峰,则高峰期在MQ中积压一些请求,然后高峰期结束,并且后端系统在一定时间段之后不再积压,那么使用这种技术方案是非常合适的。

猜你喜欢

转载自blog.csdn.net/sd09044901guic/article/details/84985837