有 Java 编程相关的问题?

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

java MongoCursorNotFoundException查询失败,错误代码为5

我们得到以下例外情况

com.mongodb.MongoCursorNotFoundException: Query failed with error code -5 and error message 'Cursor 43249415092 not found on server xx.xx.xx.xx:27017' 
        at com.mongodb.connection.GetMoreProtocol.receiveMessage(GetMoreProtocol.java:115)
        at com.mongodb.connection.GetMoreProtocol.execute(GetMoreProtocol.java:68)
        at com.mongodb.connection.GetMoreProtocol.execute(GetMoreProtocol.java:37)
        at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:155)
        at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:219)
        at com.mongodb.connection.DefaultServerConnection.getMore(DefaultServerConnection.java:194)
        at com.mongodb.operation.QueryBatchCursor.getMore(QueryBatchCursor.java:197)
        at com.mongodb.operation.QueryBatchCursor.hasNext(QueryBatchCursor.java:93)
        at com.mongodb.MongoBatchCursorAdapter.hasNext(MongoBatchCursorAdapter.java:46)
        at com.mongodb.DBCursor.hasNext(DBCursor.java:152)

我们无法找到根本原因,因为我们很少遇到这种异常

We also observed that the application is unable to read from cursor but no exception is thrown.

在没有抛出异常的情况下,我们进行了线程转储,发现从mongo读取的线程处于可运行状态

java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:152)
        at java.net.SocketInputStream.read(SocketInputStream.java:122)
        at com.mongodb.connection.SocketStream.read(SocketStream.java:85)
        at com.mongodb.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:503)
        at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:221)
        at com.mongodb.connection.UsageTrackingInternalConnection.receiveMessage(UsageTrackingInternalConnection.java:102)
        at com.mongodb.connection.DefaultConnectionPool$PooledConnection.receiveMessage(DefaultConnectionPool.java:416)
        at com.mongodb.connection.GetMoreProtocol.receiveMessage(GetMoreProtocol.java:112)
        at com.mongodb.connection.GetMoreProtocol.execute(GetMoreProtocol.java:68)
        at com.mongodb.connection.GetMoreProtocol.execute(GetMoreProtocol.java:37)
        at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:155)
        at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:219)
        at com.mongodb.connection.DefaultServerConnection.getMore(DefaultServerConnection.java:194)
        at com.mongodb.operation.QueryBatchCursor.getMore(QueryBatchCursor.java:197)
        at com.mongodb.operation.QueryBatchCursor.hasNext(QueryBatchCursor.java:93)
        at com.mongodb.MongoBatchCursorAdapter.hasNext(MongoBatchCursorAdapter.java:46)
        at com.mongodb.DBCursor.hasNext(DBCursor.java:152)

请帮助我找到这个问题的根本原因


共 (1) 个答案

  1. # 1 楼答案

    最近,我遇到了同样的问题。经过长时间的研究,我找到了答案。在我的场景中,我有4个mongos,它们在负载平衡之后(随机返回mongos IP地址)。在我的连接字符串中,我使用负载平衡主机作为mongoDB集群的地址

    当应用程序启动时,mongoDB驱动程序会创建一个带有连接池的server。在连接池中,有来自4个mongos的混合连接

    当您查询一个大数据(比batchSize大)时,第一批数据来自mongos a,然后当推送下一批请求时,连接可能会连接到mongos B/C或D(source code)。他们当然找不到光标。因此,抛出MongoCursorNotFoundException

    怎么处理

    不要在连接字符串中使用平衡主机。改用所有mongos IP地址。让mongoDB驱动程序自己来平衡请求

    错了mongodb://your.load.balance.host:27000/yourDB?connectTimeoutMS=60000&minPoolSize=100&maxPoolSize=100&waitqueuemultiple=20&waitqueuetimeoutms=60000

    mongodb://10.0.0.1:27017,10.0.0.2:27017,10.0.0.3:27017,10.0.0.4:27017/yourDB?connectTimeoutMS=60000&minPoolSize=100&maxPoolSize=100&waitqueuemultiple=20&waitqueuetimeoutms=60000

    有一个更好的解决方案:您可以为每个mongos配置一个唯一的专用主机,然后修改右侧的连接字符串:用该主机替换IP地址