事件溯源模式

概念解释

事件溯源(Event Sourcing)是一种设计模式,其核心思想是将系统的状态变化表示为一系列不可变的事件,并将这些事件存储在事件日志中。系统的当前状态可以通过重新应用(回放)这些事件来还原,从而实现状态的追溯。

传统方式

大多数应用程序会使用数据,而典型的方法是用户使用数据时通过立即更新数据使应用程序保持数据的当前状态。 例如,在传统的创建、读取、更新和删除 (CRUD) 模型中,典型的数据处理是从存储读取数据、对其作出修改、使用新值更新数据的当前状态。

CRUD 方法具有一些限制:

  • CRUD 系统直接对数据存储执行更新操作。 这些操作所需的处理工作开销可能会降低性能和响应能力,并会限制可扩展性。
  • 在包含多个并发用户的协作域中,由于会对数据单个项进行更新操作,因此出现数据更新冲突的可能性更大。
  • 除非有其他审核机制可以单独记录每个操作的详细信息,否则历史记录会丢失。

事件溯源模式优点

  • 事件不可变,并且可使用只追加操作进行存储。 用户界面、工作流或启动事件的进程可继续,处理事件的任务可在后台运行。
  •  事件不会直接更新数据存储。 只会对事件进行记录,以便在合适的时间进行处理。 使用事件可简化实现和管理
  • 事件溯源不需要直接更新数据存储中的对象,因而有助于防止并发更新造成冲突。 但是,域模型必须仍然设计为避免可能导致不一致状态的请求。
  • 事件的只追加存储提供的审核线索可用于监视对数据存储采取的操作。 它可以通过随时重播事件将当前状态重新生成为具体化视图或投影,并且可以帮助测试和调试系统,事件列表还可用于分析应用程序性能和检测用户行为趋势。

事件溯源模式缺点

  • 只有通过重播事件创建具体化视图或生成数据投影时,系统才可实现最终一致性。 应用程序将事件添加到事件存储作为处理请求的结果、发布事件和事件使用者处理事件之间存在一定程度的延迟。 在此期间,描述实体的进一步更改的新事件可能已到达事件存储。 系统设计应考虑到这些方案中实现最终一致性

问题和注意事项

事件存储是信息的永久源,因此请勿更新事件数据。 更新实体以撤销更改的唯一方式是将补偿事件添加到事件存储。 如果持久化事件的格式(而不是数据)需要更改,也许在迁移期间,很难将存储中的现有事件和新版本结合。 可能需要循环访问所有事件进行更改,使其符合新格式,或添加使用新格式的新事件。 考虑在事件架构的每个版本上使用版本标记,以同时保留事件的旧格式和新格式。

多线程应用程序和应用程序的多个实例可能将事件存储在事件存储中。 事件存储中的事件一致性至关重要,影响特定实体的事件的顺序(实体更改发生的顺序会影响当前状态)同样至关重要。 将时间戳添加到每个事件有助于避免出现问题。 另一常见做法是使用增量标识符注释请求引起的每个事件。 如果两个操作尝试同时为同一实体添加事件,则事件存储可拒绝与现有实体标识符和事件标识符相匹配的事件。

读取事件以获取信息并没有标准方法或现有机制,例如 SQL 查询。 可提取的唯一数据是将事件标识符用作条件的事件流。 事件 ID 通常会映射到各个实体。 仅可根据实体原始状态通过重播与其关联的所有事件来确定实体的当前状态。

每个事件流的长度会影响管理和更新系统。 如果是大型流,请考虑按特定间隔(例如指定数量的事件)创建快照。 可通过快照和重播此时间点后发生的事件获取实体的当前状态。

即使事件溯源会最大程度降低数据更新冲突的可能性,应用程序仍必须能够处理由最终一致性和缺少事务引起的不一致性。 例如,在指示存货减少的事件到达数据存储时,客户可能正在对该商品下订单。 这种情况导致需要在这两个操作之间作出协调,即通知客户或创建延期交付订单。

