更新 :このトピックのサポート記事(基本的にはこの投稿のコピー)は、接続のトラブルシューティングドキュメントに移動しました。
Azure IaaSネットワークが約13分のアイドルタイムアウトを強制するという既知の問題があります(経験的に到達しました)。 Azureと協力して、よりユーザーフレンドリーなものにすることができないかどうかを確認していますが、それまでの間、他のユーザーは、問題を回避するようにドライバーオプションを構成することで成功しています。
最大接続アイドル時間
Azureとお客様との共同作業で見つけた最も効果的な回避策は、最大接続アイドル時間を4分未満に設定することでした。ファイアウォールが問題を強制する前に、ドライバーにアイドル状態の接続をリサイクルさせるという考え方です。たとえば、C#ドライバーを使用しているある顧客は、MongoDefaults.MaxConnectionIdleTime
を設定します。 1分で問題が解決しました。
MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(1);
アプリケーションコード自体は変更されていませんが、現在、ドライバーはアイドル状態の接続を積極的にリサイクルしています。結果はサーバーログにも表示されます。アプリのアイドル期間中に多くの接続がチャーンします。
このアプローチの詳細については、関連するmongo-userスレッド、azureでC#ドライバーを使用するSocketExceptionを参照してください。
キープアライブ
ある種のキープアライブを使用して接続のアイドル状態を減らすことで、この問題を回避することもできます。これは、ドライバーが箱から出してすぐにサポートしない限り、通常は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") }
私たちがお手伝いします
もちろん、ご不明な点がございましたら、[email protected]までお気軽にお問い合わせください。