注意: 在 Unix 平台上,扩展对使用 fork() 系统调用但未调用 exec() 的脚本敏感。建议用户不要在派生子进程中重新使用 MongoDB\Driver\Manager 实例。
自 1.2.0 起的所有扩展版本都会在 PHP 工作进程中持久化 » libmongoc 客户端对象,这使其能够在多个请求之间重新使用数据库连接、身份验证状态和拓扑信息。
当调用 MongoDB\Driver\Manager::__construct() 时,会根据其参数(即 URI 字符串和数组选项)创建一个哈希值。扩展将尝试为该哈希值找到先前持久化的 » libmongoc 客户端对象。如果找不到现有客户端,则会创建一个新客户端并将其持久化以供将来使用。可以通过 "disableClientPersistence"
驱动程序选项禁用此行为。
每个客户端都包含自己的数据库连接和服务器拓扑视图(例如,独立、复制集、分片集群)。通过在 PHP 请求之间持久化客户端,扩展能够重新使用已建立的数据库连接,并且无需在每个请求上 » 发现服务器拓扑。
请考虑以下示例
<?php
$managers = [
new MongoDB\Driver\Manager('mongodb://127.0.0.1'),
new MongoDB\Driver\Manager('mongodb://127.0.0.1'),
new MongoDB\Driver\Manager('mongodb://127.0.0.1:27017'),
new MongoDB\Driver\Manager('mongodb://rs1.example.com,rs2.example.com/', ['replicaSet' => 'myReplicaSet']),
];
foreach ($managers as $manager) {
$manager->executeCommand('test', new MongoDB\Driver\Command(['ping' => 1]));
}
?>
前两个 Manager 对象将共享相同的 » libmongoc 客户端,因为它们的构造函数参数相同。第三个和第四个对象将各自使用自己的客户端。总共将创建三个客户端,并且执行此脚本的 PHP 工作进程将打开到 127.0.0.1
的两个连接以及到 rs1.example.com
和 rs2.example.com
的各一个连接。如果扩展在发出 hello
命令后发现了复制集的其他成员,它也将向这些服务器打开其他连接。
如果同一工作进程在第二个请求中再次执行该脚本,则将重新使用这三个客户端,并且不会建立新连接。根据上次请求服务的时间,扩展可能需要发出其他 hello
命令来更新其对拓扑的视图。
1.2.0 之前的扩展版本利用 PHP 的 Streams API 进行数据库连接,使用 » libmongoc 中的 API 指定套接字通信的自定义处理程序;但是,每个 MongoDB\Driver\Manager 都会创建一个新的 libmongoc 客户端。因此,扩展会持久化单个数据库连接,但不会持久化身份验证状态或拓扑信息。这意味着扩展需要在每个请求开始时发出命令来进行身份验证并 » 发现服务器拓扑。
数据库连接通过从服务器的主机、端口和用于构造 MongoDB\Driver\Manager 的 URI 字符串派生的哈希值来持久化。构造函数的数组选项不包含在此哈希值中。
注意: 扩展版本 >= 1.1.8 且 < 1.2.0 不会为 SSL 连接持久化套接字。有关更多信息,请参阅 » PHPC-720。
尽管在持久化 SSL 连接和拓扑信息方面存在不足,但此版本的扩展支持所有 SSL 上下文选项,因为它使用 PHP 的 Streams API。