当前位置: 首页 > 面试题库 >

在MongoDB中打开连接的SocketTimeout

禄仲渊
2023-03-14
问题内容

我有一个Java应用程序,它在MongoDB上执行一些聚合,但是有时它会挂起并抛出SocketTimeout异常。异常发生后,应用程序将正常运行(稍等片刻,然后它可能会再次引发异常)。

我刚刚发现这种解释似乎是可能的原因,但不确定。

我启动MongoClient并保持与数据库的连接打开。我不确定这是否可能是一个问题,我应该每次都获取数据库,然后让数据库进行垃圾回收(并关闭连接)。

另一种方法是定期ping Mongo以保持连接池“新鲜”。

使用的客户端是这样的:

public class DbClient {

    private static MongoClient mongoClient;
    private static MongoDatabase db;

    private DbClient() {}

    public static void init() throws Exception {
        mongoClient = new MongoClient();
    }

    public static MongoDatabase getDB() {
        if(mongoClient == null)
            throw new IllegalStateException("Client not initialized!");

        if(db == null) {
            db = mongoClient.getDatabase("my_db");
        }
        return db;
    }
}

这是SocketTimeout的可能原因吗?

这是抛出的异常:

09:20:45.742 [qtp605535417-46] INFO  org.mongodb.driver.connection - Closed connection [connectionId{localValue:16, serverValue:6562}] to myapp.com:27017 because there was a socket exception raised by this connection.
09:20:45.743 [qtp605535417-46] ERROR myapp.service.Api - Error processing request
com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving message
    at com.mongodb.connection.InternalStreamConnection.translateReadException(InternalStreamConnection.java:474) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:225) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.connection.UsageTrackingInternalConnection.receiveMessage(UsageTrackingInternalConnection.java:102) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.connection.DefaultConnectionPool$PooledConnection.receiveMessage(DefaultConnectionPool.java:435) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.connection.CommandProtocol.execute(CommandProtocol.java:112) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:159) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:286) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.connection.DefaultServerConnection.command(DefaultServerConnection.java:173) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:215) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:206) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.operation.CommandOperationHelper.executeWrappedCommandProtocol(CommandOperationHelper.java:112) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.operation.FindOperation$1.call(FindOperation.java:487) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.operation.FindOperation$1.call(FindOperation.java:482) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:239) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:212) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.operation.FindOperation.execute(FindOperation.java:482) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.operation.FindOperation.execute(FindOperation.java:79) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.Mongo.execute(Mongo.java:772) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.Mongo$2.execute(Mongo.java:759) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.OperationIterable.iterator(OperationIterable.java:47) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.FindIterableImpl.iterator(FindIterableImpl.java:143) ~[mongo-java-driver-3.2.2.jar!/:na]
    at myapp.common.db.service.dao.AnalysisMongoImpl.getAnalysis(AnalysisMongoImpl.java:66) ~[common-0.2.0-SNAPSHOT.jar!/:na]
    at myapp.common.db.service.AnalysisServiceImpl.getAnalysis(AnalysisServiceImpl.java:31) ~[common-0.2.0-SNAPSHOT.jar!/:na]
    at myapp.aggregator.service.Api$1.handle(Api.java:88) ~[aggregator-0.2.0-SNAPSHOT.jar!/:na]
    at spark.webserver.MatcherFilter.doFilter(MatcherFilter.java:139) [spark-core-1.1.1.jar!/:na]
    at spark.webserver.JettyHandler.doHandle(JettyHandler.java:54) [spark-core-1.1.1.jar!/:na]
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:179) [jetty-server-9.0.2.v20130417.jar!/:9.0.2.v20130417]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:136) [jetty-server-9.0.2.v20130417.jar!/:9.0.2.v20130417]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.0.2.v20130417.jar!/:9.0.2.v20130417]
    at org.eclipse.jetty.server.Server.handle(Server.java:451) [jetty-server-9.0.2.v20130417.jar!/:9.0.2.v20130417]
    at org.eclipse.jetty.server.HttpChannel.run(HttpChannel.java:252) [jetty-server-9.0.2.v20130417.jar!/:9.0.2.v20130417]
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:266) [jetty-server-9.0.2.v20130417.jar!/:9.0.2.v20130417]
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.java:240) [jetty-io-9.0.2.v20130417.jar!/:9.0.2.v20130417]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:596) [jetty-util-9.0.2.v20130417.jar!/:9.0.2.v20130417]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:527) [jetty-util-9.0.2.v20130417.jar!/:9.0.2.v20130417]
    at java.lang.Thread.run(Thread.java:745) [na:1.7.0_95]
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method) ~[na:1.7.0_95]
    at java.net.SocketInputStream.read(SocketInputStream.java:152) ~[na:1.7.0_95]
    at java.net.SocketInputStream.read(SocketInputStream.java:122) ~[na:1.7.0_95]
    at com.mongodb.connection.SocketStream.read(SocketStream.java:85) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:491) ~[mongo-java-driver-3.2.2.jar!/:na]
    at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:221) ~[mongo-java-driver-3.2.2.jar!/:na]
    ... 34 common frames omitted

