【发布时间】:2019-02-03 03:09:35
【问题描述】:
我们有几个遗留应用程序,主要由 GUI + 服务层 + RDMS 组成。随着时间的推移,添加了一些批处理来在不同数据库之间同步/传输数据,等等。通常的意大利面架构:)
我们正在清理这个烂摊子,我们正在设计一个基于event sourcing和materialized 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