两个常见问题 - EventStore和持久层?
我想了解行业是如何处理这个问题的!
如果微服务1将对象X持久存储到数据库A中。同时,对于微服务2以来自微服务1的数据,微服务1将相同的对象X写入事件存储B.
现在,问题是,我先在哪里写对象X?
数据库第一个然后到事件存储B,如果数据库A关闭,在应用级别回滚线程是否公平?另外,如果数据库A在线且持久化对象X但事件存储B已关闭,那么理想的错误句柄应该是什么?
如果我们反之亦然,那么错误句柄应该是什么样的?
我确实理解,在当今分布式高可用系统的世界中,系统崩溃是值得怀疑的。但是,它可能发生。我想了解当数据库或事件存储系统/集群关闭时需要做什么?
答案 0 :(得分:0)
通常,您希望避免依赖于您描述的那种两阶段提交。
一般来说,(假设一个事件来源的系统;不确定你的问题中是否含有这个/你的选项 - 也许SqlStreamStore
可能与你的上下文相关?),这通常是通过提供某些东西来管理的project
来自拉动基础上的单个权威事件集 - 每个被写入的事件需要对某些下游的相关操作维护指向它从基本流中投射事件的距离,并从那里重新启动如果被打断了。
答案 1 :(得分:0)
首先,事件存储是一种Persistence,它将应用程序状态存储为一系列事件,而不是存储最后一个投影状态的 flat 持久性。
如果微服务1将对象X持久存储到数据库A中。同时,对于微服务2以来自微服务1的数据,微服务1将相同的对象X写入事件存储B.
你试图有两个必须通过某种分布式事务保持同步的事实来源,这种事务的可扩展性不是很高。
这是一种使用事件存储的异常模式。通常,事件存储是规范的信息源,是事实的唯一来源。您正尝试将其用作通信渠道。事件存储是事件源聚合的持久性(请参阅域驱动设计)。
我看到选项:
您可以重构您的体系结构,并使object X
和事件源实体具有事件存储的持久性。然后让Read模型订阅Event存储并构建一个持久存储在数据库A中的object X
的平面表示。换句话说,首先写入Event存储,然后写入数据库A(但是最终的一致方式!)。这是一个很大的跳跃,你应该考虑一下你是否想要参加活动。
您可以在没有事件采购的情况下使用CQRS。这意味着在每次修改后,object X
会发出一个或多个Domain事件,这些事件在与object X
本身相同的本地事务中保留在数据库A中。微服务2可以订阅数据库A以获得发出的事件。实际订阅取决于数据库的类型。
答案 2 :(得分:0)
我觉得您正在使用事件存储作为沟通渠道,而不是将其用作数据库。如果您希望微服务2依靠微服务1的数据,那么您应该与REST服务进行通信。
当然,依靠REST服务可能会使您对中断的适应能力降低。在那种情况下,使用专用于通信的技术将是正确的方法。 (我在考虑MQ / Topics,例如RabbitMQ,Kafka等)
然后,一旦您的服务相互通信,您仍将需要持久保存数据……但仅在一个位置。 因此,您将需要定义要存储数据的位置。
问问自己:
谁将管理数据持久性?
是相反的方式吗? Microservice2拥有数据的管理权,而Microservice1则使用它?
它可能是您尚未创建的第三个微服务。这取决于您如何应用关注点分离。
让我们举个例子:
谁要在这里存储数据?
例如:如果我有一个Microservice3可以确保每次更改我的ObjectX
时,它都会将其PDF表示形式发送到某个地址,并通知我的所有合作伙伴该数据已用完-日期。在那种情况下,这种微服务看起来像是成为域的这一部分的“数据管理者”的好人选,并且是在数据库中进行写/读的一站式商店。