Docs 菜单
Docs 主页
/ / /
Node.js

FAQ

在此页面上

  • 为什么连接 MongoDB 时会出错?
  • 连接池在节点驱动程序中是如何工作的?
  • "connectTimeoutMS"、"socketTimeoutMS"和"maxTimeMS"之间有什么区别?
  • 如果客户端断开连接,运行中的操作会怎样?
  • 如何确认驱动程序关闭了不可用的套接字?
  • 如何防止套接字在进入活动状态前超时?
  • “connectTimeoutMS”和“socketTimeoutMS”的值为“0”意味着什么?
  • 如何防止长时间运行操作拖慢服务器?
  • “keepAlive”设置的作用是什么?
  • 如果出现意外网络行为,我该怎么办?
  • 如何防止因运行缓慢而延误其他操作?
  • 如何确保连接字符串对副本集有效?

本页包含常见问题及其相应解答。

提示

如果在此页面上找不到问题的回答,请参阅问题和帮助页面,了解后续步骤和更多资源。

如果在连接到 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() 只能关闭不活动的套接字,因此使用此方法无法中断或终止任何正在进行的操作。只有当进程结束时,驱动程序才会关闭这些套接字。

设置
说明
connectTimeoutMS

connectTimeoutMS连接选项,用于设置连接池中的单个连接在超时前与 MongoDB 服务器建立 TCP 连接的时间(以毫秒为单位)。

提示

修改 MongoClient.connect 的允许时间 要建立与 MongoDB 服务器的连接,请改用serverSelectionTimeoutMS 选项。

默认值:30000

socketTimeoutMS
socketTimeoutMS 指定驱动程序在关闭不活动套接字前的等待时间。默认值是永不使套接字超时。此选项仅适用于已连接的套接字。
maxTimeMS
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 Server 4.28100} 版本发布说明 MongoDB Server。

其他操作,如写入操作,即使客户端断开连接,也会继续在 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>,
});

如果将 connectTimeoutMSsocketTimeoutMS 的值设置为 0,应用程序将使用操作系统默认的套接字超时值。

通过指定超时值,可以防止长时间运行的操作拖慢服务器速度。您可以将 maxTimeMS() 方法链接到返回 Cursor 的操作,为特定操作设置超时。

以下示例展示如何将 maxTimeMS() 方法链接到返回 Cursor 的操作:

// Execute a find command
await collection
.find({ $where: "sleep(100) || true" })
.maxTimeMS(50);

keepAlive 是一个 ,用于设置在启动connection-setting TLS keepAlive 之前要等待的毫秒数 在 TCP 套接字上。keepAlive选项将通过定期向 MongoDB 发送探测来保持套接字处于活动状态。 但是,这仅在操作系统支持SO_KEEPALIVE时才有效。

此设置在 Node.js 驱动程序 v5.3 及更高版本中已弃用。

警告

如果防火墙忽略或丢弃 keepAlive 数据包,这可能不起作用

应用程序服务器和 MongoDB 之间存在的内部防火墙经常配置错误,并且在删除套接字连接时过于积极。

如果遇到意外的网络行为,请检查以下事项:

  1. 关闭套接字时,防火墙应发送FIN packet ,以便驱动程序检测到套接字已关闭。

  2. 防火墙应允许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必须使用副本集配置中设置的服务器的确切主机名。 给定副本集的以下配置设置,为了使副本集发现和故障转移正常工作,驱动程序必须有权访问server1server2server3

{
"_id": "testSet",
"version": 1,
"protocolVersion": 1,
"members": [
{
"_id": 1,
"host": "server1:31000"
},
{
"_id": 2,
"host": "server2:31001"
},
{
"_id": 3,
"host": "server3:31002"
}
]
}

如果您无法在此找到问题的答案,请尝试问题和帮助部分中列出的论坛和支持渠道。

后退

多字段连接