我目前正在构建一个应用程序,我想使用微服务作为模式和GraphQl进行通信。我正在考虑使用kafka / rabbitmq + authZ + auth0 + apollo + prisma。所有这些都在docker上运行。 我发现了许多关于事件采购,优势/劣势的资源,而且我坚持认为它在现实世界中是如何运作的。到目前为止,我将如何做到这一点:
理想情况下:
现在,如果我理解正确,请使用apache kafka + zookeeper:
如果我是对的,我可以假设:
有两种方法可以验证请求是否有效:
然后它向kafka发布一个事件(我自动假设kafka更新zookeeper),然后读取消息可以用来更新实体的私有快照。当然,其他MS也可以使用此消息。 我不太熟悉apache kafka + zookeeper,过去我只使用短信服务作为rabbitmq。它们在形状上似乎相似但使用方式却截然不同。
答案 0 :(得分:1)
我将尝试回答您在概念层面上的主要问题,而不必与框架和实现的细节相关联。希望这会有所帮助。
有两种方法可以验证请求是否有效:
。写方仅获取事件(来自事件存储,AKA zookeeper)以验证所请求的突变是否可能。
。写作方从传统数据库获取快照以验证所请求的突变。
我选择了第一个选项。要执行命令,您应该依赖当前事件流作为权限来确定模型的当前状态。
您的体系结构的读取模型最终只是一致的,这意味着命令发生之间存在任意延迟,并且它在读取模型上反映出来。虽然您可以使用您的体系结构来尝试确保此延迟尽可能小(即使您忽略了这样做的成本),但您将始终有一个窗口,其中您的读取模型仍然是最新的。
话虽如此,您的命令应该根据您当前的事件存储区对命令模型运行。
事件源和基本消息传递之间的主要区别在于使用事件存储而不是实体的快照?在这种情况下,我们可以假设并非所有MS都需要事件的存储策略(我的意思是,通过事件存储验证,而不是通过"私有"数据库)?如果是,是否有人可以解释您何时需要活动的商店?何时不需要?
事件采购的整个概念是:而不是将您的状态存储为"可更新的"只反映此类数据的最新阶段的数据,您将状态存储为一系列可以解释为达到此状态的操作(事件)。
所以,想象一下你的域名中有一段读取(以自由格式表示法):
实体A = {Id:1;姓名:" Something&#34 ;; }
发生了一些事情并且命令到达以将此类实体的名称更改为"其他事情"。
在传统存储中,您可以获得此类记录并将其更新为:
{Id:1;姓名:"其他事情&#34 ;; }
但是在事件源存储中,您将没有这样的记录,您将拥有一个事件流,其数据如下:
{使用Id = 1创建的实体}> {Id = 1的实体重命名为" Something"}> {Id = 1的实体重命名为"其他东西"}
现在,如果你"重播"这些事件按顺序排列,你将达到与传统存储相同的状态,只有你会知道"你是如何进入这种状态的,而传统的存储将会忘记这种历史。
现在,要回答你的问题,你绝对正确。并非所有的微服务都应该使用事件存储,甚至不推荐使用。实际上,在微服务架构中,每个微服务都应该有自己的持久性机制(很多时候都是不同的技术),没有微服务可以直接访问另一个持久性(如图所示,"另一个MS& #34;到达"比尔的MS")的事件商店。
所以,你的基本决定因素应该是:
您的微服务是否通过积极存储域内的状态演变(除了反应性地记录它)而获得更多收益?
您的微服务域是否是您对分析旧计算感兴趣的域名? (也就是说,能够将域恢复到给定的时间点,以便您可以了解其状态的演化模式 - 在这里考虑一些复杂的审计,您希望了解过去的计算)
即使您回答"是"对这两个问题......这样的架构增加的复杂性是否值得?
正如关于此主题的结束语,请注意您的模型中有多种模式交织在一起:
这两种模式经常一起使用,因为它们很好地匹配,但这不是先决条件。您可以使用事件存储数据,而不是使用CQRS分成两个模型。您可以在两个模型(命令和查询)中组织域,而不将它们主要存储为事件。