事件驱动的架构如何解决现代 Web 应用问题

自从我们过去使用服务器静态 HTML 内容以来,基于 Web 的应用程序已经取得了长足的帮助。如今,应用程序要复杂得多,并且使用多个框架、数据中心和技术。在过去几年中,我们看到两个概念主导着 IT 市场:

  • 将我们的应用程序移动到;

  • 实施微服务架构;

这些想法塑造了我们设计和构建软件的方式。从某种意义上说,我们不再建造应用程序:相反,我们正在建设平台。应用不再共享相同的计算空间。相反,他们必须通过轻量级通信协议(如 REST API 或 RPC 呼叫)相互通信。这种模式使得创建一些惊人的软件,如Facebook,Netflix,优步,和许多其他成为可能。

本文将讨论推动现代网络发展创新的一些问题。然后,我们将深入探讨事件驱动型架构 (EDA) 的基本知识,该架构试图通过以新颖的方式思考后端架构来解决这些问题。

现代网络面临的问题

每种技术必须应对当今始终在多用户、异步应用中面临的挑战:

可用性

而不是一个应用程序,我们现在有很多,几十个,甚至数百个链接的服务,其中每一个必须准备做它的工作24/7。我们怎样才能做到这一点?通常,该服务被水平扩展到多个实例,有时跨多个数据中心,使其高度可用。进入此特定服务的所有请求将在所有实例中均匀路由。某些部署工具提供自我修复功能,因此,如果一个实例出现,它将创建另一个实例来取代它的位置。

可扩展性

可扩展性与可用性有很多共同之处。可用性就是确保至少有一个服务启动并运行,随时准备为传入请求服务。另一方面,可扩展性侧重于性能。如果一个应用程序超载,则我们可以创建该应用程序的新实例,以适应请求数量的增加。但是,扩大应用程序不是没有挑战的,特别是如果我们处理有状态的应用程序

单一的真理来源

在微服务之前,这项工作很简单。所有数据都位于一个地方,通常是某种关系数据库。但是,当多个服务共享数据库时,您可能会产生问题,如团队之间对模式更改或性能问题的依赖关系。解决这个问题的一个常见模式是使用每个服务的数据库。分布式的真相来源确实有助于维护干净的架构,但我们现在必须处理分布式交易和维护多个数据库的复杂性。

同步

在典型的请求响应场景中,客户端等待服务器响应:它阻止其所有活动,直到它收到响应或超时过期。如果我们采取这种行为,并把它放在一个微型服务架构使用链式呼叫整个系统,我们可以很容易地结束我所谓的"微服务地狱"。一切都从一个服务电话开始,让我们称之为服务A。但是,服务 A 需要调用服务 B,并且乐趣还在继续。这种行为的问题在于,如果服务的资源被阻止(例如:一个线程被挂起),超时现在呈指数级。如果我们允许每个服务500毫秒超时,并且链中有5个服务呼叫,那么第一个服务将需要有一个2500毫秒(2.5秒)的超时,而最后一项服务将需要有一个500毫秒的超时。

 

 

 

 

 

 

 

现代网络挑战

引入事件驱动的架构

事件驱动型架构(EDA)是一种软件架构范式,促进事件的生产、检测、消费和反应。

-维基百科

在经典的三层应用中,我们系统的核心是数据(基础)。在 EDA 中,重点将转移到事件及其如何通过系统流动上。这种转变使我们能够彻底改变我们设计应用程序的方式,以解决上述问题。

在实际查看 EDA 是如何这样做的之前,让我们看看事件到底是什么。事件是触发通知或应用程序状态某种更改的操作。灯已打开(通知),恒温器关闭加热系统(通知),用户更改其地址(状态更改),或您的一个朋友更改他的电话号码(状态更改)。所有这些都是事件,但这并不意味着我们应该将其添加到事件驱动的解决方案中。要添加事件,必须与业务相关。用户下新订单是特定业务的相关事件,但他/她午餐吃披萨不是。

当你想到这些事件时,哪些事件可能与企业有关,但其中一些事件可能并不明显。尤其是那些作为对其他事件的反应而发生的事件。要发现流经系统的事件,请使用一种称为事件风暴的技术。将应用程序(从软件工程师到商务人士和领域专家)上的利益相关者聚集在一起,并将所有业务流程映射为特定事件。在绘制完所有业务流程后,工程团队可以将结果用作构建应用的要求。

 

使用事件风暴完成的预订应用程序示例

在了解了什么是事件以及如何识别它们后,让我们来看看它们如何解决前面提到的常见问题。

事件从生产者到消费者,都朝着单一方向流动。将此与 REST 呼叫进行比较。活动制作人从不期望消费者做出回应,而在 REST 呼叫中总会有响应。没有响应,无需阻止代码执行,直到发生其他事情。这使得事件自然异步,完全消除了超时运行的风险。

事件发生是由于行动造成的,因此没有目标系统:我们真的不能说服务A触发事件服务B:我们可以说的是服务B对服务A产生的事件感兴趣。但可能还有其他一些感兴趣的当事方,如服务 C 或 D。

那么,我们如何确保由一个系统触发的事件到达所有感兴趣的服务?大多数时候,这个问题是由消息经纪人解决的。经纪人只不过是在事件发生器(创建事件的应用程序)和事件消费者之间充当中间人的应用程序。这样,应用程序很好地脱钩,以照顾我在帖子前面谈到的可用性问题。如果应用程序暂时不可用,当它重新联机时,它将开始消耗事件并处理它们,赶上应用程序关闭时触发的所有事件。

存储呢?事件是否可以存储在数据库中,或者是否有其他内容到位?事件肯定可以存储在数据库中,但通过这样做,它们将失去其"事件"方面。事件发生后,我们无法更改它,因此事件是不可改变的。另一方面数据库。。。它们是可变的,我们实际上可以在数据入后更改数据。

存储事件的更好方法是使用事件日志。事件日志只不过是一个集中的数据存储,每个事件都作为一系列不可变记录(也称为日志)存储。将日志想象成日志,其中每个新事件都附在列表的末尾。我们始终可以通过从开始到当前重播所有事件来重现最新状态。

我唯一没有覆盖的是可扩展性。使用事件驱动的心态构建的服务设计用于多实例场景。由于状态本身存储在事件日志中,服务本身将是无状态的,这允许手术缩放任何特定的服务,我们希望。

这种模式的唯一例外是必须创建具体视图的服务。从本质上讲,物化视图表示事件日志时间点中的状态。此方法用于更轻松地查询数据。回到我们的可扩展性问题,实现视图只不过是以表的形式聚合的事件,但我们将这些表存储在哪里?大多数情况下,我们看到这些聚合在内存中执行,它会自动将我们的服务转换为状态服务。一个快速和简单的解决方案是向创建实现视图的每个服务添加一个本地数据库。这样,状态存储在数据库中,服务再次处于无状态状态。

 

 

事件驱动的架构对现代网络的回答

虽然事件驱动型架构已经存在了超过 15 年,但直到最近它才获得巨大的受欢迎程度,这是有原因的。大多数公司正在经历一个"转型"阶段,并随之出现疯狂的要求。这些要求的复杂性迫使工程师采用新的软件设计方法,这些软件在服务之间的耦合较少,维护费用较低。EDA 是解决这些问题的一个解决方案,但它不是唯一的解决方案。此外,您不应期望通过采用 EDA 可以解决所有问题。某些功能可能仍然需要良好的老式同步 REST API 或将数据存储在关系数据库中。检查什么最适合你,并适当地设计它!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值