软件架构-事件驱动架构

event-driven-architecture

事件插入队列时是有序的,这样就可以顺序处理这些事件。

事件日志

写入事件队列时,消息可能写入到事件日志(通常是磁盘存储)中。如果发生系统崩溃,系统只需要重放事件日志即可恢复到崩溃前的状态。下面是一个事件驱动架构的示例,其中包括一个用于持久化事件的事件日志:

event-driven-architecture

响应队列

有时,我们还需要向请求(即事件)返回响应,所以,很多事件驱动架构除了包含事件队列,还会有一个响应队列。下面是包含事件队列(入队队列)和响应队列(出队队列)的事件驱动架构示例:

event-driven-architecture

上图示例中箭头比较乱,但实际上创建3个丢列并在它们之间分发消息简单很多。

事件日志重放的挑战

事件驱动架构的一大优点是,在系统崩溃或系统重启情况下,只需要重放事件日志,就能够重建系统状态。在日志可以独立于时间和周边系统的情况下重放日志,这是一个很大的优势。

但是,完全独立于时间重放事件日志有时候很难实现。接下来介绍下事件日志重放的一些挑战。

处理动态数据

如前所述,写事件处理时可能会修改系统数据。有些情况,这种数据的修改受事件处理时动态数据的影响。比如,处理事件的日期和时间或者特定日期和时间的货币汇率。

这些动态数据会对事件重放造成困难。如果在不同的时间重放事件日志,处理该事件的服务可能会解析不同的动态值,比如其他的日期和时间或其他汇率。因此,在不同的日期重放事件日志,可能会出现重建系统数据与最初处理事件产生的数据不一致。

要解决动态数据的问题,可以让写事件队列将所需的动态数据标记在事件中。但是,要实现这种方案,需要事件队列知道每条事件消息需要哪些动态数据。这样会使事件队列的设计复杂化,每次需要新的动态数据时,事件队列都需要知道如何查找这些动态数据。

另外一种解决方案是,写事件队列只在写事件上标记事件的日期和时间。使用事件的原始日期和时间,处理事件的服务可以查找给定日期和时间对应的动态数据。比如,可以通过原始的日期和时间,查询当时有效的汇率。这就要求处理事件的服务需要基于日期和时间查询动态数据,但是这只是理想状态。

与外部系统的交互

事件日志重放的另一个挑战是与外部系统的协调。比如,事件日志中包含电商平台的订单,在第一次处理这个事件时,需要将订单发送到外部支付网关,以从客户信用卡中收费。

如果重放事件日志,就不希望再次为同一个订单向客户收费。因此,就不希望在事件重放时,将订单发送到外部支付网关。

事件日志重放解决方案

解决重放事件日志问题挺不容易的。有些系统没有问题,可以直接重放事件日志;有些系统可能需要知道原始事件的日期和时间;有些系统可能需要知道更多类似于事件原始处理过程中从外部系统获取的原始数据。

重放模式

在任何情况下,倾听写事件队列中事件的任何服务都必须知道传入事件是原始事件还是重放事件。这样,处理服务就能够确定如何处理动态数据或者如何与外部系统交互了。

多步骤事件队列

另外一个解决方案是采用多步骤事件队列。第一步,收集所有写事件;第二步,解析动态数据;第三步,与外部系统交互。如果需要重放事件日志,只需要跳过第一步和第二步,重放第三步即可。具体如何实现,需要取决于具体的系统设计。


你好,我是看山,公众号:看山的小屋,10 年老后端,Apache Storm、WxJava、Cynomys 开源贡献者。主业:程序猿,兼职:架构师。游于码界,戏享人生。

原文链接:Event-driven Architecture
翻译: https://www.howardliu.cn
译文链接: 软件架构-事件驱动架构
CSDN主页: http://blog.csdn.net/liuxinghao
CSDN博文: 软件架构-事件驱动架构

软件架构-事件驱动架构 看山的小屋 软件架构-事件驱动架构 微信公众号 软件架构-事件驱动架构 未来不迎,当时不杂,既过不恋

来源:看山

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年1月19日
下一篇 2021年1月19日

相关推荐