EDA - 初探事件驱动

简介: EDA - 初探事件驱动


事件驱动架构概述


事件驱动架构(Event-Driven Architecture,简称EDA)是一种软件架构模式,它将系统中的各种组件之间的通信和协作建立在事件的概念之上。


在事件驱动架构中,系统中的各个部分可以产生、发布、捕获和响应事件,这些事件可以是状态变化、用户操作、消息等等。事件驱动架构的主要思想是通过事件来触发和协调不同组件的行为,使系统更加灵活、松耦合和可扩展。



事件驱动架构的关键特点


  1. 事件(Event):事件是系统中发生的有意义的事情,可以是内部的状态变化、外部输入、消息等。事件通常包含有关事件发生时间、类型和相关数据的信息。
  2. 发布者(Publisher):发布者是产生事件的组件或模块,它们将事件发布到事件总线或事件队列中,使其他组件可以订阅并处理这些事件。
  3. 订阅者(Subscriber):订阅者是希望接收和处理特定类型事件的组件或模块。它们订阅事件,以便在事件发生时执行相应的操作。
  4. 事件总线(Event Bus)或事件队列(Event Queue):事件总线是一种中介机制,用于管理事件的发布和订阅。它负责将事件从发布者传递给订阅者,并可以支持事件的路由和过滤。
  5. 异步处理:事件驱动架构通常使用异步处理来处理事件,这意味着系统中的各个组件可以并行执行,提高了系统的响应性和性能。
  6. 松耦合(Loose Coupling):事件驱动架构可以减少组件之间的直接依赖关系,因为组件不需要直接调用彼此的方法或接口。这使得系统更容易维护、扩展和修改。


事件驱动架构在许多领域中都有广泛的应用,包括分布式系统、微服务架构、消息队列系统、实时数据处理和大规模应用程序等。它可以帮助解决系统中的异步通信、实时数据处理、解耦合和可伸缩性等挑战,使系统更具弹性和可维护性。


认知误区


有不少软件项目都使用了消息队列,但是这里需要明确的是,对消息队列的使用并不意味着你的项目就一定是事件驱动架构,很多项目只是由于技术方面的驱动,小范围地采用了某些消息队列的产品而已。


在采用事件驱动架构时,我们需要考虑业务的建模、事件的设计、上下文的边界以及更多技术方面的因素,这个系统工程应该如何从头到尾的落地,是需要经过思考和推敲的。总而言之,“事件驱动架构”的设计并不是一件易事。


另外,如果盲目使用事件驱动设计架构,就有可能要承担中断业务逻辑的风险,因为这些业务逻辑具有概念上的高度内聚,却采用了解耦机制将它们联系在一起。


换句话说,就是将原本需要组织在一起的代码强行分离,并且这样难于定位处理流程,还有数据一致性保证等问题。为了防止我们的代码变成一堆复杂的逻辑,我们应当在某些明确场景下使用事件驱动架构。



事件驱动架构的四种模式


事件通知



优点

   架构更健壮。如果加入队列的事件能够在源组件中执行,但在其它组件中由于 bug 导致其无法执行(由于将其加入到队列任务中,它们可以在 bug 修复后再执行)。

   业务处理减少延迟。当用户无需等待所有的逻辑都执行完成时,可以将这类工作加入到事件队列。

   便于系统扩展,能够让组件的研发团队独立开发,加快项目进度、降低功能难度、减少问题发生并且更有组织性。

   将信息封装在“事件”里,便于系统内传播。


缺点

  • 如果没有合理使用,可能使我们的代码变成“面条式”代码。
  • 数据一致性问题。由于流程依赖于最终的一致性,因此通常不支持ACID事务,因此重复或乱序事件的处理会使服务代码更加复杂,并且难以测试和调试所有情况。


小结

“事件通知”的缺点和优点相对应,正是因为它提供了很好的解耦能力,我们会比较难通过阅读代码去得到整个系统和流程的全貌。因为这些逻辑之间的关系不再是之前的依赖关系。这将会是一个挑战。


事件承载状态转移


在使用事件通知时,事件里面往往不会包含下游系统处理这个事件需要的所有信息。比如当业务生成一个事件,但当下游系统处理这个事件时,往往还需要知道其他信息,才能完成后续处理。所以不可避免地,下游系统在处理这个事件时,往往还需要通过某平台服务来获取这些额外信息。


