FAQ
在此页面上
本页包含常见问题及其相应解答。
提示
如果在此页面上找不到问题的回答,请参阅问题和帮助页面,了解后续步骤和更多资源。
为什么连接 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) keepalive 在 TCP 套接字上。如果启用了 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" } ] }
如果您无法在此找到问题的答案,请尝试问题和帮助部分中列出的论坛和支持渠道。