事件发布可能是“至少一次”,因此事件使用者必须是幂等的。 如果事件处理次数大于 1,则使用者不得重新应用该事件中描述的更新。 使用者 cn 的多个实例维护并聚合实体的属性,例如已下订单总数。 下订单事件发生时,只有一个实例必须成功递增聚合。 尽管这个结果不是事件溯源的主要特点,但却是通常的实现决策。

事件在事件存储中持久化,事件存储充当数据当前状态的记录系统(权威数据源)。 事件存储通常会发布这些事件,订阅者可收到通知并在需要时对其进行处理。请注意,生成事件的应用程序代码应与订阅到事件的系统分离。

所选的事件存储需要支持由应用程序生成的事件负载。
请注意以下情况:处理一个事件会涉及创建一个或多个新事件,因为这可能会导致无限循环。

何时使用此模式

请在以下方案中使用此模式:

  • 要捕获数据中的意图、用途或原因。 例如,可将对客户实体的更改捕获为一系列特定事件类型,例如“已搬家”、“帐户已关闭”或“已身故”。

  • 尽量减少或完全避免出现数据更新冲突。

  • 需要记录发生的事件,并重播事件以还原系统状态、回滚更改或保留历史记录和审核日志。 例如,任务涉及多个步骤时,可能需要执行操作来恢复更新,并重播某些步骤使数据重返一致的状态。

  • 使用事件时。 这是应用程序操作的自然功能,且几乎不需要其他开发或实现工作。

  • 需要将输入或更新数据的过程从应用这些操作所需的任务中分离。 此更改可能是为了提高 UI 的性能,或者是为了将事件分发给其他在事件发生时采取操作的侦听器。 例如,可以将工资管理系统与开支报销网站集成。 由事件存储引发的用于响应网站中数据更新的事件可同时供该网站和工资管理系统使用。

  • 希望随要求更改而灵活更改具体化模型和实体数据的格式,或需要调整读取模型或公开数据的视图(与 CQRS 结合使用时)。

  • 与 CQRS 结合使用且更新读取模型时最终一致性可接受或事件流中的解冻实体和数据的性能影响可接受。

此模式在以下情况中可能不起作用:

  • 小型域或简单域、几乎或完全没有业务逻辑的系统或者自然地适用于传统 CRUD 数据管理机制的非域系统。

  • 要求一致性和数据视图实时更新的系统。

  • 不需要审核线索、历史记录以及回滚和重播操作功能的系统。

  • 基础数据更新冲突发生率低的系统。 例如,主要是添加数据而不是更新数据的系统。

示例

会议管理系统需要跟踪会议的已完成预订数。 这种方式可以检查潜在与会者预订时是否有可用席位。 此系统可通过至少两种方式存储会议的预订总数:

  • 此系统可将预订总数信息作为单独的实体存储在包含预订信息的数据库中。 进行预订或取消预订时,此系统可相应地增加或减少此数量。 理论上而言,此方式很简单,但如果短时间内有大量与会者尝试预订席位,则可能导致可伸缩性问题。 例如,在预订期结束前的最后一天左右。

  • 此系统可将预订和取消预订信息存储为事件存储中的事件。 可通过重播这些事件来计算可用的席位数。 由于事件的不变性,此方式更具伸缩性。 此系统仅需要可从事件存储读取数据,或将数据追加到事件存储。 不会修改有关预订和取消预订的事件信息。

下图说明了如何使用事件溯源实施会议管理系统的席位预订子系统。

使用事件溯源捕获会议管理系统中有关席位预订的信息

预订两个席位的操作顺序如下:

  1. 用户界面发出为两位与会者预订席位的命令。 该命令由单独的命令处理程序处理。 一条逻辑,此逻辑从用户界面分离且负责处理发布为命令的请求。

  2. 通过查询描述预订和取消预订的事件,构造包含有关会议的所有预订的信息的一个聚合。 此聚合名为 SeatAvailability,且包含在公开此聚合中数据的查询和修改方法的域模型中。

    需要考虑的一些优化是使用快照(使获取聚合的当前状态无需查询和重播事件的完整列表)和将此聚合的缓存副本保留在内存中。

  3. 命令处理程序调用域模型公开的方法来进行预订。

  4. SeatAvailability 聚合会记录包含已预订席位数的事件。 聚合下次应用事件时,会使用所有的预订数来计算剩余的席位数。

  5. 此系统将新事件追加到事件存储中的事件列表。

