在ChangeStream中收到第一个文档之前,使用MongoDB Java驱动程序获取resume令牌?
这个问题与How do I resume a MongoDB ChangeStream at the first document and not just changes after I start listening类似,但适用于Java驱动程序。如果需要确保所有文档至少处理一次,那么这一点至关重要
例如,假设我有一个变更流(C),它订阅文档并根据每个文档的内容发送电子邮件。但是,如果电子邮件发送失败或服务器在发送电子邮件之前崩溃,则恢复令牌(R)将不会被持久化。当应用程序再次启动时,它将在没有简历令牌的情况下“监视”,因此文档将丢失,并且不会发送电子邮件
是否有一种受支持的方法可以在收到第一个变更文档之前获取ChangeStream的恢复令牌,以缓解上述问题
从MongoDB specification可以看出,这必须由驱动程序支持:
Drivers MUST expose a mechanism to retrieve the same resume token that would be used to automatically resume.
但我似乎找不到使用JavaAPI实现这一点的方法。这是可能的还是有推荐的解决方法
请注意,我非常希望而不是使用基于时间戳的startAtOperationTime
,因为时间是脆弱的,并且服务器和客户端上的时钟都可能更改
# 1 楼答案
在实现规范“必须公开恢复令牌”规定的4.2兼容驱动程序中,每次更改流执行getMore时,都会发生以下两种情况之一:
我记得在Java change streams中有一个tryNext方法,您需要调用它来检索postBatchResumeToken,而不阻塞应用程序。检索当前恢复令牌(与文档或postBatchResumeToken关联的令牌)的机制是特定于驱动程序的
https://mongodb.github.io/mongo-java-driver/4.0/apidocs/mongodb-driver-sync/com/mongodb/client/MongoChangeStreamCursor.html是我能找到的最接近的文档,除了我相信你会使用tryNext而不是next,如果tryNext没有返回任何文档,你仍然会阅读当前的简历标记,以提升你在变更流中的位置
https://docs.mongodb.com/ruby-driver/master/tutorials/ruby-driver-change-streams/#resuming-a-change-stream通常对于恢复令牌跟踪可能很有帮助,尽管这不包括需要的try_next(Ruby驱动程序也实现了它)
这将允许您在收到任何文档之前正确地恢复更改流。在处理文档之后,您需要存储简历标记,因此您需要足够快地取得进展,以免从oplog上掉下来,但postBatchResumeToken可以处理长时间没有任何更改而不会从oplog上掉下来的情况
如果你没有任何恢复标记,你仍然需要在一开始就以时间戳启动变更流,我希望你使用的方法是startAtOperationTime。如果您的驱动程序公开了当前clusterTime,您可能会提供驱动程序跟踪的当前clusterTime