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()仅关闭不活动的套接字,而不会直接终止任何正在进行的操作。 仅当关联操作完成时,驾驶员才会关闭任何正在使用的套接字。 但是, MongoClient.close()方法会关闭现有会话和事务,这可能会间接影响正在进行的操作和打开的游标的行为。

设置
说明

connectTimeoutMS

connectTimeoutMS 是一个连接选项,用于设置连接池的单个连接在超时之前与MongoDB Server建立 TCP 连接的时间(以毫秒为单位)。要修改 MongoClient.connect 与MongoDB Server建立连接所允许的时间,请改用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 服务器上运行。如果应用程序在客户端断开连接后重试操作,这种行为可能会导致数据不一致。

如果出现异常网络行为或是 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连接选项指定是否启用 传输控制协议 (TCP) keepalive 在 TCP 套接字上。如果启用了 keepalives,驱动程序会定期向 MongoDB 部署发送 ping 来检查连接是否处于活动状态。 仅当操作系统支持SO_KEEPALIVE套接字选项时,此功能才有效。

keepAliveInitialDelay 选项指定了驱动程序在启动 keepalive 之前等待的毫秒数。

5.3 驱动程序版本已弃用这些选项。从驱动程序 6.0 版开始,keepAlive 选项永久设置为 truekeepAliveInitialDelay 设置为 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必须使用副本集配置中设置的服务器的确切主机名。 给定副本集的以下配置设置,为了使副本集发现和故障转移正常工作,驱动程序必须有权访问server1server2server3

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

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

后退

多字段连接