サーバー スタックの関連部分については、以下を実行しています。
- NGINX 1.2.3
- PHP-FPM 5.3.10 と PECL mongo 1.2.12
- モンゴDB 2.0.7
- CentOS 6.2
MongoDB サーバーがなくなると、奇妙ではあるが予測可能な動作が発生します (クラッシュ、強制終了など)。try/catch
接続コードの周りにブロックがあっても、つまり:
try
{
$mdb = new Mongo('mongodb://localhost:27017');
}
catch (MongoConnectionException $e)
{
die( $e->getMessage() );
}
$db = $mdb->selectDB('collection_name');
どの PHP-FPM ワーカーが既に mongo に接続しているかに応じて、接続状態がキャッシュされ、$mdb
接続ハンドラーを使用できないため、さらなる例外が未処理になります。問題はtry
、php-fpm がダイ/リスポーンを処理するときに、最大 15 分後まで、かなりの時間、一貫して失敗しないことです。
基本的に、mongo にまだ接続されていないワーカーをヒットすると、上記の die メッセージが表示され、接続されているワーカーに接続すると、$mdb->selectDB('collection_name');
catch が実行されないため、未処理の例外が発生します。
PHP が単一プロセスの場合、つまり mod_php を使用した Apache 経由の場合、この動作は発生しません。後世のためだけに、Apache/mod_php に戻るという選択肢は現時点ではありません。
この動作を修正する方法はありますか? 異なる php-fpm プロセス間で接続状態が矛盾することは望ましくありません。
編集: この点でドライバーが修正されるのを待っている間、私の現在の回避策は、ドライバーがリクエストを処理できるかどうかを判断するために簡単なポーリングを行い、MongoDB ライブラリをロードするかロードしないか、接続できない場合はクエリを実行することです。 /クエリ:
try
{
// connect
$mongo = new Mongo("mongodb://localhost:27017");
// try to do anything with connection handle
try
{
$mongo->YOUR_DB->YOUR_COLLECTION->findOne();
$mongo->close();
define('MONGO_STATE', TRUE);
}
catch(MongoCursorException $e)
{
$mongo->close();
error_log('Error connecting to MongoDB: ' . $e->getMessage() );
define('MONGO_STATE', FALSE);
}
}
catch(MongoConnectionException $e)
{
error_log('Error connecting to MongoDB: ' . $e->getMessage() );
define('MONGO_STATE', FALSE);
}