Architecture 事件何时推送到ES中的事件存储?

Architecture 事件何时推送到ES中的事件存储?,architecture,domain-driven-design,event-sourcing,event-driven,Architecture,Domain Driven Design,Event Sourcing,Event Driven,我正在为自己研究一些新概念,事件源、微服务以及所有这些范例 最后,我们有以下结构,它代表了一个基本的事件驱动体系结构 UI -> API -> EVENTS BROKER ->> MICROSERVICES 我们从客户端(UI)向服务器(API)发出请求,执行一个命令,抛出一个事件,该事件发布到事件代理中,然后订阅该特定事件的每个服务将启动一个进程,对吗? 但是,如果我还想实施事件源,可能看起来是这样的,对吗 UI -> API -> EVENTS BROK

我正在为自己研究一些新概念,事件源、微服务以及所有这些范例

最后,我们有以下结构,它代表了一个基本的事件驱动体系结构

UI -> API -> EVENTS BROKER ->> MICROSERVICES
我们从客户端(UI)向服务器(API)发出请求,执行一个命令,抛出一个事件,该事件发布到事件代理中,然后订阅该特定事件的每个服务将启动一个进程,对吗? 但是,如果我还想实施事件源,可能看起来是这样的,对吗

UI -> API -> EVENTS BROKER ->> MICROSERVICES
          -> EVENTS STORE
在这个例子中,假设我有一个名为
Products
的聚合,如果我在事件存储中保存事件后,我的业务逻辑说不应该允许这样做,因为我现在不知道,也许我们只在一个月的特定日期接受新产品,但现在我已经存储了事件


问题本身是,在这种情况下,我应该何时将事件保存到事件存储中?

在事件源中,基本方法是只保存有效的事件。因此,在处理命令以确定需要发出和保存哪些事件时,这取决于API。API服务应该是唯一决定将哪些事件写入事件存储的东西(而且通常最好通过查询事件存储的流程将事件发布到事件代理:不应将API服务未写入事件存储的事件发布到代理)

现在,如果后来决定不应该创建在20日星期二创建的产品,则不能删除该事件:事实上,该产品是创建的。但是你可以有一个新的事件,可能叫做
ProductCreationRetracted
,解释为:“哎呀,这个产品不应该被创建”

通常,这需要修改为
产品
读取或写入事件的任何内容(除非,例如,通过某种标记,您可以确保它永远不会看到
ProductCreationRetracted
事件)

还值得注意的是,在事件源DDD中,确保只有一个进程为给定的聚合根写入事件通常非常重要(取决于用于从事件派生状态的特定代数,这一要求可能会放宽:例如,如果代数定义了无冲突的复制数据类型,那么(如果您不知道CRDT是什么,那么默认假设您不能松开单个编写器可能是合理的)

如果我还想实现事件源,可能看起来是这样的,对吗

UI -> API -> EVENTS BROKER ->> MICROSERVICES
          -> EVENTS STORE
通常不会?看起来更像这样:

UI -> API -> EVENTS STORE ->> EVENTS BROKER ->> MICROSERVICES
也就是说,我们通常在发布数据模型之前将更改持久化,而当我们切换到事件源时,顺序不会改变


毕竟,事件源“只是”使用仅附加的事件序列作为我们的数据模型,而不是文档存储中的文档或关系数据库中的行。因此保存发生在同一位置是正常的(“事务边界”与数据模型无关).

需要记住的一件重要事情是,您需要将事件源事件驱动架构分开。这两种架构不同

来自UI的命令被发送到一个特定的服务,该服务可以在内部使用CQRS/事件源来保存自己的记录(实现细节)。然后它可以选择将事件发布到其他服务。UI不向系统发送事件,只发送命令

您在一个限定的上下文中使用事件源,并且在服务之间使用不同的事件(以避免耦合)。如下图所示:

内部事件与外部事件(服务之间)不同