问题答案:

经过几次尝试,我发现这是Azure的Load
Balancer的问题

闲置60秒钟后,它将断开所有未决的TCP连接。

进一步挖掘之后,我发现了MongoDB诊断常见问题解答的这篇文章,并将tcp keepalive设置为120s:

sudo sysctl -w net.ipv4.tcp_keepalive_time=<value>

并且我还将MongoClient的socketKeepAlive设置为true:

MongoClientOptions.Builder options = MongoClientOptions.builder();
options.socketKeepAlive(true);
mongoClient = new MongoClient(mongoAddress, options.build());

这些修复之后,问题似乎消失了!



 类似资料:
  • 据我所知,每个应用程序只需要一个MongoClient实例,因此为了方便起见,我使用此方法扩展了HttpServlet: 当我运行这个代码时,它工作得很好,我连接并做我需要做的工作,但每次我运行这个特定的Servlet时,它似乎都会不断地打开与mongoDB的新连接: 在页面中我正在这样做: 然后运行一个简单的查询。有人能解释为什么我有这么多新的联系吗?我也见过这个蒙哥。霍尔德班。这是我现在做的事

  • 我有一个grails应用程序,它使用quartz每20秒循环一次域类。 每次执行quartz作业时,都会与Mongo建立另一个连接。由于某种原因,前几次没有关闭,因此在11次连接后,作业停止工作(连接超时)。我尝试了另一种方法,通过在操作中调用服务方法来调用URL,但连接数仍在不断增加。当我在没有运行Quartz作业的情况下反复调用URL时,只会创建4个新连接,不再有。 你知道怎么做吗? Grai

  • 问题内容: 我的程序需要打开大量连接(Mongo)。我得到了错误: 打开的连接太多,无法再打开 在819个连接之后。我已经知道我们可以增加此限制。但这不是我的想法。我正在考虑关闭MongoClient对象,然后在800个连接后再次创建一个新对象。 我的想法是使用新的mongoClient对象将关闭所有连接,并且当我再次启动/创建它时,连接将再次打开直到800。因此不会给出错误。(让我知道此方法是否

  • 我的主文件app.js连接到userDB我想添加第二个数据库postsDB 常量mongoose=require(“mongoose”); 常量app=express(); mongoose.set(“UseCreateIndex”,true);mongoose.set(“UseUnifiedTopology”,true); Mongoose.connect(“MongoDB://localhos

  • 问题内容: 在许多使用MongoDB的入门示例中,您将看到类似以下的代码: 如果MongoDB与任何其他数据库系统一样,并且操作通常在时间上很昂贵。 所以,我的问题是这样的:只需执行一次,将返回值分配给某个全局模块即可,模块中具有各种功能就可以进行各种与数据库相关的工作(将文档插入集合,更新文档等)。 ),然后由应用程序的其他部分调用它们(从而重新使用该值),然后,在应用程序完成后,才执行。 换句

  • 问题内容: 我正在尝试在Python中建立安全的套接字连接,而使用SSL有点麻烦。我已经找到一些有关如何与SSL建立连接的代码示例,但它们都涉及密钥文件。我尝试连接的服务器不需要接收任何密钥或证书。我的问题是,我该如何实质上包装带有SSL的python套接字连接。我知道我应该使用的密码是,协议是。这就是我一直在尝试的: 运行此代码时,没有任何错误,但响应为空。当尝试在命令行中调试此代码时,通过在终