我们有几个遗留应用程序,主要由GUI +服务层+ RDMS组成。随着时间的推移,添加了一些批处理以在不同数据库之间同步/传输数据,依此类推。通常的意大利面条建筑:)
我们正在清理这个烂摊子,我们正在设计一个基于event sourcing
和materialized views
的架构:
一步一步,现有的应用程序将不得不采用这种架构。这就是我担心的地方。如何处理数据验证?
对于旧版应用程序,当用户更新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..>
我们可能会达到应用程序可能生成无效事件的程度,甚至无法存储在自己的数据库中的事件。 (例如,应用程序可能会推送像“创建新地址”这样的命令,其中包含其“Country”表中不存在的国家/地区代码。)这就像一个悖论:“事件”存在,这是事实,但是这个事实并没有被其父母接受。
3.如果我们使用Kafka存储“事件”主题,而不是“命令”:
没有“命令”:
Service layer > Kafka topic "Events" > Consuming apps
在这里,如何避免生成应用程序发布无效事件。
你会建议什么?
问候,
我的设计中错过了一个概念吗?
关于Kafka Streams和CQRS,还有其他问题。我建议看看Kafka Streams是否是提供事务性事件存储的正确工具。
与CQRS合作是否有意义?
我不知道CQRS将成为清理你现有的意大利面条乱码的神奇子弹。存在与CQRS相关联的学习曲线,包括选择正确的域和聚合边界的曲线。如果您的团队中没有人具有CQRS专业知识,那么这段旅程可能非常困难,并且可能只是引入一类您必须处理的新问题。正如他们所说,更好的是你知道的魔鬼。
如果“流媒体平台”不执行验证,请相信生成的应用程序并接受主题中的所有事件?
命令应由域层验证,并且验证可以建模到域中。但是,在接受用户输入时,您还应该保持一定程度的验证。例如,如果需要某个字段,请确保在用户提供该字段时该字段不为空。
一旦记录了一个事件,它就被认为是事实。事件流直到现在才告诉你历史,你别无选择,只能相信它。
在发出命令或事件之前,应用程序是否应根据已管理的数据验证数据?
通常不是。这些应用会验证什么?如果队列中的事件在验证时尚未应用于您的数据源,则可能会错误地拒绝命令或事件。根据您的同步保证,您可能会逃避查询域层,以便决定下一个要发出的命令。通常,您的Aggregate或Saga将足够了解以根据需要做出决策。
花些时间阅读http://www.cqrs.nu。这有助于我在考虑实际实施之前建立对CQRS和事件采购的基线理解。
在您激动人心的旅程中干杯并祝您好运。