PHP - MongoClient连接堆叠,而不是关闭

时间:2014-02-26 15:02:48

标签: php mongodb connection-pooling

我有一个类从Mongo数据库中提取和聚合数据。这一切都正常......我在同一个连接下(在同一个类中)为连接运行了多个查询。但是,每次刷新页面时,都会打开一个新连接...我可以在我的mongod输出中看到这个:

[initandlisten] connection accepted from 127.0.0.1:46770 #12 (6 connections now open)

我看到每次页面刷新时都会计数。我认为这应该没问题;然而,连接似乎永远不会关闭

一段时间后,连接/锁在Mongo中占用了太多内存,我无法再运行查询。

这个开发环境是32位版本的Mongo,所以我不知道这是否只是因为这个而发生。 (我们的prod env是64位,我现在无法改变dev env。)

我的问题是:在为特定用户提出所有查询后,我是否应该关闭连接?我应该如何处理连接池?

服务类:

class MongoService{
    protected $mongoServer;
    public function setSpokenlayerMongoServer($mongoServer)
    { $this->mongoServer = $mongoServer; }

    protected $mongoUser;
    public function setSpokenlayerMongoUser($mongoUser)
    { $this->mongoUser = $mongoUser; }

    protected $mongoPassword;
    public function setSpokenlayerMongoPassword($mongoPassword)
    { $this->mongoPassword = $mongoPassword; }

    protected $conn;
    public function setServiceConnection($conn)
    { $this->conn = $conn; }

    public function connect(){
        try {
            $this->conn = $this->getMongoClient();
        } catch(Exception $e) {
            /* Can't connect to MongoDB! */
            // logException($e);
            die("Can't do anything :(");
        }
    }

    public function getDatabase($name){
        if(!isset($this->conn)){
            $this->connect();
        }
        return $this->conn->$name;
    }

    protected function getMongoClient($retry = 3) {
        $connectString= "mongodb://".$this->mongoUser.":".$this->mongoPassword."@". $this->mongoServer."";
        try {
            return new MongoClient($connectString);
        } catch(Exception $e) {
            /* Log the exception so we can look into why mongod failed later */
            // logException($e);
        }
        if ($retry > 0) {
            return $this->getMongoClient(--$retry);
        }
        throw new Exception("I've tried several times getting MongoClient.. Is mongod really running?");
    }
}

在查询所在的服务类中:

protected function collection(){
    if(!isset($this->collection)){
        $this->collection =  $this->db()->selectCollection($this->collectionName);
    }
    return $this->collection;
}

然后查询就像这样:

$results = $this->collection()->aggregate($ops);

这是正确的行为吗?

1 个答案:

答案 0 :(得分:0)

如果您正在使用Azure IaaS,可能会在其他平台上出现问题。

一种选择是更改Mongo配置:

MongoDefaults.MaxConnectionIdleTime = TimeSpan.FromMinutes(5);

这会在5分钟后终止所有空闲连接。