本页包含常见问题及其相应解答。
提示
如果在此页面上找不到问题的回答,请参阅问题和帮助页面,了解后续步骤和更多资源。
为什么连接 MongoDB 时会出错?
如果在连接到 MongoDB 部署时出现问题,请参阅连接故障排除指南,了解潜在的解决方案。
连接池在节点驱动程序中是如何工作的?
对于 MongoDB 拓扑结构中的每个服务器,每个 MongoClient
实例都有一个内置连接池。连接池按需打开套接字以支持应用程序中对 MongoDB 的并发请求。
每个连接池的最大大小由 maxPoolSize
选项设置,默认值为 100
。如果某个服务器的在用连接数达到 maxPoolSize
值,则对该服务器的下一个请求将等待,直到出现可用连接。
除了支持应用程序请求所需的套接字之外,每个MongoClient
实例还为 MongoDB 拓扑结构中的每个服务器再打开两个套接字,用于监控服务器的状态。 例如,连接到三节点副本集的客户端会打开六个监控套接字。 如果应用程序使用maxPoolSize
的默认设置,并且仅查询主(默认)节点,则连接池中的总连接数最多可以为106
。 如果应用程序使用读取偏好来查询从节点,则这些连接池会增长,总连接数可能为306
。
要在一个进程中支持大量并发 MongoDB 请求,可以增加 maxPoolSize
。
连接池的速率受到了限制。maxConnecting
选项将决定连接池在任何时候可以并行创建的连接数量。例如,如果 maxConnecting
的值为 2
,则仅当发生以下情况之一时,尝试同时签出连接的第三个请求才会成功:
连接池完成创建连接,且池中连接数少于
maxPoolSize
。现有连接会重新检入池中。
由于对创建连接的速率有限制,驱动程序重用现有连接的能力得到了提高。
您可以使用 minPoolSize
选项设置每个服务器的最小并发连接数,默认值为 0
。驱动程序会用这个数量的套接字初始化连接池。如果套接字关闭,导致套接字总数(包括使用中的和闲置的)下降到最小值以下,则会打开更多套接字,直到达到最小值。
您可以通过设置 maxIdleTimeMS
选项来设置一个连接在连接池中保持空闲状态的最大毫秒数。一旦 maxIdleTimeMS
的连接处于空闲状态,连接池就会将其删除并替换。此选项默认为 0
(无限制)。
以下 MongoClient
的默认配置适用于大多数应用程序:
const client = new MongoClient("<connection string>");
MongoClient
支持多个并发请求。为每个流程创建一个客户端,并重复用于流程中的所有操作。这种做法比为每个请求创建一个客户端更有效率。
该驱动程序不限制可以等待套接字变为可用状态的请求数量,应用程序有责任在负载峰值期间将其池的大小限制为绑定队列。请求等待的时间为 waitQueueTimeoutMS
选项中指定的时间,默认为 0
(无限制)。
如果请求等待套接字的时间超过 waitQueueTimeoutMS
所定义的时长,则会引发连接错误。如果在负载峰值期间限制操作的持续时间比完成每个操作更重要,请使用此选项。
当MongoClient.close()
被任何请求调用时,驾驶员会关闭所有空闲套接字,并关闭所有正在使用的套接字,因为它们会返回到池中。 调用MongoClient.close()
仅关闭不活动的套接字,而不会直接终止任何正在进行的操作。 仅当关联操作完成时,驾驶员才会关闭任何正在使用的套接字。 但是, MongoClient.close()
方法会关闭现有会话和事务,这可能会间接影响正在进行的操作和打开的游标的行为。
"connectTimeoutMS"、"socketTimeoutMS"和"maxTimeMS"之间有什么区别?
设置 | 说明 |
---|---|
connectTimeoutMS |
默认值:30000 |
socketTimeoutMS |
|
maxTimeMS | maxTimeMS 指定服务器等待操作到达服务器后完成的最长时间。如果操作超过指定的时间限制,则会返回超时错误。只能将 |
如需指定 MongoClient
的可选设置,请在构造函数的 options
对象中声明一个或多个可用设置,如下所示:
const client = new MongoClient(uri, { connectTimeoutMS: <integer value>, socketTimeoutMS: <integer value> });
要查看所有可用设置,请参阅 MongoClientOptions API 文档。
如需指定 maxTimeMS
,可将带有超时规范的 maxTimeMS()
方法链接到返回 Cursor
的操作:
const cursor = myColl.find({}).maxTimeMS(50);
如果客户端断开连接,运行中的操作会怎样?
从MongoDB Server版本 4.2 开始,如果客户端断开连接,服务器会终止聚合等运行的操作和查找操作。
其他操作,如写入操作,即使客户端断开连接,也会继续在 MongoDB 服务器上运行。如果应用程序在客户端断开连接后重试操作,这种行为可能会导致数据不一致。
如何确认驱动程序关闭了不可用的套接字?
如果出现异常网络行为或是 MongoDB 进程因错误而失败,则可能不会收到驱动程序正确关闭相应套接字的确认信息。
为确保驱动程序在这些情况下正确关闭套接字,请设置 socketTimeoutMS
选项。当 MongoDB 进程超时时,驱动程序将关闭套接字。我们建议您选择的 socketTimeoutMS
的值应比应用程序执行最慢操作的预期持续时间长两到三倍。
如何防止套接字在进入活动状态前超时?
拥有大型连接池并不总能减少重新连接请求。考虑以下示例:
应用程序的连接池大小为 5 个套接字,socketTimeoutMS
选项设置为 5000 毫秒。操作平均每 3000 毫秒发生一次,重新连接请求也很频繁。每个套接字在 5000 毫秒后超时,也就是说所有套接字都必须在这 5000 毫秒内执行某些操作,以避免关闭。
每 3000 毫秒一条信息不足以让套接字处于活动状态,因此有几个套接字会在 5000 毫秒后超时。为避免过多的套接字超时,可通过指定 maxPoolSize
选项来减少驱动程序在连接池中可维护的连接数。
如需为 MongoClient
指定可选的 maxPoolSize
设置,请在构造函数的 options
对象中声明如下:
const client = new MongoClient(uri, { maxPoolSize: <integer value>, });
“connectTimeoutMS”和“socketTimeoutMS”的值为“0”意味着什么?
如果将 connectTimeoutMS
或 socketTimeoutMS
的值设置为 0
,应用程序将使用操作系统默认的套接字超时值。
如何防止长时间运行操作拖慢服务器?
通过指定超时值,可以防止长时间运行的操作拖慢服务器速度。您可以将 maxTimeMS()
方法链接到返回 Cursor
的操作,为特定操作设置超时。
以下示例展示如何将 maxTimeMS()
方法链接到返回 Cursor
的操作:
// Execute a find command await collection .find({ $where: "sleep(100) || true" }) .maxTimeMS(50);
keepAlive 选项有什么作用?
keepAlive
连接选项指定是否在 TCP 套接字上启用传输控制协议 (TCP) keepalive。如果启用了keepalives,驾驶员会定期向MongoDB 部署发送 ping 来检查连接是否处于活动状态。仅当操作系统支持SO_KEEPALIVE
套接字选项时,此功能才有效。
keepAliveInitialDelay
选项指定了驱动程序在启动 keepalive 之前等待的毫秒数。
5.3 驱动程序版本已弃用这些选项。从驱动程序 6.0 版开始,keepAlive
选项永久设置为 true
,keepAliveInitialDelay
设置为 300000 毫秒(300 秒)。
警告
如果您的防火墙忽略或删除了 keepalive 消息,您可能无法识别删除的连接。
如果出现意外网络行为,我该怎么办?
如果应用程序和 MongoDB 之间的防火墙配置不正确,您可能会遇到意外的网络行为。这些防火墙在删除连接时可能过于激进,从而可能导致意外错误。
确认您的防火墙会执行以下行为:
关闭连接时,防火墙会发送
FIN
数据包,从而告知驱动程序该套接字已关闭。防火墙允许 keepalive 消息。
提示
要了解有关 keepalive 消息的更多信息,请参阅 keepAlive 选项有何作用?常见问题解答条目。
如何防止因运行缓慢而延误其他操作?
当您使用同一 MongoClient
实例同时运行多个 MongoDB 操作时,缓慢的操作可能会导致其他操作延迟。缓慢的操作会占用 MongoDB 的连接,从而导致其他操作需要等待,直到有其他连接空出来。
如果怀疑是缓慢的 MongoDB 操作导致了延迟,可以使用以下方法检查所有进行中操作的性能:
在部署中启用数据库分析器。 要了解更多信息,请参阅 手册中的 数据库分析器 MongoDB Server。
运行
db.currentOp()
MongoDB Shell 命令。如需了解更多信息,请参阅“服务器手册”中的 db.currentOp() 文档。启用连接池监控。如需了解更多信息,请参阅“连接池监控”。
确定哪些操作导致延迟后,请尝试提高这些操作的性能。 阅读《MongoDB 性能最佳实践指南》,了解可能的解决方案。
若在实施性能最佳实践后仍出现延迟,则可修改连接设置以增大连接池大小。连接池是指驱动程序随时进行维护的与服务器的一组连接。
要指定连接池的最大大小,可以在 MongoClient
实例的连接选项中设置 maxPoolSize
选项。maxPoolSize
的默认值为 100
。如果正在使用的服务器连接数达到 maxPoolSize
,则发送到服务器的下一个操作将暂停,直到与驱动程序的连接可用。以下代码在创建新的 MongoClient
时将 maxPoolSize
设置为 150
:
const client = new MongoClient(uri, { maxPoolSize: 150 });
提示
如需了解有关连接池化的更多信息,请参阅节点驱动程序中的连接池化如何运行?常见问题解答条目。
如何确保连接字符串对副本集有效?
传递给驱动程序的连接string必须使用副本集配置中设置的服务器的确切主机名。 给定副本集的以下配置设置,为了使副本集发现和故障转移正常工作,驱动程序必须有权访问server1
、 server2
和server3
。
{ "_id": "testSet", "version": 1, "protocolVersion": 1, "members": [ { "_id": 1, "host": "server1:31000" }, { "_id": 2, "host": "server2:31001" }, { "_id": 3, "host": "server3:31002" } ] }
如果您无法在此找到问题的答案,请尝试问题和帮助部分中列出的论坛和支持渠道。