29

nodejsとmongoDBを使用していますが、接続に問題があります。

まあ、実際には「ウェイク」の問題です!それは完全にうまく接続します-超高速で、私は一般的に結果に満足しています。

私の問題:接続をしばらく使用しないと(時間枠が5分以上変化するため、しばらくの間)、停止しているように見えます。切断イベントが発生しません-ハングするだけです。

最終的に、エラーのような応答が返されます:[* .mongolab.comに接続できませんでした:*]-(* =マスクされた値)

アプリをすばやく再起動すると、接続が再び正常になります。時々、アプリを再起動しないと、更新して問題なく再接続できます。

これが「ウェイク」の問題だと思う理由です。

コードの大まかな概要:

私はコードを含めていません-私はそれが必要だとは思いません。動作します(接続ドロップアウトは別として)

注意事項:「接続」は1つだけです。閉じないでください。私は決して再開しません。

私はマングース、socketioを使用しています。

/* constants */

var mongoConnect = 'myworkingconnectionstring-includingDBname';


/* includes */

/* settings */

/* Schema */

var db = mongoose.connect(mongoConnect);

    /* Socketio */

io.configure(function (){
    io.set('authorization', function (handshakeData, callback) {

    });
});

io.sockets.on('connection', function (socket) {

});//sockets

io.sockets.on('disconnect', function(socket) {
    console.log('socket disconnection')
});

/* The Routing */

app.post('/login', function(req, res){  

});

app.get('/invited', function(req, res){

});

app.get('/', function(req, res){

});

app.get('/logout', function(req, res){

});

app.get('/error', function(req, res){

});

server.listen(port);
console.log('Listening on port '+port);

db.connection.on('error', function(err) {
    console.log("DB connection Error: "+err);
});
db.connection.on('open', function() {
    console.log("DB connected");
});
db.connection.on('close', function(str) {
    console.log("DB disconnected: "+str);
});

私はここでさまざまな構成を試しました。たとえば、常に開いたり閉じたりします。ただし、一般的なコンセンサスは、1つのオープンラッピングを使用する場合と同じように行うことです。??

接続のステータスをチェックし続ける接続テスターを試しました...これはすべて問題ないように見えますが、問題は引き続き発生します。

私は初日からこの問題を抱えています。私は常にMongoLabでMongoDBをホストしてきました。この問題はローカルホストではさらに悪化しているようです。しかし、私はまだAzureとnodejit.suで問題を抱えています。

それはどこでも起こります-それは私、MongoDB、またはmongolabでなければなりません。

ちなみに、私もphpドライバーで同様の経験をしました。(ただし、これがnodejs上にあることを確認するため)

誰かが「これは正常だ」と言ったとしても、助けがあれば素晴らしいでしょう。

前もって感謝します

ロブ

4

6 に答える 6

31

更新: このトピックに関するサポート記事 (基本的にはこの投稿のコピー) は、接続のトラブルシューティング ドキュメントに移動しました。

Azure IaaS ネットワークでは約 13 分のアイドル タイムアウトが適用されるという既知の問題があります (経験的に到達)。私たちは Azure と協力して、ユーザー フレンドリーにすることができないかどうかを確認していますが、それまでの間、ドライバー オプションを構成して問題を回避することで成功した他のユーザーもいます。

最大接続アイドル時間

Azure およびお客様と協力して見つけた最も効果的な回避策は、最大接続アイドル時間を 4 分未満に設定することです。アイデアは、ファイアウォールが問題を強制する前に、ドライバーがアイドル状態の接続をリサイクルするようにすることです。たとえば、C# ドライバーを使用しているある顧客は、MongoDefaults.MaxConnectionIdleTime1 分に設定して問題を解決しました。

MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1);

アプリケーション コード自体は変更されていませんが、バックグラウンドでドライバーがアイドル状態の接続を積極的にリサイクルしています。結果は、サーバー ログにも表示されます。アプリのアイドル期間中に多数の接続チャーンが発生しています。

関連する mongo-user スレッドSocketException using C# driver on azureに、このアプローチの詳細が記載されています。

生き続ける