为了解决这个问题,我们引入一个种新的模式,叫做“事件承载状态转移”。简单来说,就是让事件的消费方自己保留一份在业务处理过程中需要用到的上游系统的数据。比如让下游系统保留一份在处理状态变更事件时所需要用到的变更前的状态,避免去平台查询。


优点

  • 架构更健壮。减少事件消费方对生产方的额外依赖(获取事件处理所需数据);
  • 业务处理减少延迟。增加事件消费方系统的响应速度,因为不再需要调用平台API以获取事件处理所需数据;
  • 无需担心被查询组件的负载(尤其是远程组件)。


缺点

  • 尽管现在数据存储已经不再是问题根源,依然会保存多个只读的数据副本,一致性进一步被破坏;
  • 增加数据处理的复杂度,即使处理逻辑符合规范,它也需要额外处理和维护外部数据的本地副本业务逻辑。


事件溯源


有些时候我们不但关心系统当前的状态,我们还关心如何变成当前这个状态的,但是数据库仅仅简单地保存实体的当前状态。事件溯源可以帮助我们解决这个问题。


事件溯源是一个特别的思路,它并不持久化实体对象,而是只把初始状态和每次变更的事件记录下来,并在内存中根据事件还原实体对象的最新状态,mysql主从备份用到的binary log以及redis的aof持久化机制,都可以认为是“事件溯源”的实现。


事件溯源在做完数据库更新之后,它将事件的发送操作转换为往数据库或者日志系统中写入一条事件记录,其它节点通过查询数据库或者文件系统,来得到这些事件,并通过回放来确保数据的最终一致性。



优点

  • 可以呈现一个完整的变动历史;
  • 提供更方便的debug手段;
  • 可以回溯到任何一个历史状态;
  • 方便修改当前事件;


缺点


   要实现一个可靠和高性能的事件仓库(保存的事件记录)并不是一件容易的事情,应用代码需要根据事件库的 API 进行重写。


CQRS (Command Query Responsibility Segregation)

https://learn.microsoft.com/en-us/azure/architecture/patterns/cqrs

https://martinfowler.com/bliki/CQRS.html


简单来说,就是针对系统的读写操作,使用不同的数据模型、API接口、安全机制等,来达到对读写操作的完全隔离,满足不同的业务需求


事件驱动架构的适用场景


以经验来讲,以下三 种场景可以使用事件驱动开发:



组件的解耦

当服务(或组件) A 需要执行服务 B 中的业务逻辑,相比于直接调用,我们可以向事件代理(事件分发器)中发送一个事件。服务 B 通过监听分发器中的特殊事件类型,然后当这类事件被接收到时去执行它。


这意味着服务 A 和服务 B 都依赖于事件代理和事件,而无需关注彼此实现:即完成它们的解耦



执行异步任务

有时我们会有一系列需要执行的业务逻辑,但是由于它们需要耗费相当长的执行时间,所以我们不想看到用户耗费时间去等待这些逻辑处理完成。在这种情况下,最好将它们作为异步任务来运行,并立即向用户返回一条信息,通知其稍后继续处理相关操作。



跟踪状态的变化


在传统的数据存储方式中,我们通过实体模型存数据。当这些实体模型中的数据发生变化时,我们只需更新数据库中的行记录来表示新的值。这里有个问题,就是业务上我们无法准确存储数据的变更和修改时间。但是在事件驱动架构中,可以通过事件溯源将包含修改的内容存入到事件里。


抽象模型设计


