溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

PHP MongoDB drive1.2版本連接該怎么處理以及PHP MongoDB drive1.3版本怎么處理

發(fā)布時間:2021-09-29 10:38:12 來源:億速云 閱讀:158 作者:柒染 欄目:編程語言

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

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

  PHPMongoDBdrive1.2版本連接怎么處理

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

  最簡單的版本:

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

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

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

  >

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

  在函數(shù)中:

  functiondoQuery()

  {

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

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

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

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

  >

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

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

  PHPMongoDBdrive1.3版本怎么處理

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

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

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

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

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

  >

  輸出:

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

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

  然后該連接會在連接管理器中注冊:

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

  Replicasets

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

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

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

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

  $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é)點,但是管理器中已經(jīng)注冊了兩個連接:

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

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

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

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

  $options=array(

  'replicaSet'=>'seta',

  'readPreference'=>'secondaryPreferred',

  );

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

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

  驗證的連接

  假如MongoDB啟用驗證功能,那么連接的哈希值會包含驗證相關(guān)的哈希值。這樣不同腳本,使用不同的用戶名、密碼連接同一個MongoDB上的不同的數(shù)據(jù)庫時,能夠相互區(qū)分,而不會誤用連接。下面示例使用admin用戶名連接admin數(shù)據(jù)庫,然后觀察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)替換為一個包含數(shù)據(jù)庫名admin、用戶名admin和哈希值bda5cc70cd5c23f7ffa1fda978ecbd30,該哈希值是根據(jù)用戶名、數(shù)據(jù)庫名和密碼哈希值計算得來。

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

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

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

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

  $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

  因為我們的連接并沒有執(zhí)行test2數(shù)據(jù)庫的授權(quán)驗證,因而失敗。假如我們執(zhí)行驗證,就會正常運行:

  $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)在管理器中有兩個已驗證的連接:

  順便提一句,假如你打開了E_DEPRECATED級別的錯誤提示,則會看到:

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

  驅(qū)動建議通過創(chuàng)建兩個MongoClient對象完成該類任務(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";

  }

  >

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

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

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

php
AI