我最近试图解决这个问题。
您的客户端偶尔会连接到单个服务器。
我最近再次看了greg youngs video on occasionally connected systems on skillsmatter.com。
在那里,他说处理它的最佳方法是:
现在这一切都很好,但我有一个更复杂的情况 - 一个有两个服务器:测试和生产
您还可以将此视为git merge场景,您希望将所有更改从分叉远程存储库A推送到原始远程存储库B.
问题是:
所以我猜这个问题基本上有两个解决方案: a)保留命令流并将其下载到客户端 - 但这与在事件采购系统中仅存储事件的事实相冲突 b)有一种机制可以从已经提交的事件中重新创建命令。 这样,客户端可以查看生产中的模板版本,以查看尚未在那里发出的事件。然后它相应地创建命令并执行它们。
我的问题:
谢谢你们的想法!
感谢您分享您的想法。但似乎我必须澄清一些事情 - 测试与制作的事情。
让我们假设我们正在构建一些像salesforce这样的应用程序框架:您可以 - 通过使用指向和单击 - 使用其实体和工作流等来定义您的应用程序。 当然,您可以在单独的沙箱环境中执行此操作。 当您完成第一个应用程序版本后,您将需要将其移至生产服务器,以便您的用户可以实际使用您构建的应用程序"。
现在考虑以下内容:在生产中,您意识到,存在一个小错误,您可以立即修复它。然后,您希望将这些更改传回测试环境。
所以现在问题是:真正的来源是什么?
我喜欢抱怨git,因为大多数开发者都知道。 基本上我可以看到我有两个选择:
其中一个环境是记录簿。所以在那种情况下,我必须收集所有命令,一旦我更新生产,我就会推送命令。 这就像 git rebase
让我们假设这两个系统都是"记录簿"。在这种情况下,我需要同步测试环境中发生的事件和生产环境中发生的事件(因此我在测试和生产中获得了相同的应用程序定义) 因此,来自Test的事件不仅仅附加到生产的事件流,而是按照它们实际发生的顺序在生产事件流中排序。 这就像 git merge
我个人更喜欢 git merge 选项,因为它会在两个系统中产生完全相同的事件顺序。 当然,这将允许偶尔连接的客户端使用相同的方法进行分布式协作: 假设我们在Test中定义并使用此Event Sourcing方法发布到Production的应用程序随后被多个偶尔连接的客户端用于实际收集数据。 现在,多个客户端可以在相同的聚合根同步上彼此协同工作(如在peer2peer系统中),同时仍保持相同的事件流顺序。
然而,问题可能是客户端将事件e1同步到服务器,但此事件对应的聚合器已经处理了稍后发生的事件e2。所以事件处理会出现故障。
所以我的问题是:这个" git merge"是否有任何明显的缺点?
答案 0 :(得分:1)
我认为你对你的记录/真相的定义纠缠在你的情况中。
如果 production 是记录簿,那么应该发送命令。在这种情况下,测试实例在几个方面与客户端实例类似;它变成了一个可以尝试外出的沙箱,但它实际上可能并不代表真相"当谈到推动下一阶段的事情。因此,您将命令排在队列中,并最终将这些命令传递给生产实例。
如果 test 是这些更改的记录簿,那么您不能与生产共享命令,而是共享事件(或者可能是投影,具体取决于哪种型号更适合您的实际使用情况)。这有点类似于使用微服务: test 是支持发送给它的命令的微服务,而生产是一个单独的微服务,可以响应来自 test 的事件 - 在其他单词,生产取决于测试中的阅读模型。
回顾Udi Dahan对services所说的话可能有助于澄清事情
服务是特定业务能力的技术权威。 任何数据或规则必须仅由一项服务拥有。
我的猜测,基于您使用" test"和#34;生产",是生产系统没有权力改变正在推动测试的数据;它只是消耗了该数据的视图。这使你直接回到单个服务器(实际上是:单本记录)用例。