有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在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) 个答案

  1. # 1 楼答案

    在实现规范“必须公开恢复令牌”规定的4.2兼容驱动程序中,每次更改流执行getMore时,都会发生以下两种情况之一:

    • 返回至少一个文档,每个文档都包含该文档的简历标记,或者
    • 没有返回任何文档,在这种情况下,postBatchResumeToken仍然由4.0.7+服务器提供

    我记得在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