Event Driven事件驱动,你要知道的这里基本都有了
在微服务、分布式、云计算的背景下,事件驱动越来越多地被使用到。但奇怪的是,在和不同团队交流的过程中,我们发现大家对事件驱动的理解都不一样。本文的主要内容基于Martin Fowler在其博客上发布的关于事件驱动的文章(具体请参考文献#1及#2),主要是想讨论事件驱动的几种典型模式。
我们为什么需要事件驱动?
考虑一个保险的业务场景,当一个人在购买保险时,保险公司的内部系统需要根据客户的情况对保费进行计算。假如这个客户的基本信息改变了,其保费是需要重新进行计算的。在这样一个保险的场景中,其业务关系是:
当客户信息变化,客户管理服务需要通知保费计算服务进行重新计算,也就是说客户管理服务依赖于保费计算服务。若我们从现实业务的角度去考虑,客户管理服务不应该依赖于保费计算服务,至少应该保费计算服务依赖于客户管理服务。这种与现实不相符的依赖关系会将复杂的业务逻辑集中在了客户管理服务中,这将极大地影响该服务的可维护性。那么,比较理想的方式是什么呢?
客户管理服务与保费计算服务是松散的依赖关系,即客户管理服务不会主动通知其它服务执行某些行为,而是由保费计算服务去监听客户管理的变更,从而来决定是否需要重新计算保费。
上面说提到的这种方式就是事件驱动的具体表现形式。而在整个过程中,承担着媒介,起到通知的作用的就是事件。
优势 vs 劣势
了解事件驱动后,我们简单的归纳一下事件驱动的一些优势以及劣势。
- 优势
- 反转了服务间的依赖关系,更贴近真实的业务逻辑关系。
- 事件成为了可以被消费的对象,而不仅仅是在函数间传递的临时参数,从而可以同时被多个服务消费。
- 其它服务不需要直接和生成事件的服务进行交互,而可以通过监听事件,触发其对应的操作,从而降低了服务内部的复杂度。
- 劣势
引入事件驱动带来的主要问题是:由于服务间高度解耦,很难从全局的角度了解服务间的依赖关系(至少通过单纯看代码,比较难)。另外,由多个服务组成的业务流程是否被顺利地执行,也需要额外的监控。
事件 vs 命令
当我们提到事件的时候,总会不知不觉地将事件和命令混淆在一起。在具体讨论事件驱动的几种模式前,有必要进行一下说明:
- 事件:生成事件的对象通过事件描述了一个动作及其结果,但是该对象不知道事件接下来会被如何处理。
- 命令:生成命令的对象知道针对某一事件的处理逻辑,所以该对象将要求目标对象对事件进行相应的处理。
总的来说,事件更像是被动操作,而命令更倾向于主动操作。
事件驱动的几种模式
- 事件通知 (Event Notification)
事件通知是最常用到的事件驱动方式。其典型过程如下图:
当客户信息发生变化时,客户管理服务发布客户信息变化的事件,并加入队列。保费计算服务通过订阅该队列中客户信息变化的事件,从而可以捕获客户信息变化,触发保费再计算的过程。事件通知模式可以高效的进行扩展,众多服务可以监听同一队列。
- 携带状态的事件 (Event-carried State Transfer)
事件通知模式可以有效地对服务进行解耦,不过,同时也带来了一个问题。考虑这样一种场景,A服务发布了一个事件,B服务捕获事件后需要A服务提供额外的数据进行处理,所以B服务通过A服务API获得数据,进行业务处理。这看起来似乎没什么问题,但是当有N多服务都需要A服务提供额外的数据时,那么A服务很容易会出现过载的情况。
携带状态的事件这种模式主要用来解决上述问题。为了防止过多服务访问A服务,A服务在生成事件的同时,将额外数据也一并加入到事件中。从而其它服务可以直接从事件中获得其需要的数据,而不需要访问A服务。
不过,携带状态的事件这种模式同时也带来了一些问题:需要更多的储存空间,另外数据有可能出现不一致的风险。
- 事件溯源 (Event Sourcing)
事件溯源模式的处理方法与传统的处理方式不同,其核心是记录事件的过程,通过叠加事件,计算出最新的结果。我们通过以下例子进行详细的解释:
当用户将名字从“托马斯”改为“詹姆斯”时,传统的方式是将名字“托马斯”删除,重新生成名字“詹姆斯”。
但是在事件溯源模式的模式下,用户首先生成名字从“托马斯”改为“詹姆斯”的事件,再由该事件将驱动用户的名字修改为“詹姆斯”。
简单来说,事件溯源模式有点像代码的版本控制(例如:Git)。当我们手上有历史的所有代码版本,我可以随便恢复到任何事件节点。事件溯源模式也是类似的,其核心就是记录事件的过程,而不是事件导致的结果。
事件溯源模式带来的好处是:每个事件都是可追溯的,符合审计的要求;可以将事件叠加的结果记录在内存中,从而大大的提升性能(需要基于定期快照)。其需要注意的地方是:如果事件的schema需要进行修改,可能会影响到过往的事件;当系统进行了较大重构,基于原有的事件是否能够兼容。
参考文献
- What do you mean by “Event-Driven”? - https://martinfowler.com/articles/201701-event-driven.html
- GOTO 2017 • The Many Meanings of Event-Driven Architecture • Martin Fowler - https://www.youtube.com/watch?v=STKCRSUsyP0
pstrike 2018.06.08 于广州天河
【尊重版权:转载之前请先联系我】