Microservices 事件存储可能成为单点故障?
几天以来,我一直在试图弄清楚如何通知其他微服务,在微服务中创建了一个新实体,并将该实体存储在MongoDB中 我想:Microservices 事件存储可能成为单点故障?,microservices,cqrs,event-sourcing,eventstoredb,Microservices,Cqrs,Event Sourcing,Eventstoredb,几天以来,我一直在试图弄清楚如何通知其他微服务,在微服务中创建了一个新实体,并将该实体存储在MongoDB中 我想: 微服务之间的耦合度较低 避免微服务之间的分布式事务,如两阶段提交(2PC) 起初,像RabbitMQ这样的消息代理似乎是一个很好的工具,但随后我看到了MongoDB中的新文档和代理中的消息不是原子的问题 通过eventuate.io: 解决此问题的一种方法是添加一个标记,说明文档是否已在代理中发布,并有一个预定的后台进程,该进程在MongoDB中搜索未发布的文档,并使用,当
- 微服务之间的耦合度较低
- 避免微服务之间的分布式事务,如两阶段提交(2PC)
因此,确认Eventate示例中使用的事件存储是单点故障是正确的?您所面临的是事件存储的一个实例。基本上,您希望在网络上有两个实体在某些方面达成一致,但是。莱斯利·兰波特证明了这是不可能的 因此,无论您向网络中添加多少新实体(消息队列是一个),您都永远无法100%确定会达成一致。事实上,情况正好相反:添加到分布式系统中的实体越多,最终达成协议的把握就越小
<> P>一个实际的答案是,如果你考虑增加更多的复杂性和单点故障,那么2PC就不是那么糟糕了。如果您绝对不希望出现单点故障,并且希望假设网络是可靠的(换句话说,网络本身不可能是单点故障),您可以尝试P2P算法,例如,但对于两个对等点,我打赌它会简化为简单的2PC。我们使用NServiceBus中的发件箱方法处理此问题:
此方法要求整个操作的初始触发器作为队列上的消息传入,但效果很好。您还可以为事件存储中的每个条目创建一个标志,告知此事件是否已发布。另一个进程可以轮询事件存储区中那些未发布的事件,并将它们放入消息队列或主题中。这种方法的缺点是,必须将此队列或主题的使用者设计为消除传入消息的重复,因为这种模式只保证至少一次传递。另一个缺点可能是轮询频率导致的延迟。但由于我们已经进入了最终一致的领域,这可能不是什么大问题 如果我们有两个事件存储,并且每当创建一个域事件时,它都会在这两个事件存储上排队。查询端的事件处理程序处理从两个事件存储中弹出的事件 当然,每个事件都应该是幂等的。
但这难道不能解决事件存储作为单一入口点的问题吗?这不是mongodb解决方案,但您是否考虑过利用Redis 5中引入的Streams功能来实现可靠的事件存储。看看这个介绍 我发现它具有一系列丰富的功能,如消息跟踪、消息确认以及轻松提取未确认消息的能力。这肯定有助于实现至少一次消息传递保证。它还支持使用“消费者组”概念对消息进行负载平衡,这有助于扩展处理部分
关于您担心成为单点故障的问题,根据文档,流和消费者信息可以跨节点复制并保存到磁盘(我相信使用常规Redis机制)。这有助于解决单点故障问题。我目前正在考虑将其用于我的一个微服务项目。谢谢Udi!。两个问题:
Bus.Send(new PreparePurchasedProducts())的含义是什么
和总线发布(new PurchaseOrderReceived())代码>?消息未在分派步骤中发布?那么这个括号是什么意思呢?我知道如果调度步骤失败,Db Tx将不会回滚