PHPMongoDBdrive1.2版本連接該怎么處理以及PHPMongoDBdrive1.3版本怎么處理

PHP MongoDB drive1.2版本連接該怎么處理以及PHP MongoDB drive1.3版本怎么處理,針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。

我們提供的服務(wù)有:成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、嘉定ssl等。為1000+企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的嘉定網(wǎng)站制作公司

1.3版本的PHPMongoDBdriver重寫了連接處理庫(kù),和以前版本相比,在持久連接和連接池方面,都有了重大的變化。

PHPMongoDBdrive1.2版本連接怎么處理

1.2版本的驅(qū)動(dòng)引入了連接池,在執(zhí)行任何查詢時(shí),都會(huì)從連接池中請(qǐng)求一個(gè)連接,完成之后再歸還給連接池。這里的完成是指持有該連接的變量離開了它的作用域,下面是一個(gè)示例。

最簡(jiǎn)單的版本:

$m=newMongoClient();//←從連接池請(qǐng)求連接

$c=$m->demo->test;

$c->insert(array('test'=>'yes'));

>

←$m離開作用域,連接歸還給連接池

在函數(shù)中:

functiondoQuery()

{

$m=newMongoClient();//←從連接池請(qǐng)求連接

$c=$m->demo->test;

$c->insert(array('test'=>'yes'));

}//←$m離開作用域,連接歸還給連接池

>

在某些情況下,系統(tǒng)可能會(huì)產(chǎn)生大量的連接,比如在ORMs/ODMs的某個(gè)復(fù)雜結(jié)構(gòu)中引用連接對(duì)象,如下例子:

for($i=0;$i<5;$i++)>

PHPMongoDBdrive1.3版本怎么處理

在1.3版本中,連接管理做了很大改動(dòng)。每個(gè)worker進(jìn)程(線程、PHP-FPM或Apacheworker)中,驅(qū)動(dòng)把連接管理和Mongo*對(duì)象分離,降低驅(qū)動(dòng)的復(fù)雜度。下面以單個(gè)節(jié)點(diǎn)的MongoDB實(shí)例來說明驅(qū)動(dòng)如何處理連接。

當(dāng)一個(gè)worker進(jìn)程啟動(dòng),MongoDB驅(qū)動(dòng)會(huì)為之初始化連接管理器管理連接,并且默認(rèn)沒有連接。

在第一個(gè)請(qǐng)求調(diào)用newMongoClient();時(shí),驅(qū)動(dòng)創(chuàng)建一個(gè)新連接,并且以一個(gè)哈希值標(biāo)識(shí)這個(gè)連接。這個(gè)哈希值包括以下參數(shù):主機(jī)名、端口,進(jìn)程ID和可選的replicaset名,假如是密碼驗(yàn)證的連接,則還包括數(shù)據(jù)庫(kù)名、用戶名和密碼的哈希值(對(duì)于密碼驗(yàn)證的連接,我們后面再詳細(xì)討論)。調(diào)用MongoClient::getConnections()方法,可以查看連接對(duì)應(yīng)的哈希值:

$m=newMongoClient('mongodb://whisky:27017/');

var_dump($m->getConnections()[0]['hash']);

>

輸出:

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

輸出中的”-”表示該連接不屬于某個(gè)replicaset,”X”是沒有用戶名、數(shù)據(jù)庫(kù)和密碼時(shí)的占位符,22835是當(dāng)前進(jìn)程的進(jìn)程ID。

然后該連接會(huì)在連接管理器中注冊(cè):

在需要連接的任何時(shí)候,包括插入、刪除、更新、查找或執(zhí)行命令,驅(qū)動(dòng)都會(huì)向管理器請(qǐng)求一個(gè)合適的連接來執(zhí)行。請(qǐng)求連接時(shí)會(huì)用到newMongoClient()的參數(shù)和當(dāng)前進(jìn)程的ID。每個(gè)worker進(jìn)程/線程,連接管理器都會(huì)有一個(gè)連接列表,而每個(gè)PHPworker同一時(shí)刻,只會(huì)運(yùn)行一個(gè)請(qǐng)求,因此和每個(gè)MongoDB之間只需要一個(gè)連接,不斷重用,直到PHPworker終止或顯式調(diào)用MongoClient::close()關(guān)閉連接。

Replicasets

在存在復(fù)制集的環(huán)境中,情形有點(diǎn)不一樣。newMongoClient()的連接字符串中,需要指定多個(gè)hosts,并標(biāo)示當(dāng)前正在實(shí)用復(fù)制集:

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

其中的replicaSet參數(shù)不能省略,否則驅(qū)動(dòng)會(huì)認(rèn)為你是準(zhǔn)備連接三個(gè)不同的mongos進(jìn)程。

在實(shí)例化時(shí),驅(qū)動(dòng)會(huì)檢查復(fù)制集的拓?fù)浣Y(jié)構(gòu)。下面例子的輸出,顯示在調(diào)用newMongoClient()之后,復(fù)制集中所有可見的數(shù)據(jù)節(jié)點(diǎn)都會(huì)在管理器中注冊(cè)一個(gè)連接:

$m=newMongoClient('mongodb://whisky:13001/replicaSet=seta');

foreach($m->getConnections()as$c)

{

echo$c['hash'],"\n";

}

>

輸出:

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

雖然連接字符串中沒有whisky:13000節(jié)點(diǎn),但是管理器中已經(jīng)注冊(cè)了兩個(gè)連接:

管理器不僅包含連接的哈希值和TCP/IPsocket,還保存哪個(gè)節(jié)點(diǎn)是主節(jié)點(diǎn),以及每個(gè)節(jié)點(diǎn)的“距離”。下面的腳本顯示了這些額外的信息;

