社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
事件溯源是一种以事件为中心的编写业务逻辑和持久化领域对象的方法。事件溯源可以消除一些可能的编程错误,因为这项技术可以保证在创建或更新聚合时一定会发布事件。
这是一本关于微服务架构设计方面的书,这是本人阅读的学习笔记。下面对一些符号做些说明:
()为补充,一般是书本里的内容;
[]符号为笔者笔注;
事件溯源模式:使用一系列便是状态更改的领域事件来持久化聚合。
事件溯源采用基于领域事件的概念来实现聚合的持久化;它将每个聚合持久化为数据库中的一系列事件,称为事件存储。
图解:
process()
接收命令对象参数,该参数表示具体的请求,并确定需要自行哪些状态更改;它验证命令对象的参数,并且在不更改聚合状态的情况下,返回表示状态更改的事件列表;如果无法执行该命令,则此方法通常会引发异常;apply()
都将特定事件类型作为参数来更新聚合;这些方法与聚合产生的事件类型一一对应;重要的是要注意执行这些方法不会出现失败,因为这些事件代表了一个已经发生的状态变化;每个方法都会根据事件更新聚合;图解:
reviseOrder()
方法被process()
方法和apply()
方法替代;process()
方法将ReviseOrder命令作为参数;process()
方法要么返回OrderRevisionProposed事件,要么抛出异常;
apply()
方法将Order的状态更改为REVISION_PENDING;创建聚合的步骤:
更新聚合的步骤:
createOrder()
和reviseOrder()
,在事件溯源版本中都由process()
和apply()
方法替代;reviseOrder()
、confirmRevision()
和rejectRevision()
;process()
方法和一些apply()
方法替代这三个的方法;指两个或多个请求同时更新同一聚合的情况;
长生命周期的聚合可能会有大量事件;随时间推移,加载和重放这些事件会变得越来越低效;常见解决方法是定期持久保存聚合状态的快照;
使用相同的消息多次安全地调用消息接收方,则消息接收方是幂等的;具体实现方式取决于事件储存库是关系型数据库还是NoSQL数据库;
事件溯源应用程序的结构分三个层次:
每个级别可能发生的不同类型的更改:
通过向上转换(Upcasting)来管理结构的变化:
好处:
弊端:
使用事件溯源的应用程序将事件存储在事件存储库中;事件存储库是数据库和消息代理功能的组合;它表现为数据库和消息代理;
Eventuate Local的事件数据库结构:
通过订阅Eventuate Local的事件代理接受事件:
Eventuate Local的事件中继把事件从数据库传播到消息代理:
Eventuate Client框架使开发人员能够使用Eventuate Local事件存储库编写基于事件溯源的应用程序;它为开发基于事件溯源的聚合、服务和事件处理程序提供了框架基础;
图解:
@EventSubscriber
注解指定持久化订阅方的ID;@EventHandlerMethod
注解将creditReserved()方法标识为事件处理程序;事件溯源可以轻松使用基于协同式的Saga;将事件溯源的业务逻辑与基于编排的Saga相结合更具挑战性;
Saga编排器由服务的方法创建,会执行创建和更新聚合两项操作,该服务必须保证则两个操作在同一个事物中完成;因此取决于使用的事件数据库类型;
当关系型数据库作为事件存储库时,应该如何创建Saga编排器:
@Transactional
注解,使Eventuate Local框架与Eventuate Tram Saga框架在同一个ACID事务中更新时间存储库并创建Saga编排器即可;当非关系型数据库作为事件存储库时,应该如何创建Saga编排器:
好处:保证松耦合,因为OrderService之类的服务不再明确地实例化Saga;
问题:如何处理重复事件保证幂等性,解决方法如下:
下图显示了Accounting Service如何处理Saga发送的Authorize Command;Accounting Service使用Eventuate Saga框架,该框架用于编写使用事件溯源的Saga;
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!