IRONSOFTWAREHOME

事件源核心概念

事件溯源核心概念

Derek Comartin

11分31秒

事件溯源是一种功能强大但又复杂的模式,常用于现代软件架构中,尤其是在 C# 和 .NET Core 应用程序中。 为了充分理解如何实现事件溯源,我们将按照CodeOpinion.com的 Derek Comartin 在他的视频*" 事件溯源核心概念"*中解释的关键原则进行讲解。

如果您想更好地了解事件存储概念、领域驱动设计或如何构建事件溯源系统,那么您来对地方了。 让我们深入了解!

事件溯源简介

在视频开头(0:00),Derek 讨论了人们对事件溯源及其相关核心概念的困惑。他将事件溯源定义为不仅仅是"捕获当前状态",而是存储事件——将领域模型发生的每一次变化都记录在一个只追加的日志中。

这样,您就可以完整地保存系统状态变化的历史记录。 与其只持久化最终状态,不如持久化反映所发生业务逻辑的事件。

事件:捕捉商业事实

在 0:33,德里克解释了什么是真正的事件。 事件代表系统中已经发生的事情——一个业务事实。 例如,"ProductReceived"事件将包含收到的数量和日期。

Derek 强调,存储事件时,必须使用反映过去时的命名约定来命名,例如"产品已发货"或"库存已调整"。 在事件架构中,您可能会有诸如公共 Guid ID、公共字符串名称和时间戳之类的字段。

每个事件还应该有一个唯一标识符,这对于一个仅追加存储系统来说至关重要,在该系统中你要将事件追加到事件流中。

活动流程:组织活动

2:02,Derek 转入事件流。 他将其与关系数据库表进行比较,并解释说,在事件溯源中,与领域对象(例如库存项目)相关的所有事件都属于同一个事件流。

每个事件流都与一个特定的实体相关联——通常由一个公共 Guid ID 和一个字符串名称定义。 例如,SKU 为 ABC123 的产品将拥有自己的数据流,其中包含收货或发货等持久化事件。

Derek 建议,在对这些进行建模时,要从聚合根和领域对象的角度来思考,借鉴领域驱动设计的概念。

对生命周期(无论是短寿命还是长寿命)进行建模有助于优化流的数量和规模。 这对于提高复杂系统的性能至关重要。

预测和读取模型

4:12,Derek 介绍了预测和读取模型。 由于您的事件溯源系统捕获的是事件而不是当前状态,因此您必须重放事件才能回答诸如"当前库存数量是多少?"之类的问题。

要构建读取模型,您需要处理来自流的事件。 例如,使用 private void Apply(Event e) 或类似方法,您可以根据每种事件类型的事件处理程序来增加或减少股票数量。

Derek 演示了如何在文档数据库或关系数据库中构建读取模型——也许一个投影只是简单地显示现有数量,另一个投影显示发货历史记录。

这体现了命令查询职责分离(CQRS):将写入操作(命令)与读取操作(查询)分开。

针对写入模型的预测

6:48,Derek 展示了如何在写入端应用投影。 这对于在允许行动发生之前对其进行验证至关重要。

在命令处理程序中,发货前需要验证产品数量是否充足。 Derek 使用了类似 private void Apply(List) 的方法<Event>事件)以重建必要的状态。

诸如 public int Version 之类的字段有助于跟踪流的演变,确保最终一致性。

这种实际应用有助于在处理新事件时强制执行业务逻辑,确保您的系统只对有效的状态转换执行操作。

订阅:对新事件做出反应

8:01,德里克谈到了订阅服务。 订阅功能让活动消费者可以监听新活动并做出反应。

例如,投影仪可以订阅事件流,并在看到"产品已发货"事件时更新读取模型。 或者,发布者可以监听事件并将其发布到 RabbitMQ 或 Kafka 等外部系统,与其他服务集成。

Derek 描述的订阅不仅用于更新内部模型,还用于在不同的事件系统之间分发数据,从而保持最终一致性。

这展现了事件驱动架构的另一个主要优势:您的服务最终保持一致性,但可以独立扩展。

核心概念回顾

9点21分,德里克总结了核心概念:

事件反映事实。

  • 事件流按实体组织事件。

  • 投影将流转换为可查询的读取模型或可操作的写入模型。

订阅功能允许服务做出相应的反应和更新。

他强调,应将事件持久化到仅追加日志中,维护审计跟踪,并在必要时重放事件。

快照和优化

9:39,Derek 讲解了快照功能。 虽然快照经常与事件溯源一起被讨论,但他澄清说,快照是一种性能优化,而不是核心需求。

快照通过定期保存部分状态来减少重放所有事件的开销,但通过仅追加日志,完整的历史仍然存在。

主要区别:事件溯源与事件驱动架构

10:00,Derek 提醒大家注意一个常见的误解:事件溯源和事件驱动架构是不同的! Kafka 等工具可以帮助进行数据分发,但真正的事件溯源侧重于将领域事件记录为不可变的审计跟踪。

在将事件溯源集成到复杂系统中时,理解这种区别至关重要。

结论

看完 Derek Comartin 的视频后,很明显,事件溯源是指将每一次变化都记录为一个事件,而不仅仅是最终状态。 通过将事件存储在仅追加存储系统中,您可以构建丰富的事件模式,从而提供审计跟踪、灵活的事件查询以及对命令查询职责分离的强大支持。

无论你是在 .NET Core 还是任何其他平台上处理 C# 事件溯源,Derek 对核心概念、事件处理程序、私有集、受保护集以及在模型中应用事件(例如 private void Apply())的结构化解释都非常有价值。

如果你正在构建弹性域模型、改进存储系统,或者创建具有最终一致性等诸多优势的复杂模式,那么研究 Derek 的方法是必不可少的。也请关注他的YouTube 频道,那里有更多精彩的视频。

Earn More by Sharing What You Love

Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Let's Stay in Touch!

Join our newsletter, you’ll get exclusive access on article updates. We value your privacy

Key in blue circle

立即获取免费的 30 天试用版密钥

Your trial license will be sent to your email address

无任何限制。100% 解锁。无需信用卡。

OR
bullet_checked无需信用卡或创建账户无任何限制。100% 解锁。无需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried Iron Suite
获取您的无义务咨询
填写下面的表格或通过sales@ironsoftware.com
您的资料将始终保密。
深受全球数百万工程师信赖
Iron Software 的客户徽标
立即获取您的免费30 天试用密钥
无需信用卡或创建账户