我有一个系统,它使用mongoDB作为持久性,使用RabbitMQ作为消息代理。我面临一个挑战,我只想为事务性发件箱发布失败场景实现RabbitMQ。我不确定这是否可能,因为我也有使用相同mongoDB持久性的使用者,所以当我编写一个代码,涵盖RabbitMQ发布失败场景的事务性发件箱时,发布的消息会在mongoDB commitTransaction之前到达消费者,因此由于延迟,我的使用者无法在mongoDB中找到消息。
我的代码如下所示;
1-开始会话事务
2-使用会话插入文档(因此在我调用commit之前它不会持久)
3-发布rabbitMQ
4-如果成功,commitTransaction
5-如果错误,请将会话插入发件箱文档,而不是commitTransaction。
6-如果mongoDB abortTransaction出了问题(如果发布成功,mongoDB失败,我的消费者首先检查mongoDB是否存在,如果不存在,什么也不做)。
因此,问题是在这里,消息到达消费者的时间早于mongoDB持久性,您有建议任何解决方案来解决我的问题吗?
发布于 2021-09-02 09:46:23
所以我想和大家分享我的解决方案。
不幸的是,不可能只为失败场景实现事务性发件箱模式。
我决定的是,创建一个围绕高可用性的体系结构;
MongoDB作为高可用持久性,RabbitMQ作为高可用消息代理。
我删除了之前编码的所有会话事务,并实现了立即写入和发布。
在最坏的情况下:
1-插入文件(成功)
2- rabbitmq发布(失败)
3-插入发件箱(失败)
我将拥有的是,在我的蒙戈未发表的文件。即使在最坏的情况下,我也可以用另一个应用程序重新发布来自MongoDB的消息,但是我不会编写该应用程序,直到我面对这种情况,因为我们不能涵盖代码中的每个失败场景。因此,我们的消息代理或持久性必须是高可用性的。
发布于 2021-08-30 16:41:20
据我所知,https://microservices.io/patterns/data/transactional-outbox.html图片中概述的体系结构直接映射到MongoDB变更流:
可以重试消息代理的发布,如果出现任何错误,也可以重新尝试更改流读取。您需要正确跟踪简历标记,例如,请参见https://docs.mongodb.com/ruby-driver/master/reference/change-streams/#resuming-a-change-stream。
这种办法的局限性:
您所建议的解决方案有一组不同的问题,例如,在提交通知之前先发布通知,这样就可以发现通知处理器无法找到它从message获得的文档的可能性。
https://stackoverflow.com/questions/68985499
复制相似问题