MongoDB 欧洲杯买球下注盘口:PHP Driver的连接处理解析

1.3版本的PHP MongoDB
driver重写了一而再三回九转管理库,和原先版本对照,在漫长连接和连接池方面,都有了首要的转换。

1.2版本的连年管理

1.2本子的驱动引进了连接池,在进行此外查询时,都会从连接池中倡议一个延续,达成以往再归还给连接池。这里的达成是指装有该连接的变量离开了它的功效域,上面是一个示范。

最简便的版本:

<?php
$m = new MongoClient();    // ← 从连接池请求连接
$c = $m->demo->test;
$c->insert( array( 'test' => 'yes' ) );
?>

← $m离开功用域,连接归还给连接池

在函数中:

<?php
function doQuery()
{
        $m = new MongoClient();    // ← 从连接池请求连接
        $c = $m->demo->test;
        $c->insert( array( 'test' => 'yes' ) );
} // ← $m离开作用域,连接归还给连接池
?>

在一些境况下,系统恐怕会发生大批量的连年,比方在ORMs/ODMs的某部复杂布局中援用连接对象,如下例子:

<?php
for ( $i = 0; $i < 5; $i++ )
{
        $conns[] = new MongoClient();
}// ← 现在有5个连接
?>

1.3版本的三番五次管理