$m=newMongoClient('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,1mswhisky:13000;seta;X;5776:–PRIMARY,0ms

驅(qū)動(dòng)把操作分為兩種類型:寫操作,包括插入、更新、刪除和命令;讀操作,包括find和findOne。默認(rèn)情況下,假如沒有設(shè)置讀偏好參數(shù),管理器會(huì)一直返回主節(jié)點(diǎn)的連接。讀偏好參數(shù)可以通過setSlaveOkay()設(shè)置,也可以在連接字符串中設(shè)置:

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

加上這些參數(shù)后,連接字符串變得特別長(zhǎng),因此PHP驅(qū)動(dòng)允許將選項(xiàng)放在數(shù)組中,作為第二個(gè)參數(shù)傳入:

$options=array(

'replicaSet'=>'seta',

'readPreference'=>'secondaryPreferred',

);

$m=newMongoClient("mongodb://whisky:13000,whisky:13001/",$options);

對(duì)于每個(gè)操作,驅(qū)動(dòng)向管理器請(qǐng)求獲取一個(gè)合適的連接。對(duì)于寫操作,會(huì)一直返回主節(jié)點(diǎn)的連接;對(duì)于讀操作,假如輔助節(jié)點(diǎn)可用且“距離”不遠(yuǎn)的話,則會(huì)返回該輔助節(jié)點(diǎn)的連接。

驗(yàn)證的連接

假如MongoDB啟用驗(yàn)證功能,那么連接的哈希值會(huì)包含驗(yàn)證相關(guān)的哈希值。這樣不同腳本,使用不同的用戶名、密碼連接同一個(gè)MongoDB上的不同的數(shù)據(jù)庫(kù)時(shí),能夠相互區(qū)分,而不會(huì)誤用連接。下面示例使用admin用戶名連接admin數(shù)據(jù)庫(kù),然后觀察hash值的變化:

$m=newMongoClient('mongodb://admin:admin@whisky:27017/admin');

var_dump($m->getConnections()[0]['hash']);

>

輸出:

string(64)“whisky:27017;-;admin/admin/bda5cc70cd5c23f7ffa1fda978ecbD30;8697″

以前示例中的”X”部分已經(jīng)替換為一個(gè)包含數(shù)據(jù)庫(kù)名admin、用戶名admin和哈希值bda5cc70cd5c23f7ffa1fda978ecbd30,該哈希值是根據(jù)用戶名、數(shù)據(jù)庫(kù)名和密碼哈希值計(jì)算得來。

為了驗(yàn)證能夠正確工作,需要在連接字符串中包含數(shù)據(jù)庫(kù)名,否則會(huì)默認(rèn)為admin。

在建立連接后要使用數(shù)據(jù)庫(kù),需要先選擇該數(shù)據(jù)庫(kù),如:

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

假如選擇的數(shù)據(jù)庫(kù)是連接字符串中指定的數(shù)據(jù)庫(kù),或者連接字符串中的數(shù)據(jù)庫(kù)是admin,那么一切都會(huì)正常運(yùn)行。否則,驅(qū)動(dòng)會(huì)創(chuàng)建一個(gè)新的連接,從而防止驗(yàn)證被繞過,如下所示:

$m=newMongoClient('mongodb://user:user@whisky:27017/test');

$db=$m->test2;

$collection=$db->collection;

var_dump($collection->findOne());

>

輸出:

Fatalerror:Uncaughtexception‘MongoCursorException’withmessage‘whisky:27017:unauthorizeddb:test2ns:test2.collectionlocktype:0client:127.0.0.1′in…/mongo-connect-5.php.txt:6

因?yàn)槲覀兊倪B接并沒有執(zhí)行test2數(shù)據(jù)庫(kù)的授權(quán)驗(yàn)證,因而失敗。假如我們執(zhí)行驗(yàn)證,就會(huì)正常運(yùn)行:

$m=newMongoClient('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;26983whisky:27017;-;test2/user2/984b6b4fd6c33f49b73f026f8b47c0de;26983

現(xiàn)在管理器中有兩個(gè)已驗(yàn)證的連接:

順便提一句,假如你打開了E_DEPRECATED級(jí)別的錯(cuò)誤提示,則會(huì)看到:

Deprecated:FunctionMongoDB::authenticate()isdeprecatedin…/mongo-connect-6.php.txtonline5

驅(qū)動(dòng)建議通過創(chuàng)建兩個(gè)MongoClient對(duì)象完成該類任務(wù):

$mTest1=newMongoClient('mongodb://user:user@whisky:27017/test',array('connect'=>false));

$mTest2=newMongoClient('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";

}

>

單個(gè)MongoDB服務(wù)器能支持的并發(fā)連接相當(dāng)有限,假如使用PHP-FPM的話,每個(gè)worker進(jìn)程有自己獨(dú)立的連接池,那么很容易達(dá)到連接數(shù)的上限。因此,在生產(chǎn)環(huán)境中,不管有沒有使用復(fù)制集,都要部署mongos,然后PHP-FPM連接mongos,這樣可以減少mongod的連接數(shù),并且PHP-FPM和mongos之間可以使用短連接(即每個(gè)請(qǐng)求結(jié)束時(shí)都顯式調(diào)用close函數(shù)關(guān)閉MongoDB連接)。

關(guān)于PHP MongoDB drive1.2版本連接該怎么處理以及PHP MongoDB drive1.3版本怎么處理問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

分享題目:PHPMongoDBdrive1.2版本連接該怎么處理以及PHPMongoDBdrive1.3版本怎么處理
分享網(wǎng)址:http://muchs.cn/article28/gdscjp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google網(wǎng)站改版、App開發(fā)、定制網(wǎng)站網(wǎng)站策劃、靜態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名