如果某位用户取消席位,此系统将执行相似过程,但命令处理程序会发出生成席位取消事件并将其追加到事件存储的命令。

除了扩大可伸缩性范围外,使用事件存储还可提供会议预订和取消预订的完整历史记录或审核线索。 事件存储中的事件是准确的记录。 无需以其他任何方式持久化聚合,因为此系统可轻松重播事件并将状态还原到任意时间点。

结论

通常配合CQRS模式结合使用,适用于大型应用系统,带来便利的同时也需要考虑更多潜在且复杂的问题,如事件与实体之间的最终一致性、延迟等问题。一般小项目还是算了。不过是个很优秀的设计理念,有借鉴价值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/180136.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

webshell之扩展免杀

由于很多企业为了防止源码泄露,都会使用加密扩展将代码进行加密,那么我们就可以就将计就计,将webshell也利用扩展加密,将特征消除,从而达到免杀的效果 1.php-beast 扩展地址 下载dll,并添加至ext中 在php…

网络安全等级保护收费标准?

不同省份价格会略有不同,二级等保一般不低于5万元;三级等保不低于9万元,个别省份也可能7万也能办理,根据企业实际情况和省市选定的代理机构确定。 等级保护二级? 第二级等保是指信息系统受到破坏后,会对公民、法人和其他组织的合…

Airtest结合Poco对控件实施精准截图,学起来!

1.前言 最近在Q群内发现有个小伙伴提出了一个很有趣的脚本需求,想要实现“通过选择器获取到了控件,然后截图这个控件范围”,根据我们的Airtest的局部截图接口以及poco控件的属性查询接口是可以很快实现的~ 2.接口查找 首先我们需要知道我们…

PHP 正则式 全能匹配URL(UBB)

