MongoDB C驾驶员提供两种连接模式:单线程和池化。我们建议使用池化模式,尤其是对于多线程应用程序。
重要
与其他MongoDB驱动程序不同, C驾驶员没有实现连接池化的 CMAP 规范。在C驾驶员上下文中,连接池化是指驱动程序对客户端对象的缓存,而不是数据库连接。
池化模式
要使用池化模式,请创建一个 mongoc_client_pool_t:
mongoc_uri_t *uri = mongoc_uri_new("mongodb://hostA,hostB/?replicaSet=my_rs"); mongoc_client_pool_t *pool = mongoc_client_pool_new(uri);
当您首次调用 mongoc_client_pool_pop 时,池会在背景启动监控线程。监控线程独立连接到连接 URI 中的所有服务器。当监控线程收到来自服务器的 hello 响应时,它们更新服务器拓扑结构的共享视图。该池在发现新服务器时会创建额外的监控线程和连接。当池从服务器拓扑结构的共享视图中删除服务器时,监控线程终止。
每个执行MongoDB操作的线程都必须从池中检出一个客户端:
mongoc_client_t *client = mongoc_client_pool_pop(pool); /* use the client for operations ... */ mongoc_client_pool_push(pool, client);
单个 mongoc_client_t 对象不是线程安全的。只有 mongoc_client_pool_t对象提供线程安全性。
在池化模式下,一旦监控发现可用的服务器,程序的操作就会解除阻塞。示例,如果程序中的一个线程等待在主节点 (primary node in the replica set)上执行“插入”,则一旦发现主节点 (primary node in the replica set),它就会解除阻塞,而不是等待检查所有从节点。
池为每台服务器打开一个连接进行监控。每个客户端都会与其用于应用程序操作的每个服务器打开自己的连接。后台监控线程大约每10 秒独立地重新扫描一次服务器。您可以通过在连接heartbeatFrequencyMS URI 中指定 选项来配置此时间间隔。 (请参阅 mongoc_uri_t )。
当池中没有可用的客户端对象且尚未达到 maxPoolSize 限制时,客户端端池会创建新的 mongoc_client_t对象。 maxPoolSize 的默认值为 100。
您还可以在连接waitQueueTimeoutMS URI 中指定 ,以限制 mongoc_client_pool_pop 等待池中客户端的时间。 (请参阅 mongoc_uri_t )。如果指定waitQueueTimeoutMS ,请确认池实际返回客户端:
mongoc_client_t *client = mongoc_client_pool_pop(pool); if (client) { /* use the client for operations */ mongoc_client_pool_push(pool, client); } else { /* handle a wait queue timeout */ }
提示
要使用 的非阻塞替代方案,请使用mongoc_client_pool_pop mongoc_client_pool_try_pop。
请参阅连接池选项以配置池大小和行为。有关在池化模式下使用驾驶员的多线程程序的扩展示例,请参阅 mongoc_client_pool_t 。
单线程模式
要使用单线程模式,直接创建一个 mongoc_client_t:
mongoc_client_t *client = mongoc_client_new( "mongodb://hostA,hostB/?replicaSet=my_rs");
当您首次将客户端用于MongoDB操作时,客户端会按需连接。通过使用每个服务器的非阻塞套接字,客户端开始同时检查每个服务器,并使用异步 poll 或 select 函数从套接字接收事件,直到所有服务器均已响应或超时。在单线程模式下, C驱动程序会扇出以同时开始所有检查,然后在所有检查完成或超时后扇入。扫描完成后,客户端执行您的操作并返回。
在单线程模式下,客户端大约每分钟重新扫描服务器拓扑结构一次。如果自上次扫描以来已经过去一分钟以上,则在客户端完成扫描时,客户端上的下一个操作会阻塞。您可以在连接heartbeatFrequencyMS URI 中使用 参数配置此时间间隔。 (请参阅 mongoc_uri_t )。
单线程客户端为拓扑结构中的每个服务器打开一个连接。这些连接处理扫描拓扑结构和执行正常操作。
提示
您可以在连接 URI 中指定 serverSelectionTryOne=false 选项,以提高单线程客户端对象与MongoDB的连接的弹性。