我为一家初创公司工作,我们希望通过事件源构建基本的概念证明。任何人都可以对这些基本问题进行澄清吗?
对可能的基本流程的疑问...听起来是否完整且有意义?
客户端-> eventStore API->存储事件->可能将消息发布到队列中->确认客户端的赞许->建立您的读取模型/索引吗? ->客户端公开发布事件->同一事件的其他使用者现在可以根据事件采取行动。
在“构建读取模型”部分上我还不太清楚...我想您可以在任何单独的数据存储中构建“投影”?或者只是为实际事件存储中的数据建立索引以便快速查询?
对这些问题的任何澄清都是很好的。
谢谢! -罗恩
答案 0 :(得分:2)
我将为您提供一些我已使用/看到过的基本事件采购术语。另外,我将在CQRS的上下文中使用事件源,尽管它可以单独使用(直到现在我才这样做)。
事件存储是事件的持久性(数据库)。应用程序的写/命令和读/查询端对事件存储有不同的要求。
写方需要由集合发出的事件必须按顺序 并受并发插入的保护。人们将其称为 Event流 =聚合实例(即Product#1234)发出的所有事件。读取时,事件流也应该很快,也就是说,按照事件的发出顺序(从最旧的开始)读取事件流中的所有事件,都应该非常快。在执行每个命令之前,这是聚合补液所必需的。
读取端希望所有事件在所有聚合中都按 total 的顺序排列。如果您满足此要求,则Readmodels的构建会更简单。但是,通过加大开发设计工作量,可以创建不需要总订单的Readmodel。
大型系统的问题是,通常,Readmodels需要来自多个事件存储的事件
事件源是事件流的集合吗?
如果“事件源”是“事件存储”,则为“是”。
每个边界上下文都有事件源吗?还是按DDD汇总(例如汽车及其变化)?
最简单的系统是具有单个事件存储实例的系统。这是因为Readmodels然后仅需要连接到一个实例,并且您可以拥有事件的总顺序。
如果系统太大,则不可能只有一个事件存储。这意味着您无法拥有事件的总顺序,这意味着Readmodels很难构造(并非不可能)并且操作成本增加。
因此,您必须进行权衡。一个不错的权衡是在每个有界上下文中都有一个事件存储。
每个事件源都有自己的数据存储吗?
在这个答案的背景下,这个问题没有意义。一个事件存储=一个数据存储。
将示例作为汽车的事件源,其中每个事件流都基于唯一的carId吗?
是的,每个汽车实例(具有唯一的ID)都有一个事件流。
客户端-> eventStore API->存储事件->可能将消息发布到队列中->确认客户端的赞许->建立您的读取模型/索引吗? ->客户端公开发布事件->同一事件的其他使用者现在可以根据事件采取行动。
这取决于您的体系结构/样式/ Readmodels如何接收事件。
您可能有一个简单的同步系统,当在同一进程/线程中处理命令,发出事件时,事件立即被保存到事件存储中,然后所有Readmodels和Sagas都收到这些新事件,所有步骤都同步完成。
一个更复杂的系统执行命令,将事件持久保存到事件存储,然后将响应返回给客户端。在一个单独的过程中,Readmodels和Sagas会从事件存储(提供此类API)中轮询新事件,并在后台对其进行处理。
其他解决方案使用消息队列;之所以很难做到这一点,是因为无法安全地以一种可扩展的方式将事件持久保存到事件存储 并以原子方式将它们发布到消息队列中(无论成功还是失败)。没有)。