1 网络结构和软件架构
大家知道互联网基于IEEE所提出的标准ISO七层模型运行,而在应用层也有经典的三层应用程序架构(表示层UI,业务逻辑层BLL,数据处理层DAL),在其中我们系统的核心是 data(base)。 有人将其表示为餐厅生产过程:
餐厅服务员 餐厅厨师 餐厅采购员
| | |
表示层UI 业务逻辑层BLL 数据层DAL
在 事件驱动(EDA)中,焦点转移到事件以及它们如何在系统中流动。相关业务事件通过事件风暴技术识别。事件单向流动,异步处理,消除超时风险,实现服务解耦。消息代理确保事件传递,而事件日志提供不可变记录。
这种转变使我们能够彻底改变设计应用程序的方式来解决上述问题。
在实际了解 EDA 如何做到这一点之前,让我们看看事件到底是什么。
事件是触发通知或应用程序状态的某种更改的操作。灯已打开(通知),恒温器已关闭加热系统(通知),用户更改其地址(状态更改)或您的某个朋友更改了他的电话号码(状态更改)。
所有这些都是事件,但这并不意味着我们应该将它们添加到事件驱动的解决方案中。
2 添加事件
要添加事件,该事件必须与业务相关。用户下新订单是该特定业务的相关事件,比如用户午餐吃牛肉吗。
当您考虑这些时,哪些事件与企业相关可能是显而易见的,但其中一些可能不是。
尤其是那些作为对其他事件的反应而发生的事件。要发现流经系统的事件,请使用称为事件风暴的技术。
将应用程序上的利益相关者(从软件工程师到业务人员和领域专家)聚集在一起,并将所有业务流程映射为特定事件。
映射所有业务流程后,工程团队可以将结果用作构建应用程序的要求。
在弄清楚了什么是事件以及如何识别它们之后,让我们来看看它们如何解决前面提到的常见问题。
事件以单一方向流动,从生产者到使用者。将此与 REST 调用进行比较。事件生成者从不期望使用者的响应,而在 REST 调用中,将始终存在响应。
没有响应,无需阻止代码执行,直到发生其他事情。这使得事件本质上是异步的,完全消除了运行超时的风险。
事件作为操作的结果发生,因此没有目标系统;我们不能真的说服务 A 会触发服务 B 的事件;我们可以说的是,服务 B 对服务 A 生成的事件感兴趣。但也可能有一些其他方感兴趣,例如服务 C 或 D。
那么,我们如何确保由一个系统触发的事件到达所有感兴趣的服务呢?大多数情况下,此问题由消息代理解决。
代理只不过是一个应用程序,它充当事件生成器(创建事件的应用程序)和事件使用者之间的中间人。
这样,应用程序就可以很好地解耦,从而解决我在文章前面谈到的可用性问题。
如果应用程序暂时不可用,当它重新联机时,它将开始使用事件并处理它们,赶上应用程序关闭时触发的所有事件。
3 存储事件
事件可以存储在数据库中还是会有其他东西?事件绝对可以存储在数据库中,但这样做会丢失其“事件”方面。
事件发生后,我们无法更改它,因此事件是不可变的。另一方面,数据库,它们是可变的,我们实际上可以在插入数据后更改数据。
存储事件的更好方法是使用事件日志。
- 事件日志
只不过是一个集中式数据存储,其中每个事件都存储为一系列不可变记录,也称为日志。
将日志想象成一个足迹记录,其中每个新事件都附加到列表的末尾。我们始终可以通过从开始到现在重播日志中的所有事件来重新创建最新状态。
我唯一没有介绍的是可扩展性。使用事件驱动思维方式构建的服务旨在部署在多实例方案中。
由于状态本身存储在事件日志中,因此服务本身将是无状态的,这允许对我们想要的任何特定服务进行外科手术扩展。
此模式的唯一例外是必须创建实例化视图的服务。
实质上,实例化视图表示事件日志的时间点中的状态。此方法用于更轻松地查询数据。
回到我们的可扩展性问题,物化视图只不过是以类似表格的格式聚合的事件,但是我们在哪里存储这些表?
大多数情况下,我们看到这些聚合在内存中执行,这会自动将我们的服务转换为有状态的服务。
一种快速简便的解决方案是向创建实例化视图的每个服务添加本地数据库。
这样,状态存储在数据库中,服务再次无状态。
4 事件驱动架构应用于web结构
尽管事件驱动架构已经存在了近20年,但它仍然需要获得了广泛的普及,这是有原因的。
大多数公司正在经历“初始转型”阶段后,随之而来的是疯狂的需求。
这些要求的复杂性迫使工程师采用新的软件设计方法,这些方法可以减少服务之间的耦合并降低维护开销。EDA是这些问题的一种解决方案,但它不是唯一的解决方案。
5 使用场景
Web 和移动后端的微服务通信
电子商务或媒体和娱乐网站通常必须纵向扩展以处理不可预测的流量。客户访问电子商务网站并下订单。
订单事件被发送到事件路由器。
所有下游微服务都可以获取订单事件进行处理。示例操作可能包括:提交订单、授权付款以及将订单详细信息发送给运输提供商。
由于每个微服务都可以独立扩展和失败,因此该流程可以在订单高峰期扩展而不会出现单点故障。
- 业务工作流程自动化
许多业务工作流程(例如金融服务交易)需要重复相同的步骤。您可以使用事件驱动型架构(EDA)来启动和自动化这些步骤。
例如,当客户向银行申请新账户时,银行必须进行一些数据检查(身份证明文件、地址等)。一些账户还需要人工批准阶段。您可以通过工作流服务编排所有这些步骤,该服务会在收到新账户申请时自动执行这些步骤。
您还可以添加一个工作流,通过机器学习异步处理客户应用程序数据以提取相关数据,这可能可以节省数小时的手动数据收集和验证时间。
- SaaS 应用程序集成
软件即服务(SaaS)环境面临的最大挑战是缺乏对用户活动和数据的可见性。为了解锁孤立的数据,事件驱动型架构可以摄取 SaaS 应用程序事件或将事件发送到他们的 SaaS 应用程序。例如,您可以构建中间件来获取传入的合作伙伴订单数据并将订单直接发送到内部订单处理应用程序。
- 基础设施和自动化
在运行计算密集型工作负载(例如财务分析、基因组研究或媒体转码)时,您可以通过扩展计算资源以进行高度并行处理,然后在作业完成后缩减计算资源。
特别地,在高度监管的行业中,拥有 EDA 的公司可以启动安全状态资源以响应事件,或者在安全策略发送警报事件时采取补救措施。
6 小结
您不应该期望通过采用 EDA 可以解决所有问题。
使用事件驱动可促进系统组件之间的松耦合,从而提高敏捷性。
微服务可以独立扩展,失败时不会影响其他服务,并且可以降低工作流的复杂性。
可以灵活地路由、缓冲和记录事件以用于审计目的。
基于推送的事件流可以实时运行,从而降低了与创建和运行代码相关的成本,该代码不断地轮询系统以进行更改。
某些功能可能仍需要良好的老式同步 REST API 或将数据存储在关系数据库中。检查哪些工具最适合您并适当地设计它才是最重要的。