architecture - 什么时候将事件推送到 ES 中的事件存储?
问题描述
我正在尝试一些新概念,事件溯源、微服务以及所有这些范式。
假设我们有以下结构,它代表了一个基本的事件驱动架构
UI -> API -> EVENTS BROKER ->> MICROSERVICES
我们从客户端(UI)向服务器(API)发出请求,执行一个引发事件的命令,该事件被发布到事件代理中,然后订阅该特定事件的每个服务都将启动一个过程,对吗?但是如果我还想实现事件溯源怎么办,它可能看起来是这样的吗?
UI -> API -> EVENTS BROKER ->> MICROSERVICES
-> EVENTS STORE
对于这个例子,假设我有一个聚合,Products
如果我将事件保存在事件存储中后,我的业务逻辑说它不应该被允许,因为我现在不认为我们只在特定日期接受新产品在本月,但现在我已经存储了该事件
问题本身是,在这种情况下,我应该什么时候将事件保存到 EVENT STORE 中?
解决方案
在事件溯源中,基本方法是只保存有效事件。因此,在处理命令以确定需要发出和保存哪些事件时,取决于您的 API。API 服务应该是唯一决定将哪些事件写入事件存储的东西(并且通常通过查询事件存储的进程将事件发布到事件代理是一个好主意:任何事件都不应该发布到未由 API 服务写入事件存储的代理)。
现在,如果后来决定不应该创建 20 日星期二创建的产品,则无法删除该事件:产品已创建是事实。但是你可以有一个新的事件,可能叫做类似ProductCreationRetracted
的,解释为:“哎呀,这个产品不应该被创造出来”。
一般来说,这将需要修改任何为Product
s 读取或写入事件的内容(除非,例如,通过某种标记,您可以确定它永远不会看到ProductCreationRetracted
事件。
还值得注意的是,在事件源 DDD 中,确保只有一个进程正在为给定的聚合根写入事件通常很重要(取决于用于从事件派生状态的特定代数,这个要求可能会被放宽:例如,如果代数定义了无冲突的复制数据类型(如果您不知道 CRDT 是什么,那么默认假设您不能放松单写器可能是合理的)。
推荐阅读
- mysql - 如何修复“1054 - 子句上的未知列”
- kotlin - 派生类属性未在 kotlin 中序列化
- angular - PrimeNG Angular2 组件有 DynamicDialogRef 和没有 DynamicDialogRef 的实现问题
- java - itextpdf 表格列数
- reactjs - 我的 onclick 函数与提交处理程序重叠
- vue.js - 在 Vue 项目之间共享资产和组件
- process - 操作系统中的PCB
- mysql - 如果在某些条件下 SQL 中没有值,则计数显示为零?
- python - 将存储在变量中的字典值添加到列表 python3
- go - 告诉我这段代码 GOLANG 有什么问题