【问题标题】:Apache Kafka Streams and Event Sourcing, CQRS and validationApache Kafka 流和事件溯源、CQRS 和验证
【发布时间】:2019-02-03 03:09:35
【问题描述】:

我们有几个遗留应用程序,主要由 GUI + 服务层 + RDMS 组成。随着时间的推移,添加了一些批处理来在不同数据库之间同步/传输数据,等等。通常的意大利面架构:)

我们正在清理这个烂摊子,我们正在设计一个基于event sourcingmaterialized views的架构:

  • 基于 Kafka 和 Kafka Streams 的事件日志
  • 事件被流式传输到消费应用,这些应用以他们想要的方式使用/存储数据

逐步地,现有应用程序将不得不采用这种架构。这就是我担心的地方。如何处理数据验证?

在旧版应用中,当用户更新 UI 上的数据时,服务层会先进行验证(技术检查和业务检查),然后再将新状态保存在数据库中。 (technical checks 我的意思是检查字段的类型、长度、外键的存在......以及business checks,比如“如果 attr_A = xxx 那么 attr_B 不能为空”。)

对于新架构,即使我们承诺依赖event sourcing 模式,我意识到我目前正在设计一些看起来更像CQRS + Event Sourcing 解决方案的东西:

Service layer > Kafka topic "Commands" > Validation > Kafka topic "Events" > Consuming apps

(与Service layer 属于生产者应用。) 在这个设计中,重要的是要记住,“生产应用”也是一个“消费应用”,生产应用的数据库只会在周期结束时更新。

而且我不确定我们的方向是否正确。我预见到 2 或 3 种不同的方式可以走得更远。没有一个是 100% 满意的:

1.如果您继续使用此 CQRS 选项

保持“命令”主题:

Service layer > Kafka topic "Commands" > Validation > Kafka topic "Events" > Consuming apps
<PRODUCING APP> <---------------------- STREAMING PLATFORM ----------------><.CONSUM APP.>

我将Validation 阶段设计为由 Kafka Streams 应用程序管理。在这种情况下,处理我之前所说的“技术检查”不会太复杂。但我真的不确定Streaming Platform 是处理业务检查的正确位置。

2.如果您继续使用此 CQRS 选项,无需业务验证

保持“命令”主题:

Service layer   >  Kafka topic "Commands" > Kafka topic "Events"   >  Consuming apps
<.PRODUCING APP.> <---------------- STREAMING PLATFORM ------------> <..CONSUM APP..>

我们可能会达到应用程序可能会生成无效事件的程度,这些事件甚至无法存储在自己的数据库中。 (例如,应用程序可能会推送类似“创建新地址”的命令,其中包含在其“国家”表中不存在的国家代码。)这就像一个悖论:“事件”存在,这是事实,但其父级不接受这一事实。

3.如果我们使用 Kafka 来存储“事件”主题,而不是“命令”:

没有“命令”:

Service layer   >  Kafka topic "Events"   >  Consuming apps

再说一遍,如何避免生产应用发布无效事件。

你有什么建议?

  • 我的设计中有没有遗漏的概念?
  • 使用 CQRS 是否有意义?
  • “流媒体平台”是否应该不执行验证、信任生产应用并接受主题中的所有事件?
  • 在发出命令或事件之前,应用程序是否应该根据它们已经管理的数据验证数据?

问候,

【问题讨论】:

    标签: apache-kafka cqrs apache-kafka-streams event-sourcing


    【解决方案1】:

    我的设计中有没有遗漏的概念?

    还有其他关于 Kafka Streams 和 CQRS 的问题。我建议看看 Kafka Streams 是否是提供事务性事件存储的正确工具。

    使用 CQRS 是否有意义?

    我不知道 CQRS 会成为清理您目前拥有的意大利面条式代码混乱的灵丹妙药。有一条与 CQRS 相关的学习曲线,包括选择正确的域和聚合边界。如果您的团队中没有人具有 CQRS 方面的专业知识,那么旅程可能会非常困难,并且可能会简单地引入您必须处理的一类新问题。正如他们所说,最好是你认识的魔鬼。

    “流媒体平台”是否应该不执行验证、信任生产应用并接受主题中的所有事件?

    命令应该由域层进行验证,并且可以将验证建模到域中。但是在接受用户输入时,您还应该保持一定程度的验证。例如,如果需要某个字段,请确保在用户提供该字段时它不为空。

    一旦事件被记录下来,它就被认为是事实。事件流告诉你迄今为止的历史,你别无选择,只能相信它。

    在发出命令或事件之前,应用程序是否应该根据它们已经管理的数据验证数据?

    通常不会。应用程序会针对什么进行验证?如果队列中有事件在验证时尚未应用于您的数据源,您可能会错误地拒绝命令或事件。根据您的同步保证,您可能会通过查询域层来决定接下来要发出哪些命令。通常,您的 Aggregate 或 Saga 将知道足以根据需要做出决策。

    花点时间阅读http://www.cqrs.nu。这有助于我在考虑实际实施之前建立对 CQRS 和事件溯源的基本理解。

    为您激动人心的旅程干杯并祝您好运。

    【讨论】:

      猜你喜欢
      • 2019-01-31
      • 2018-11-15
      • 2019-09-22
      • 2012-03-16
      • 2018-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多