Event Sourcing

  • 事件溯源

特点:

  • 整个系统以事件为驱动,所有业务都由事件驱动来完成。
  • 事件是最重要的元素,系统的数据以事件为基础,事件要保存在某种存储上。
  • 业务数据只是一些由事件产生的视图,不一定要保存到数据库中。

原理

  • 通过事件触发相应对象的相应处理函数。(类似于观察者模式)

Event Sourcing(以事件为源的处理模式):

  • 事件需要持久保存在数据库或其他地方,而对象的数据状态却不需要保存,我们只是在需要获得对象当前的数据状态的时候,通过这个对象相关的事件,调用他们的处理函数,重新生成当前状态。
  • 当然,每次都这样调用处理函数势必会造成资源的浪费,因为它需要从数据库中取得所有这个对象的事件,然后依次调用处理函数。
  • 所以一般可以把这个对象的最新状态,以一种视图的方式保存在数据库中。

构成

聚合对象

是一个领域模型,有唯一的标识ID。

Event Store

用于存储事件(如数据库)。

  • 每个事件应该也包含一个它要处理的聚合对象的id,以及事件的顺序,查询的时候就是根据聚合对象的id从数据库中找到相关的事件,并按照生成的事件或序号排序。
  • Event Store除了提供事件数据的存储、查询功能以外,还可提供事件的重现等功能。事件的重现,就是将截止某一个时间的所有事件取出来,调用相应的处理函数,生成当时那个时间点的业务状态。所以在重现之前,如果业务数据的状态,通过视图的形式保存到了数据库中,则需先清除相应的数据。
  • 正是由于Event Sourcing模式的这个以事件为源的特性,所以我们才有可能提供这样的历史重现的功能。

聚合资源库

一般情况下,聚合对象的数据状态是不会保存在数据库当中。
每当系统要获得某一个账户的数据的时候,都是从Event Store当中取出所有相关聚合对象的事件,然后依次的调用这些事件的处理方法,“聚合”出该领域对象最新的数据状态。这个,就是聚合资源库需要提供的功能。

视图

由于每次都重新“聚合”出对象,获取当前的状态,会浪费很多资源。
所以,可在某个事件发生的时候,将这个聚合对象的最新数据状态,写到一个表中,这个表可叫做物化视图。

查询

由于提供了专门的视图表,将聚合对象的最新状态保存在数据库中。那么,在查询的时候,可以通过该物化视图去查询,而不是通过聚合对象的资源库去查询。

Event Sourcing与CQRS

前面为了性能考虑,将聚合对象的数据状态用物化视图的形式保存,来用于数据的查询操作,也就是说将数据的更新与查询的流程隔离开来。
通过事件来更新聚合对象的数据状态,同时由另一个处理器处理相同的事件,来更新物化视图的数据。

使用Event Sourcing和CQRS模式后的简单流程图:
图1

  • 对于Command类型的请求(需要修改数据),web层会走通过Event Sourcing更新聚合对象的流程,这时会有一个Event Handler的处理类监听相应事件,更新物化视图。
  • 对于Query类型的请求,web层会通过相应的DAO获取数据返回。

优缺点

优点

  • 方便进行溯源和历史重现
  • 方便Bug的修复,还可通过事件分析业务的过程
  • 能提供较好的性能:事件数据的保存是一个一直新增的写表操作,没有更新。由另一个Event Handler处理这些事件,更新物化视图的表。而在更新数据的时,只需要锁记录,所以这个更新的过程也很快。
  • 方便使用数据分析等系统:数据就是事件,我们只需要在现有的事件是加上需要的处理方法,来做数据分析;或者将event直接发送到某个分析系统。我们就不需要为了做数据分析,再在系统里定义各种事件,发送事件等。

缺点

  • 需要使用基于事件的响应式编程思维
  • 没有成熟完善的框架
  • 事件的结构的改变:由于业务的变化,我们设计的事件,可能需要添加或删除一些数据。此时,想要进行“历史重现”就会有问题。因而需要通过某种方式进行兼容。
  • 从领域模型角度设计系统,而不是以数据库表为基础设计(针对不懂领域模型设计者来说,才是缺点)。

Event Sourcing模式的适用场景

  • Event Sourcing模式比较适用于有复杂业务的应用系统。当系统有大量的CRUD(即增删改查类型的业务),那么就不适合使用Event Sourcing模式。
  • 团队里面有DDD(领域驱动设计)相关的人员,那么你应该优先考虑使用Event Sourcing。
  • 对于系统来说,业务数据产生的过程比结果更重要,或者说更有意义,那就应该使用Event Sourcing。你可以使用Event Sourcing的事件数据来分析数据产生的过程,解决bug,也可以用来分析用户的行为。
  • 如果需要系统提供业务状态的历史版本(如一个内容管理系统),可针对内容实现版本管理,版本回退等操作,那就应该使用Event Sourcing。

results matching ""

    No results matching ""