ある種のkeepaliveを使用して接続のアイドル状態を減らすことで、この問題を回避することもできます。これは、通常はTCP キープアライブを利用して、ドライバーがそのままでサポートしていない限り、実装するのが少し難しいです。独自のロールを作成する必要がある場合は、アイドル状態の接続を数分ごとにプールから取得し、単純で安価なコマンド (おそらくping ) を発行してください。

切断の処理

積極的なファイアウォールのセットアップがなくても、切断が時々発生する可能性があります。本番環境に入る前に、それらを正しく処理する必要があります。

まず、必ず自動再接続を有効にしてください。その方法はドライバーによって異なりますが、ドライバーが接続不良のために操作が失敗したことを検出すると、自動再接続をオンにすると、ドライバーに再接続を試みるように指示します。

しかし、これで問題が完全に解決するわけではありません。再接続をトリガーした失敗した操作をどうするかという問題がまだ残っています。自動再接続は、失敗した操作を自動的に再試行しません。特に書き込みの場合、これは危険です。そのため、通常は例外がスローされ、アプリはそれを処理するよう求められます。多くの場合、読み取りの再試行は簡単です。ただし、書き込みの再試行は慎重に検討する必要があります。

以下の mongo シェル セッションは、この問題を示しています。mongo シェルでは、デフォルトで自動再接続が有効になっています。という名前のコレクションにドキュメントを挿入し、stuffそのコレクション内のすべてのドキュメントを検索します。次に、タイマーを 30 分にセットして、同じ検索を再試行しました。失敗しましたが、シェルは自動的に再接続し、すぐに検索を再試行すると、期待どおりに機能しました。

% mongo ds012345.mongolab.com:12345/mydatabase -u *** -p *** 
MongoDB shell version: 2.2.2 
connecting to: ds012345.mongolab.com:12345/mydatabase 
> db.stuff.insert({}) 
> db.stuff.find() 
{ "_id" : ObjectId("50f9b77c27b2e67041fd2245") } 
> db.stuff.find() 
Fri Jan 18 13:29:28 Socket recv() errno:60 Operation timed out 192.168.1.111:12345 
Fri Jan 18 13:29:28 SocketException: remote: 192.168.1.111:12345 error: 9001 socket exception [1] server [192.168.1.111:12345] 
Fri Jan 18 13:29:28 DBClientCursor::init call() failed 
Fri Jan 18 13:29:28 query failed : mydatabase.stuff {} to: ds012345.mongolab.com:12345 
Error: error doing query: failed 
Fri Jan 18 13:29:28 trying reconnect to ds012345.mongolab.com:12345 
Fri Jan 18 13:29:28 reconnect ds012345.mongolab.com:12345 ok 
> db.stuff.find() 
{ "_id" : ObjectId("50f9b77c27b2e67041fd2245") }

私たちは助けるためにここにいます

もちろん、ご不明な点がございましたら、support@mongolab.com までお気軽にお問い合わせください。私たちは助けるためにここにいます。

于 2013-01-18T23:42:05.837 に答える
20

すべての助けてくれてありがとう-私はローカルホストとライブサーバーの両方でこの問題を解決することができました。

これが私の現在機能している接続コードです:

var MONGO = {
    username: "username",
    password: "pa55W0rd!",
    server: '******.mongolab.com',
    port: '*****',
    db: 'dbname',
    connectionString: function(){
        return 'mongodb://'+this.username+':'+this.password+'@'+this.server+':'+this.port+'/'+this.db;
    },
    options: {
        server:{
            auto_reconnect: true,
            socketOptions:{
                connectTimeoutMS:3600000,
                keepAlive:3600000,
                socketTimeoutMS:3600000
            }
        }
    }
};

var db = mongoose.createConnection(MONGO.connectionString(), MONGO.options);

db.on('error', function(err) {
    console.log("DB connection Error: "+err);
});
db.on('open', function() {
    console.log("DB connected");
});
db.on('close', function(str) {
    console.log("DB disconnected: "+str);
});

最大の変更は、「接続」ではなく「createConnection」を使用することだったと思います。以前はこれを使用していましたが、オプションが役立つかもしれません。この記事は大いに役立ちましたhttp://journal.michaelahlers.org/2012/12/building-with-nodejs-persistence.html