在1.3本子中,连接管理做了极大更动。每一个worker进度(线程、PHP-FPM或Apache
worker卡塔尔中,驱动把连接管理和Mongo*指标分别,减弱驱动的复杂度。上面以单个节点的MongoDB实例来表达驱动如哪管理连接。

当三个worker进度运行,MongoDB驱动会为之伊始化连接微处理器管理总是,况兼暗许未有连接。

在第一个央求调用new
MongoClient(State of Qatar;时,驱动制造叁个新连接,並且以八个哈希值标记这些三番一遍。那么些哈希值满含以下参数:主机名、端口,进程ID和可选的replica
set名,倘若是密码验证的总是,则还包涵数据库名、客户名和密码的哈希值(对于密码验证的连接,我们前边再详尽斟酌)。调用MongoClient::getConnections(卡塔尔方法,能够查看连接对应的哈希值:

<?php
$m = new MongoClient( 'mongodb://whisky:27017/' );
var_dump( $m->getConnections()[0]['hash'] );
?>

输出:

string(22) “whisky:27017;-;X;22835″

输出中的”-”表示该连接不归属某些replica
set,”X”是不曾客商名、数据库和密码时的占位符,22835是当下历程的经过ID。

下一场该连接会在三番五次微机中登记: 欧洲杯买球下注盘口 1

在急需一而再接二连三的别的时候,富含插入、删除、更新、查找或实施命令,驱动都会向管理器央浼一个适宜的延续来试行。央浼连接时会用到new
MongoClient(State of Qatar的参数和近些日子进程的ID。每种worker进度/线程,连接微处理器都会有叁个三番两次列表,而各类PHP
worker同不时刻,只会运营二个号令,因而和种种MongoDB之间只供给一个接二连三,不断重用,直到PHP
worker终止或显式调用MongoClient::close(State of Qatar关闭连接。

Replica sets

在设有复制集的条件中,情状有一点点不等同。new
MongoClient(卡塔尔的连接字符串中,必要钦定多少个hosts,并标示当前正值实用复制集:

$m = new
MongoClient(“mongodb://whisky:13000,whisky:13001/?replicaSet=seta”);

个中的replicaSet参数无法大约,不然驱动会感到你是绸缪连接四个例外的mongos进度。

在实例化时,驱动会检查复制集的拓扑布局。上面例子的输出,呈现在调用new
MongoClient(卡塔尔国之后,复制集中具备可知的数量节点都会在微机中登记二个接连:

<?php
$m = new MongoClient( 'mongodb://whisky:13001/?replicaSet=seta' );
foreach ( $m->getConnections() as $c )
{
    echo $c['hash'], "\n";
}
?>

输出:

whisky:13001;seta;X;32315 whisky:13000;seta;X;32315

纵然接二连三字符串中向来不whisky:13000节点,不过管理器中曾经注册了四个三番四次:

欧洲杯买球下注盘口 2

微机不仅仅带有连接的哈希值和TCP/IP
socket,还保存哪个节点是主节点,以至各种节点的“间隔”。下边包车型大巴脚本呈现了那么些额外的新闻;

<?php
$m = new MongoClient( 'mongodb://whisky:13001/?replicaSet=seta' );
foreach ( $m->getConnections() as $c )
{
    echo $c['hash'], ":\n",
        " - {$c['connection']['connection_type_desc']}, ",
        "{$c['connection']['ping_ms']} ms\n";
}
?>

欧洲杯买球下注盘口 ,输出:

whisky:13001;seta;X;5776: – SECONDARY, 1 ms whisky:13000;seta;X;5776:
– PRIMARY, 0 ms

使得把操作分为二种档案的次序:写操作,包含插入、更新、删除和下令;读操作,富含find和findOne。暗中认可景况下,若无设置读偏幸参数,微机会一贯重回主节点的一而再连续。读偏爱参数能够经过setSlaveOkay(卡塔尔设置,也足以在三翻五次字符串中安装:

$m = new MongoClient("mongodb://whisky:13000,whisky:13001/?replicaSet=seta&readPreference=secondaryPreferred");

加多这几个参数后,连接字符串变得专程长,因而PHP驱动允许将精选放在数组中,作为第一个参数字传送入:

$options = array(
        'replicaSet' => 'seta',
        'readPreference' => 'secondaryPreferred',
);
$m = new MongoClient("mongodb://whisky:13000,whisky:13001/", $options);

对此每个操作,驱动向微处理机伏乞获取一个适用的连天。对于写操作,会向来再次回到主节点的接连几天;对于读操作,如若扶助节点可用且“间距”不远的话,则会回来该救助节点的总是。

证实的三番若干回

若是MongoDB启用验证作用,那么连接的哈希值会满含验证相关的哈希值。那样差别脚本,使用区别的客商名、密码连接同一个MongoDB上的两样的数据库时,能够互相区分,而不会误用连接。下边示例使用admin客户名连接admin数据库,然后观察hash值的改造:

<?php
$m = new MongoClient( 'mongodb://admin:admin@whisky:27017/admin' );
var_dump( $m->getConnections()[0]['hash'] );
?>

输出:

string(64)
“whisky:27017;-;admin/admin/bda5cc70cd5c23f7ffa1fda978ecb class=”wp_keywordlink”>D30;8697″

此前示例中的”X”部分已经替换为叁个含有数据库名admin、客商名admin和哈希值bda5cc70cd5c23f7ffa1fda978ecbd30,该哈希值是依据顾客名、数据库名和密码哈希值计算得来。

为了求证能够科学专门的工作,须要在接连字符串中包含数据库名,不然会默以为admin。

在建设布局连接后要运用数据库,必要先选拔该数据库,如:

$collection = $m->demoDb->collection; $collection->findOne();

假诺接受的数据库是连接字符串中钦赐的数据库,或然三番四遍字符串中的数据库是admin,那么整个都会平时运作。不然,驱动会创立四个新的连接,进而制止于核算证被绕过,如下所示:

<?php
$m = new MongoClient( 'mongodb://user:user@whisky:27017/test' );

$db = $m->test2;
$collection = $db->collection;
var_dump( $collection->findOne() );
?>

输出:

Fatal error: Uncaught exception ‘MongoCursorException’ with message
‘whisky:27017: unauthorized db:test2 ns:test2.collection lock type:0
client:127.0.0.1′ in …/mongo-connect-5.php.txt:6

因为我们的总是并不曾实行test2数据库的授权验证,由此失败。要是大家举行验证,就能够寻常运行:

<?php
$m = new MongoClient( 'mongodb://user:user@whisky:27017/test' );

$db = $m->test2;
$db->authenticate('user2', 'user2' );
$collection = $db->collection;
$collection->findOne();

foreach ( $m->getConnections() as $c )
{
    echo $c['hash'], "\n";
}
?>

输出:

whisky:27017;-;test/user/602b672e2fdcda7b58a042aeeb034376;26983
whisky:27017;-;test2/user2/984b6b4fd6c33f49b73f026f8b47c0de;26983

到现在微处理机中有五个已证实的连年:

欧洲杯买球下注盘口 3

顺便提一句,如若您张开了E_DEPRECATED等第的荒谬提醒,则会看出:

Deprecated: Function MongoDB::authenticate() is deprecated in
…/mongo-connect-6.php.txt on line 5

使得提议通过创办七个MongoClient对象完成该类职责:

<?php
$mTest1 = new MongoClient( 'mongodb://user:user@whisky:27017/test', array( 'connect' => false ) );
$mTest2 = new MongoClient( 'mongodb://user2:user2@whisky:27017/test2', array( 'connect' => false ) );

$mTest1->test->test->findOne();
$mTest2->test2->test->findOne();

foreach ( $mTest2->getConnections() as $c )
{
    echo $c['hash'], "\n";
}
?>

单个MongoDB服务器能支撑的产出连接一定有限,假如利用PHP-FPM的话,各样worker进度有友好单身的连接池,那么比较轻巧完毕连接数的上限。因而,在分娩条件中,不管有未有应用复制集,都要安排mongos,然后PHP-FPM连接mongos,那样能够减弱mongod的连接数,而且PHP-FPM和mongos之间能够使用短连接(即每一个诉求甘休时都显式调用close函数关闭MongoDB连接卡塔尔(قطر‎。

相关文章