事件存储可能成为单点故障?

问题描述 投票:9回答:5

几天以来,我一直试图弄清楚如何告知其余的微服务,在微服务A中创建一个新实体,将该实体存储在MongoDB中。

我想要:

  • 微服务之间的耦合很低
  • 避免像两阶段提交(2PC)这样的微服务之间的分布式事务

起初像RabbitMQ这样的消息代理似乎是一个很好的工具,但后来我看到了在MongoDB中提交新文档并在代理中发布消息而不是原子的问题。

Why event sourcing? by eventuate.io:enter image description here

解决此问题的一种方法意味着通过添加一个标记来说明文档的模式有点脏,该标记表明文档是否已在代理中发布,并且具有在MongoDB中搜索未发布文档的预定后台进程,并使用这些文档将这些文档发布到代理confirmations,当确认到达时,文档将被标记为已发布(使用at-least-once和idempotency语义)。这个解决方案是在thisthis答案中提出的。

读克里斯理查德森的Introduction to Microservices我最后在Developing functional domain models with event sourcing这个伟大的演讲中,其中一张幻灯片问:

如何在没有2PC的情况下自动更新数据库并发布事件和发布事件? (双写问题)。

答案很简单(在下一张幻灯片中)

更新数据库和 发布活动

这是基于this oneCQRS a la Greg Young的另一种方法。

域存储库负责发布事件,这通常在单个事务内部,同时将事件存储在事件存储中。

我认为委托存储和发布事件到事件存储的责任是一件好事,因为避免了2PC或后台进程的需要。

然而,在某种程度上它是真正的that

如果您依赖事件存储来发布事件,那么您将与存储机制紧密耦合。

但是,如果我们采用消息代理来进行微服务的交互,我们可以说同样的话。

令我担心的是,事件存储似乎成为单点故障。

如果我们从example eventuate.io看这个enter image description here

我们可以看到,如果事件存储已关闭,我们无法创建帐户或资金转移,失去了微服务的优势之一。 (虽然系统将继续响应查询)。

因此,确认eventuate示例中使用的事件存储是单点故障是正确的吗?

cqrs microservices event-sourcing get-event-store
5个回答
6
投票

你所面对的是Two General's Problem的一个例子。基本上,你想在网络上有两个实体同意the network is not fail safe。 Leslie Lamport证明这是不可能的。

因此,无论您向网络添加多少新实体,消息队列为一个,您将永远不会100%确定将达成协议。实际上,情况恰恰相反:您添加到分布式系统的实体越多,您就越不能确定最终会达成协议。

对你的情况一个实际的答案是,如果你考虑增加更多的复杂性和单点故障,2PC并不是那么糟糕。如果你绝对不想要单点故障并且想要假设网络是可靠的(换句话说,网络本身不能是单点故障),你可以尝试一种P2P算法,例如DHT,但是两个同行我打赌它减少到简单的2PC。


1
投票

我们使用NServiceBus中的Outbox方法处理这个问题:

http://docs.particular.net/nservicebus/outbox/

这种方法要求整个操作的初始触发器作为队列中的消息进入,但效果很好。


1
投票

您还可以为事件存储中的每个条目创建一个标志,以指示此事件是否已发布。另一个进程可以在事件存储中轮询这些未发布的事件,并将它们放入消息队列或主题中。这种方法的缺点是该队列或主题的消费者必须设计为消除传入消息的重复,因为该模式仅保证至少一次传递。由于轮询频率,另一个缺点可能是延迟。但由于我们已经进入了最终一致的区域,这可能不是一个大问题。


1
投票

如果我们有两个事件存储,那么每当创建一个域事件时,它就排队到两个事件存储库中。查询端的事件处理程序处理从两个事件存储中弹出的事件。

当然,每个事件都应该是幂等的。但这不会解决我们的事件存储是单一入口点的问题吗?


0
投票

不是特别是mongodb解决方案,但您是否考虑过利用Redis 5中引入的Streams功能来实现可靠的事件存储。看看这个介绍here

我发现它具有丰富的功能集,如消息拖尾,消息确认以及轻松提取未确认消息的功能。这肯定有助于实现至少一次消息传递保证。它还支持使用“使用者组”概念的消息负载平衡,这有助于扩展处理部分。

关于您对单点故障的关注,根据文档,流和消费者信息可以跨节点复制并持久保存到磁盘(使用我认为的常规Redis机制)。这有助于解决单点故障问题。我正在考虑将其用于我的一个微服务项目。

© www.soinside.com 2019 - 2024. All rights reserved.