PHP 正则式 全能匹配URL(UBB) 语言:PHP 注明:正则式 无语言限制(js、PHP、JSP、ASP、VB、.net、C#...)一切皆可。 简介:PHP UBB 正则式 全能匹配URL 自动加超级链接。网上找了很多都不匹配或…

短视频矩阵系统源码搭建部署分享

一、 短视频矩阵系统源码搭建部署分享 目录 一、 短视频矩阵系统源码搭建部署分享 二、短视频矩阵系统搭建功能设计 三、 抖音矩阵号矩阵系统功能设计原则 四、 短视频矩阵开发部分源码展示 很高兴能够帮助您,以下是短视频矩阵系统源码搭建部署分享&#xff1a…

python命令行 引导用户填写可用的ip地址和端口号

字多不看,直接体验 待补充 演示代码 # -*- coding:UTF-8 -*- """ author: dyy contact: douyaoyuan126.com time: 2023/11/23 10:29 file: 引导用户填写可用的ip地址和端口号.py desc: xxxxxx """# region 引入必要的依赖 import …

2023亚太杯数学建模C题思路 - 我国新能源电动汽车的发展趋势

1 赛题 问题C 我国新能源电动汽车的发展趋势 新能源汽车是指以先进技术原理、新技术、新结构的非常规汽车燃料为动力来源( 非常规汽车燃料指汽油、柴油以外的燃料),将先进技术进行汽车动力控制和驱动相结 合的汽车。新能源汽车主要包括四种类型&#x…

网络安全等级保护2.0国家标准

等级保护2.0标准体系主要标准如下:1.网络安全等级保护条例2.计算机信息系统安全保护等级划分准则3.网络安全等级保护实施指南4.网络安全等级保护定级指南5.网络安全等级保护基本要求6.网络安全等级保护设计技术要求7.网络安全等级保护测评要求8.网络安全等级保护测评…

插入排序(形象类比)

最近在看riscv手册的时候,里面有一段代码是插入排序,但是单看代码的时候有点迷,没看懂咋操作的,后来又查资料复习了一下,最终才把代码看明白,所以写篇博客记录一下。 插入排序像打扑克牌 这是我听到过比较形…

运动戴什么耳机好?运动无线耳机哪个品牌比较好?运动耳机推荐

​如果你是一名户外运动爱好者,那么一款高品质的运动耳机是必不可少的。它们具备好音质、高稳固性舒适度、防尘防水等多项防护功能,让你在恶劣的天气条件下也能保持音乐的陪伴。面对市面上越来越多的运动耳机,到底哪款更值得入手?…

SS8837T-DF-TP-12V/1.8A直流有刷H桥驱动芯片

由工采网代理提供的SS8837T-H桥驱动芯片为摄像机、消费类产品、玩具和其它低电压或者电池供电的运动控制类应用提供了一个集成的电机驱动器解决方案 可广泛应用于:指纹锁、阀门控制、监控安抚、摄像机、数字单镜头反光 (DSLR) 镜头、消费类产品、玩具、机器人技术、…

CyberRT-共享内存实现

CyberRT共享内存类图 共享内存消息发布 数据用共享内存发布时,首先会创建ShmTransmitter对象,包含两个主要成员segment和notifier,Segment用于创建共享内存(上面绿色部分),Notifer 最终构建ReadableInfo通…

高通OTA升级方案介绍

高通OTA升级方案介绍 1. 高通LE OTA1.1 背景1.2 Recovery系统 2. SDX12 OTA方案3 OTA包的加密 3UK Penetration Test对于OTA升级也有严格的安全要求,下面是几条用例要求: Firmware: A sufficiently strong signing key MUST be in use. Signing keys MUS…

kubernetes 部署 spinnaker

spinnaker简介 Spinnaker 是一个开源、多云持续交付平台,它将强大而灵活的管道管理系统与主要云提供商的集成相结合。Spinnaker 提供应用程序管理和部署,帮助您快速、自信地发布软件变更。 Spinnaker 提供了两组核心的功能: 应用管理与应用程…

信息系统的安全保护等级的五个级别

信息系统的安全保护等级分为五级:第一级为自主保护级、第二级为指导保护级、第三级为监督保护级、第四级为强制保护级、第五级为专控保护级。 法律依据:《信息安全等级保护管理办法》第四条 信息系统的安全保护等级分为以下五级:   &#…

外贸自建站服务器怎么选?网站搭建的工具?

外贸自建站服务器用哪个好?如何选海洋建站的服务器? 外贸自建站是企业拓展海外市场的重要手段之一。而在这个过程中,选择一个适合的服务器对于网站的稳定运行和优化至关重要。海洋建站将为您介绍如何选择适合的外贸自建站服务器。 外贸自建…

SAP LU04记账更改通知单创建转储单报错:L3094 记帐修改没有份存在

解决办法: 使用事务码LU02,修改过账更改状态,将过账更改状态改为U,强制关闭 1. LU04 查找记账更改通知单号 2. 事务码LU02修改状态 这个时候再用LU04去查看的时候,就不会再显示了

一个ETL流程搞定数据脱敏

数据脱敏是什么? 数据脱敏是指在数据处理过程中,通过一系列的技术手段去除或者替换敏感信息,以保护个人隐私和敏感信息的安全的过程。数据脱敏通常在数据共享、数据分析和软件测试等场景下使用,它旨在降低数据泄露和滥用的风险。…

Sealos 云操作系统私有化部署教程

Sealos 私有云已经正式发布了,它为企业用云提供了一种革命性的新方案。Sealos 的核心优势在于,它允许企业在自己的机房中一键构建一个功能与 Sealos 公有云完全相同的私有云。这意味着企业可以在自己的控制和安全范围内,享受到公有云所提供的…

4.22每日一题(累次积分的计算:交换次序)

注:因为 是积不出的函数,所以先不用算,最后发现,出现dx与dy可以相互抵消,即可算出答案