【问题标题】:Why do I get a socket timeout the first time I hit the database after a recompile?为什么重新编译后第一次访问数据库时会出现套接字超时?
【发布时间】:2012-06-13 14:45:59
【问题描述】:

我使用的是 playframework 2.0,每次重新编译后,我的应用程序第一次尝试访问数据库时都会出现套接字超时。我直接使用 Mongo 驱动程序。这是一个典型的堆栈跟踪:

play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[Network: can't call something : ds031907.mongolab.com/107.21.99.26:31907/heroku_app4620908]]
at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:82)     [play_2.9.1.jar:2.0]
at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:63) [play_2.9.1.jar:2.0]
at akka.actor.Actor$class.apply(Actor.scala:290) [akka-actor.jar:2.0]
at play.core.ActionInvoker.apply(Invoker.scala:61) [play_2.9.1.jar:2.0]
at akka.actor.ActorCell.invoke(ActorCell.scala:617) [akka-actor.jar:2.0]
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:179) [akka-actor.jar:2.0]
Caused by: com.mongodb.MongoException$Network: can't call something : ds031907.mongolab.com/107.21.99.26:31907/heroku_app4620908
at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:227) ~[mongo-java-driver-2.7.3.jar:na]
at com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:305) ~[mongo-java-driver-2.7.3.jar:na]
at com.mongodb.DBCollection.findOne(DBCollection.java:647) ~[mongo-java-driver-2.7.3.jar:na]
at com.mongodb.DBCollection.findOne(DBCollection.java:626) ~[mongo-java-driver-2.7.3.jar:na]
at models.daos.ModuleDAO.findPublishedModuleById(ModuleDAO.java:445) ~[classes/:na]
at controllers.LearnController.viewModule(LearnController.java:31) ~[classes/:2.0]
Caused by: java.net.SocketException: Operation timed out
at java.net.SocketInputStream.socketRead0(Native Method) ~[na:1.6.0_31]
at java.net.SocketInputStream.read(SocketInputStream.java:129) ~[na:1.6.0_31]
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218) ~[na:1.6.0_31]
at java.io.BufferedInputStream.read1(BufferedInputStream.java:258) ~[na:1.6.0_31]
at java.io.BufferedInputStream.read(BufferedInputStream.java:317) ~[na:1.6.0_31]
at org.bson.io.Bits.readFully(Bits.java:35) ~[mongo-java-driver-2.7.3.jar:na]

这是我的初始化代码:

public static DB getDB(){
    ensureMongo();
    DB db = mongo.getDB(MOJULO_DB);
    if(!db.isAuthenticated()){
        db.authenticate(MONGO_USERNAME, MONGO_PASSWORD);
        if(db.isAuthenticated())
            System.out.println("authentication success on db:" +  db.getName());
        else
            System.out.println("db authentication failure");
    }
    return db;
}
private static synchronized void ensureMongo(){
    if(mongo == null){
        try{
            MongoURI mongoURI = new MongoURI(MONGO_URI);
            mongo = new Mongo(mongoURI);
            DB db = mongo.getDB(MOJULO_DB);
            db.command("ping");
        }catch(UnknownHostException ex){
            mongo = null;
            System.out.println("failed to connect to mongo");
            ex.printStackTrace();
        }
    }
}
public static void disconnect(){
    System.out.println("disconnecting from mongo");
    if(mongo != null){
        mongo.close();
        mongo = null;
    }
}

我使用类外部的getDB 方法来获取数据库。该方法旨在创建不存在的 mongo 单例。我总是得到验证成功 println,但是在第一次访问数据库时,我得到了套接字超时异常。

在我的 Global 类中,当应用程序关闭时,我关闭了与数据库的连接。

@Override
public void onStop(Application app) {
    System.out.println("stop");
    Logger.info("Application shutdown...");
    DBManager.disconnect();
} 

有什么想法吗?

【问题讨论】:

  • 这可能与在部署时获取新的类加载器有关。当您部署和创建另一个 mongo 实例时,您可能应该丢弃该实例。此外,在代码中,在 mongo = new Mongo(mongoURI); 之后,您永远不会在 getDB() 方法中真正连接到 mongo你应该添加一些实际使用数据库的东西,比如 db.command("ping")。
  • 我在onStop(Application app) 方法中添加了对mongo.close() 的调用。我还在初始化 mongo 单例后立即添加了一个 ping。但仍然没有运气。
  • 我在问题中添加了 ping 代码和我的 onClose 方法。
  • 代码对我来说看起来不错,我看不出是什么导致了套接字超时......对不起!

标签: mongodb playframework-2.0 mongodb-java


【解决方案1】:

我不是 MongoDB 专家,但可以看到与其他数据库连接的相似之处。 你的连接是如何配置的? 当您第一次尝试使用数据库连接(查找方法)时,它看起来(对我来说)可能正在尝试加载所有映射/数据库和表定义/其他所有内容。 在您的 ensureMongo() 方法中运行一个简单的数据库查询可能会更好,以允许系统重新初始化它需要的所有内容(您可能需要在此方法上设置更长的超时时间)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    • 2014-12-18
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多