3

私はplayframework2.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クラスの外部からメソッドを使用してdbを取得します。このメソッドは、mongoシングルトンが存在しない場合に作成することを目的としています。私は常に認証成功printlnを取得しますが、データベースへの最初のヒットで、ソケットタイムアウト例外が発生します。

Globalクラスでは、アプリケーションを閉じたときにデータベースへの接続を閉じます。

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

何か案は?

4

1 に答える 1

0

私は MongoDB の専門家ではありませんが、他の DB 接続との類似性を確認できます。接続はどのように構成されていますか? 初めてDB接続(findメソッド)を使用しようとすると、すべてのマッピング/ DBおよびテーブル定義/その他すべてをロードしようとしているように見えます。システムが必要なものをすべて再初期化できるように、ensureMongo() メソッドで単純な DB クエリを実行する方がよい場合があります (このメソッドでより長いタイムアウトを設定する必要がある場合があります)。

于 2012-07-02T13:56:20.443 に答える