Axon 或 Kafka 支持 CQRS/ES

KDW*_*KDW 4 architecture cqrs event-sourcing apache-kafka axon

考虑一个简单的用例,我想将产品评级作为事件存储在事件存储中。

我可以使用两种不同的方法:

  1. 使用Axon:Rating聚合负责处理CreateRatingCommand并发送RatingCreatedEvent。发送事件会将评级存储在事件存储中。其他事件处理程序可以在连接到 Axon 服务器实例并执行评级所需的任何操作时重播事件流。在这种情况下,事件处理程序将用作流处理器。
  2. 使用Kafka: KafkaProducer 将用于在 Kafka 主题中存储评级 POJO(正确序列化后)。将主题的保留时间设置为无限期将导致任何事件都不会及时丢失。在这种情况下,Kafka Streams 将用于执行实际的评级处理逻辑。

对于这两种方法,我都出现了一些架构问题:

使用轴突时:

  1. 如果聚合内没有需要维护或更改的真实状态,那么使用 Axon(或类似解决方案)是否有任何附加值?聚合仅充当数据的“哑”占位符,但不提供任何状态更改逻辑。
  2. Axon 如何处理同一事件类型的多个事件处理程序?它们是否都会并行处理相同的事件(相同的聚合 ID),或者相同的事件仅由其中一个处理程序处理一次?
  3. 存储在 Axon 事件存储中的事件是否会保留到时间结束?

使用卡夫卡时:

  1. Kafka 将具有相同键的事件/消息存储在同一分区中。在用户产品评级用例中,如何为密钥选择最佳值?UserId、ProductId 或两者的单独主题,并在两个主题中发布每个事件。
  2. 为每个用户和每个产品使用单独的主题是否明智,从而导致集群上有大量主题?(大约<5k 个产品和>10k 个用户)。

我不知道 SO 是否是此类问题的首选论坛...我只是想知道您在这个特定用例中推荐什么作为最佳实践。期待您的反馈,并随时指出我在之前的问题中遗漏的其他想法。

编辑@12/11/2020:我刚刚找到了一个相关的讨论,其中包含与我的问题相关的有用信息。

Ste*_*ven 5

正如扬·加林斯基(Jan Galinski)已经指出的那样,这个问题还没有一个万无一失的答案。这确实值得在AxonIQ 的讨论论坛上进行更广泛的讨论。无论如何,这里有一些问题我绝对可以给出答案,所以让我们开始吧:

  1. Axon 问题 1 - 正如您所注意到的,Axon 框架大量用于以 DDD 为中心的应用程序。然而,没有什么可以强迫你将自己建立在这个观念之上。您可以将框架从事件溯源细节中剥离出来,也可以完全去除建模细节,纯粹地追求不同命令、事件和查询的消息传递理念。当版本 4(当前)实际发布时,将 Axon 框架版本 3 分为这些子部分是一个有意识的决定。除此之外,我认为不仅仅以事件消息为基础是有很大价值的。使用不同的命令和查询只会进一步解耦您的组件,从而实现更丰富、更容易扩展的应用程序环境。
  2. Axon 问题 2 - 这取决于带注释的方法实际所在的位置@EventHandler。如果它们在同一个类中,则只会调用其中一个。如果他们被定位到不同的类别,那么两者都会收到相同的事件。此外,如果它们被隔离在不同的类之间,请务必注意 Axon 使用事件处理器作为调用事件处理程序的技术解决方案。如果不同的类被分组在同一个事件处理器下,您可以施加一定的顺序,哪个处理程序首先被调用。接下来,如果事件处理应该并行发生,您将必须配置所谓的TrackingEventProcessor(Axon Framework 中的默认值),因为它允许配置多个线程来同时处理事件。好吧,作为本节的总结,您在问题二中提出的所有内容都是一种选择,而不是必需的。确实只是配置问题。可能值得在 Axon Framework 的文档页面上查看有关此事的信息。
  3. Axon 问题 3 - 由于 Axon 服务器用于事件存储,因此根本没有保留期。所以是的,它们默认保留到时间结束。但是,如果您觉得存储事件没有价值以作为所有模型的基础(就像您在使用事件溯源时所做的那样),那么没有什么可以阻止您删除事件。

这是我个人不太熟悉的 Kafka 问题(我猜是 Axon Framework 的贡献者)。不过,我也可以在这里就此事给你两分钱,尽管我在这里推荐第二种意见:

  1. Kafka 问题 1 - 从我个人对此类应用程序需要什么的感觉来看,我假设您希望能够尽可能高效地检索给定产品的所有数据。我敢打赌,重要的是所有事件都位于同一分区中,以使此过程尽可能高效,之后不需要任何合并。考虑到这一点,我认为使用ProductIdwill 最有意义。
  2. Kafka 问题 2 - 如果您预计只有 5_000 个产品和 10_000 个用户,我想为这些产品设置单独的主题应该是可行的。意见传入- 不过,我个人认为 Kafka 的目的是为您提供直接的权力来决定何时使用主题,而不是使您实际尝试实现的业务功能变得复杂。从应用程序开发的角度来看,赋予隔离流的能力更像是事后的想法。我认为,一旦您需要企业级/高效的消息总线,那么这个选项就真正发挥作用,因为这样您就可以针对批量进行优化。

希望这一切可以帮助您进一步@KDW!