正直なところ、なぜこれらのオプションを追加したのかよくわかりません-@jareedが述べたように、「MaxConnectionIdleTime」で成功している人もいますが、私が見る限り、javascriptドライバーはそうではありませんこのオプションがあります:これは、動作を複製しようとした私の試みでした。

これまでのところ良いです-これが誰かを助けることを願っています。

更新:2013年4月18日 注、これは異なる設定の2番目のアプリです

今、私はこれを解決したと思いましたが、問題は最近別のアプリで再び醜い頭になりました-同じ接続コードで。混乱している!!!

ただし、設定は少し異なります…</ p>

この新しいアプリは、IISNodeを使用してWindowsボックスで実行されていました。 私はこれが最初は重要だとは思っていませんでした。

Azure(@jareed)のmongoに問題がある可能性があることを読んだので、DBをAWSに移動しましたが、それでも問題は解決しませんでした。

それで、私はそのオプションオブジェクトでもう一度遊んで、それについてかなり多くを読み始めました。この結論に達しました:

options: {
    server:{
        auto_reconnect: true,
        poolSize: 10,
        socketOptions:{
            keepAlive: 1
        }
    },
    db: {
        numberOfRetries: 10,
        retryMiliSeconds: 1000
    }
}

それは、私の元のオプションオブジェクトが私が述べていることよりも少し教育を受けていました。しかし、それでも良くありません。

さて、何らかの理由で私はそのウィンドウボックスを降りなければなりませんでした(モジュールがコンパイルされていないことに関係しています)-それを動作させるためにもう1週間費やすよりも移動する方が簡単でした。

そこで、アプリをnodejitsuに移動しました。低く、私の接続が生き続けているのを見てください!ウー!

それで…。これはどういう意味ですか…わかりません!私が知っているのは、これらのオプションはノードジツで機能するようだということです…。私のため。

IISNodeは、アプリを存続させるために、ある種の「永遠の」スクリプトを使用していると思います。公平を期すために、これを開始するためにアプリがクラッシュすることはありませんが、絶えず更新されるある種の「アプリサイクル」が必要だと思います。これにより、継続的デプロイを実行できます(ftpコードをアップする必要はありません)。アプリを再起動します)-おそらくこれが要因です。しかし、私は今推測しているだけです。

もちろん、これはすべて今を意味します、これは解決されていません。それはまだ解決されていません。それは私のセットアップで私のためにちょうど解決されました。

于 2013-01-19T20:21:37.613 に答える
6

この問題がまだ残っている人へのいくつかの推奨事項:

  1. node.js に最新の mongodb クライアントを使用していることを確認してください。v1.2.x から v1.3.10 (今日の最新版) に移行したときに、この領域が大幅に改善されていることに気付きました。

  2. オプション オブジェクトを MongoClient.connect に渡すことができます。Azure から MongoLab に接続するときは、次のオプションが役に立ちました。

    options = { db: {}, server: { auto_reconnect: true, socketOptions: {keepAlive: 1} }, replSet: {}, mongos: {} };

    MongoClient.connect(dbUrl, options, function(err, dbConn) { // あなたのコード });

  3. より信頼できると思われる「閉じる」イベントの処理方法について説明しているこの他の回答を参照してください。https://stackoverflow.com/a/20690008/446681

于 2013-06-27T02:49:48.837 に答える
1

次のようにオプションを有効にしauto_reconnect Serverます。

var db = mongoose.connect(mongoConnect, {server: {auto_reconnect: true}});

ここで開いている接続は、実際には (デフォルトで) 5 つの接続のプールであるため、接続して開いたままにしておくのは正しいことです。私の推測では、mongolab との接続が断続的に失われ、それが発生すると接続が切断されます。うまくいけば、有効にすることでそれがauto_reconnect解決します。

于 2012-12-22T03:21:27.693 に答える
0

MongoDB から定期的に切断されるという同様の問題がありました。2つのことを行うと修正されました:

  1. コンピューターがスリープ状態にならないようにしてください (ネットワーク接続が切断されます)。
  2. ルーター/ファイアウォールをバイパスします (または、適切に構成します。これはまだ方法がわかりません)。
于 2013-01-16T17:46:29.050 に答える