Apache Kafka流和事件源,CQRS和验证

时间:2018-08-28 13:02:57

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

我们有几个旧版应用程序,主要由GUI +服务层+ RDMS组成。随着时间的流逝,添加了一些批处理以在不同数据库之间同步/传输数据,依此类推。常见的意大利面条架构:)

我们正在清理这种混乱,我们正在设计基于event sourcingmaterialized views的体系结构:

  • 基于Kafka和Kafka流的事件日志
  • 事件被流式传输到使用中的应用程序,该应用程序以所需方式使用/存储数据

分步操作,现有的应用程序将必须采用此体系结构。这就是我担心的地方。如何处理数据验证?

使用旧版应用程序,当用户更新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属于生产者应用。) 在此设计中,请记住“生产应用程序”也是“消费应用程序”,并且生产应用程序的数据库仅在周期结束时进行更新。 < / p>

我不确定我们的方向是正确的。我预言有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是否有意义?
  • “流媒体平台”是否不执行验证,信任正在制作的应用并接受主题中的所有事件?
  • 在发出“命令”或“事件”之前,应用程序是否应该根据它们已经管理的数据来验证数据?

此致

1 个答案:

答案 0 :(得分:2)

  

我的设计中是否缺少一个概念?

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

  

使用CQRS是否有意义?

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

  

“流媒体平台”是否不执行验证,信任正在制作的应用并接受主题中的所有事件?

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

一旦记录了事件,就将其视为事实。事件流可以告诉您直到现在的历史,您别无选择,只能信任它。

  

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

通常不是。应用程序将针对哪些条件进行验证?如果在验证时队列中有尚未应用到数据源的事件,则您可能会错误地拒绝命令或事件。根据您的同步保证,您可能不愿查询域层,以便决定下一步要发出的命令。通常,您的汇总或Saga会知道足够多,可以根据需要做出决策。

花一些时间通读http://www.cqrs.nu。这对我在考虑实际实施之前建立对CQRS和事件源的基线理解很有帮助。

祝您旅途愉快,万事如意。