事件存储、CQRS 与基础设施管道构建
1. 事件存储(Event Store)
事件存储系统相对简单,可使用多种数据存储系统来实现,如文件系统中的简单文件、亚马逊简单存储服务(S3)存储桶,或任何能可靠存储一系列数据条目的数据库存储。其接口需支持三个基本功能:
- 存储新事件并分配正确顺序,以便按保存顺序检索事件。
- 通知正在构建投影的事件订阅者有关他们关心的新事件,并实现竞争消费者模式。
- 为特定事件类型获取事件 X 之后的 N 个事件,用于协调流程,例如在投影丢失、受损或存疑时进行重新计算。
本质上,事件存储的基本接口仅由两个函数组成:
save(x)
getNAfterX()
此外,还有一种强大的通知系统,允许消费者订阅事件。这里的“强大”指符合竞争消费者模式。该模式很重要,因为基于事件构建投影的系统可能希望有多个客户端实例“监听”事件,以实现冗余和可扩展性。通知器必须合理确保只向一个监听实例进行一次事件传递,以避免意外的事件重复导致数据损坏。可采用以下两种方法:
1. 使用已为消费者提供此类保证的消息队列实现,如 Apache Kafka。
2. 允许消费者将 HTTP 端点注册为回调。为每个新事件调用回调端点,并让消费者端的负载均衡器处理工作分配。
两种方法各有优劣,一种是基于推送的,另一种是基于拉取的,具体选择取决于实际需求。
在开发过程中,还可参考一个在 GitHub 上发布的事件存储骨架的参考实现,可对其进行查看、测试或贡献代码。