相关文章
element-plus:el-date-picker日期只选择年月不要日
element-plus:el-date-picker日期只选择年月不要日
1419 0
|
5月前
|
人工智能 负载均衡 Java
Spring AI Alibaba 发布企业级 MCP 分布式部署方案
本文介绍了Spring AI Alibaba MCP的开发与应用,旨在解决企业级AI Agent在分布式环境下的部署和动态更新问题。通过集成Nacos,Spring AI Alibaba实现了流量负载均衡及节点变更动态感知等功能。开发者可方便地将企业内部业务系统发布为MCP服务或开发自己的AI Agent。文章详细描述了如何通过代理应用接入存量业务系统,以及全新MCP服务的开发流程,并提供了完整的配置示例和源码链接。未来,Spring AI Alibaba计划结合Nacos3的mcp-registry与mcp-router能力,进一步优化Agent开发体验。
2173 15
|
9月前
|
存储 算法 C++
【C++数据结构——查找】二分查找(头歌实践教学平台习题)【合集】
二分查找的基本思想是:每次比较中间元素与目标元素的大小,如果中间元素等于目标元素,则查找成功;顺序表是线性表的一种存储方式,它用一组地址连续的存储单元依次存储线性表中的数据元素,使得逻辑上相邻的元素在物理存储位置上也相邻。第1次比较:查找范围R[0...10],比较元素R[5]:25。第1次比较:查找范围R[0...10],比较元素R[5]:25。第2次比较:查找范围R[0..4],比较元素R[2]:10。第3次比较:查找范围R[3...4],比较元素R[3]:15。,其中是顺序表中元素的个数。
336 68
【C++数据结构——查找】二分查找(头歌实践教学平台习题)【合集】
|
2月前
|
人工智能 监控 数据可视化
新媒体内容策划看板:高效内容生产的秘密武器
新媒体内容策划看板是可视化任务管理工具,用于规划选题、排期、执行及监控内容生产全流程,解决传统管理方式效率低、协作混乱等问题。核心模块包括选题库、内容日历、制作追踪和多平台分发跟踪,支持团队高效协作与数据反馈。主流工具如飞书、Notion、板栗看板各具优势,适配不同规模团队。通过集成数据指标(阅读量、转化率等)和AI辅助(智能排期、生成建议),看板可优化内容策略并形成闭环管理。未来,看板将与AI深度结合,推动内容生产智能化。
171 0
|
8月前
|
机器学习/深度学习 算法 PyTorch
从零开始深度学习:全连接层、损失函数与梯度下降的详尽指南
在深度学习的领域,全连接层、损失函数与梯度下降是三块重要的基石。如果你正在踏上深度学习的旅程,理解它们是迈向成功的第一步。这篇文章将从概念到代码、从基础到进阶,详细剖析这三个主题,帮助你从小白成长为能够解决实际问题的开发者。
|
7月前
|
机器学习/深度学习 存储 人工智能
SAFEARENA: 评估自主网络代理的安全性
基于大语言模型的智能体在解决基于网络的任务方面正变得越来越熟练。随着这一能力的增强,也随之带来了更大的被恶意利用的风险,例如在在线论坛上发布虚假信息,或在网站上销售非法物质。为了评估这些风险,我们提出了SAFEARENA,这是第一个专注于故意滥用网络代理的基准测试。SAFEARENA包含四个网站上共计500个任务,其中250个是安全的,250个是有害的。我们将有害任务分为五类:虚假信息、非法活动、骚扰、网络犯罪和社会偏见,旨在评估网络代理的真实滥用情况。我们对包括GPT-4o、Claude-3.5 Sonnet、Qwen-2-VL 72B和Llama-3.2 90B在内的领先基于大语言模型的网
322 11
SAFEARENA: 评估自主网络代理的安全性
|
12月前
|
存储 SQL 关系型数据库
MySQL存储引擎
本文介绍了数据库优化的多个方面,包括选择合适的存储引擎、字段定义原则、避免使用外键和触发器、大文件存储策略、表拆分及字段冗余处理等。强调了从业务层面进行优化的重要性,如通过活动设计减少外部接口调用,以及在高并发场景下的流量控制与预处理措施。文章还提供了具体的SQL优化技巧和表结构优化建议,旨在提高数据库性能和可维护性。
350 1
MySQL存储引擎
|
10月前
|
人工智能 算法 自动驾驶
新视角设计下一代时序基础模型,Salesforce推出Moirai-MoE
**Moirai-MoE:时间序列预测的新突破** Salesforce Research团队提出了Moirai-MoE模型,通过稀疏混合专家(MoE)技术,解决了传统时间序列预测方法中存在的频率不可靠和非平稳性问题。该模型在39个数据集上的实验结果表明,其性能优于现有基础模型,具有更高的创新性和泛化能力。论文地址:https://arxiv.org/abs/2410.10469
353 4
|
SQL 关系型数据库 MySQL
MySQL 事务回滚。在执行删除、更新等操作时,防止误操作
MySQL 事务回滚。在执行删除、更新等操作时,防止误操作
458 2