对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

使用连接池

在本指南中,您可以学习;了解如何使用C++驱动程序创建和配置连接池。连接池是应用程序可用于管理多个并发MongoDB操作的客户端对象的缓存。

实例化 mongocxx::pool 后,池会根据需要创建客户端对象,直到达到最大池大小。每个运行MongoDB操作的线程从池中检出一个客户端,使用它来执行操作,然后将客户端返回到池中。客户端池会自动管理这些客户端的生命周期。

重要

与大多数MongoDB驱动程序不同, C++驱动程序未实现MongoDB连接监控和连接监控/池化 (CMAP)规范。在这种情况下,连接池化是指驱动程序对客户端对象的缓存,而不是数据库连接。

与独立运行的实例客户端相比,连接池具有显着的性能优势。mongocxx::pool 使用单独的背景监控线程来持续监控集群。因此,应用程序线程无需等待拓扑结构监控完成即可执行操作。相比之下,独立运行的实例mongocxx::client 会定期停止以检查集群状态,并在检查期间阻止所有操作。

即使应用程序仅使用一个线程,也可以使用连接池。池的背景监控提供比独立运行的实例客户端的定期检查更好的性能。

下表总结了 mongocxx::poolmongocxx::client 之间的主要区别:

功能
mongocxx::pool
mongocxx::client

推荐用于多线程应用程序

可以。

No.

后台监控

是的。池为每个服务器使用单独的线程。

不会。客户端会定期执行阻塞检查。

监控间隔

每台服务器每 10 秒一次。

每 60 秒一次。

线程安全

线程安全,但获取的客户端不是线程安全的。

不是线程安全的。

货叉安全

您必须在分叉后创建池。

您必须在分叉后创建客户端。

提示

线程和分叉

要进一步学习;了解如何跨多个线程使用客户端和客户端对象以及何时分叉进程,请参阅 线程和分叉安全指南

要创建连接池,请将连接 URI 传递给 mongocxx::pool 对象的构造函数,以实例化该对象。每个运行MongoDB操作的线程都必须通过调用 acquire() 节点函数从池中获取客户端。当客户端超出范围时,它会自动返回到池中。

此示例文件执行以下操作:

  • 创建连接池

  • 创建三个线程,每个线程从池中获取自己的客户端

  • 在每个线程中执行插入操作

1#include <iostream>
2#include <thread>
3#include <vector>
4
5#include <bsoncxx/builder/basic/document.hpp>
6#include <bsoncxx/builder/basic/kvp.hpp>
7#include <mongocxx/instance.hpp>
8#include <mongocxx/pool.hpp>
9#include <mongocxx/uri.hpp>
10
11using bsoncxx::builder::basic::kvp;
12using bsoncxx::builder::basic::make_document;
13
14int main() {
15 mongocxx::instance instance{};
16
17 mongocxx::uri uri{"mongodb://localhost:27017"};
18 mongocxx::pool pool{uri};
19
20 std::vector<std::thread> threads;
21
22 // Creates multiple threads that each acquire a client from the pool
23 for (int i = 0; i < 3; ++i) {
24 threads.emplace_back([&pool, i]() {
25 auto client = pool.acquire();
26 auto collection = (*client)["db"]["coll"];
27
28 // Inserts a sample document
29 collection.insert_one(make_document(kvp("thread_id", i)));
30
31 std::cout << "Thread " << i << " inserted a document" << std::endl;
32 });
33 }
34
35 // Waits for all threads to complete
36 for (auto& thread : threads) {
37 thread.join();
38 }
39
40 std::cout << "All threads completed" << std::endl;
41
42 return 0;
43}

您可以通过在连接 URI 中包含选项来配置连接池行为。下表描述了您可以设立的连接池选项:

URI 选项
说明

maxPoolSize

指定连接池可以创建的客户端最大数量。当达到此限制时,acquire()节点函数会阻塞,直到另一个线程将客户端返回连接池。
默认为 100
类型int

minPoolSize

指定连接池维护的最小客户端数。连接池在初始化时创建该数量的客户端,并持续维护至少该数量的客户端。
默认为 0
类型int

waitQueueTimeoutMS

指定当连接池达到 maxPoolSize 值时,acquire() 函数等待客户端可用的最长时间(毫秒)。如果此超时到期,acquire() 函数将生成错误。
默认为无超时。
类型int

以下示例指定 maxPoolSize 选项来创建最大大小为 5 个客户端的连接池:

mongocxx::uri uri{"mongodb://localhost:27017/?maxPoolSize=5"};
mongocxx::pool pool{uri};

要学习;了解有关本指南中讨论的类型和函数的更多信息,请参阅以下API文档: