1

对于我们服务器堆栈的相关部分,我们正在运行:

  • NGINX 1.2.3
  • PHP-FPM 5.3.10 和 PECL mongo 1.2.12
  • MongoDB 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');

根据已经连接到 mongo 的 PHP-FPM 工作人员,连接状态被缓存,导致进一步的异常未处理,因为$mdb无法使用连接处理程序。令人不安的是,在try相当长的一段时间内,最多 15 分钟后,当 php-fpm 进程死亡/重生时——我假设——时,它并没有持续失败。

本质上,行为是,当您遇到尚未连接到 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);
}
4

1 回答 1

2

PHP mongo 驱动程序连接代码在 1.3 版本中进行了大修,在撰写本文时目前处于 beta2 版本。根据您的描述,您的问题可能会通过以下修复得到解决:

https://jira.mongodb.org/browse/PHP-158

https://jira.mongodb.org/browse/PHP-465

发布后,您将能够在此处查看完整的修复列表:

https://jira.mongodb.org/browse/PHP/fixforversion/10499

或者,也可以在PECL 网站上。如果您可以测试 1.3 并确认您的问题仍然存在,那么我相信驱动程序开发人员很乐意在 1.3.0 发布之前收到您的来信,特别是如果它很容易重现的话。

于 2012-09-15T13:35:27.360 回答