Docs 菜单
Docs 主页
/ / /
Node.js 驱动程序
/

连接故障排除

本页面针对您在使用 MongoDB Node.js 驱动程序连接到 MongoDB 部署时可能遇到的问题提供了可能的解决方案。

注意

此页面仅解决连接问题。如果您在使用 MongoDB 或驱动程序时遇到任何其他问题,请访问以下资源:

  • 问题和帮助页面,其中包含有关如何报告错误、对驾驶员做出贡献以及查找更多资源的信息

  • MongoDB Community论坛,用于提问、讨论或获取一般技术支持

如果驾驶员无法连接到指定托管,您可能会收到 MongoServerSelectionError

以下各节描述您可以采取的可能解决问题的措施。

确认MongoDB 部署侦听的端口没有被同一网络上的防火墙阻止。 MongoDB默认使用端口 27017。要学习;了解有关MongoDB使用的默认端口以及如何更改这些端口的更多信息,请参阅MongoDB Server手册中的默认MongoDB端口

警告

请勿在防火墙中打开端口,除非您确定该端口是 MongoDB 部署使用的端口。

验证您的IP地址是否列在集群的IP访问列表中。您可以在Atlas 用户界面的“网络访问”部分找到IP访问列表。要学习;了解有关如何配置IP访问列表的更多信息,请参阅Atlas文档中的配置IP访问列表条目指南。

如果驾驶员尝试连接MongoDB实例时连接被拒绝,则会生成类似于以下内容的错误消息:

MongoServerSelectionError: connect ECONNREFUSED <IPv6 address>:<port>

以下各节描述您可以采取的可能解决问题的措施。

在 Node.js v17 及更高版本中,在客户端和主机都支持的情况下,DNS 解析器默认使用 IPv6。例如,如果 MongoDB 使用 IPv4 而您的客户端使用 IPv6,则驱动程序将返回之前的错误消息。

您可以将 MongoDB 部署配置为在通过 mongodmongos 启动时使用 IPv6 模式。有关如何指定 IPv6 模式的更多信息,请参阅服务器手册中的 IP 绑定

作为替代方案,您可以通过将IPv4 指定为family: 4 MongoClient 的选项来在客户端中显式使用 。

const client = new MongoClient(uri, {
family: 4,
});

如果在驾驶员调用 client.connect() 时重置连接,则会生成类似于以下内容的错误消息:

MongoServerSelectionError: connect ECONNRESET ::<IP address>:<port>

以下部分介绍一种可能有助于解决此问题的方法。

文件描述符是与打开的进程关联的唯一标识符。在大多数操作系统中,来自驱动程序的每个打开的连接都与文件描述符相关联。操作系统通常对单个进程使用的文件描述符的数量有限制。如果连接数超过此限制,则可能会发生 ECONNRESET 错误。

您可以通过设置 maxPoolSize 来设立最大连接数。要解决此错误,您可以通过设置 maxPoolSize 的值来减少允许的最大连接数。或者,您可以增加操作系统中的文件限制。要学习;了解有关如何设立maxPoolSize 的更多信息,请参阅 maxPoolSize 的API文档。

警告

更改操作系统配置时务必始终保持谨慎。

如果授权配置不正确,Node.js 驱动程序可能无法连接到 MongoDB 实例。如果您使用 SCRAM-SHA-256 进行身份验证并且驱动程序无法连接,则驱动程序可能会引发类似于以下消息之一的错误消息:

MongoServerError: bad auth : authentication failed
connection() error occurred during connection handshake: auth error:
sasl conversation error: unable to authenticate using mechanism
"SCRAM-SHA-256": (AuthenticationFailed) Authentication failed.

以下各节描述您可以采取的可能解决问题的措施。

当您尝试使用 SCRAM-SHA-256 连接到MongoDB时,无效的连接字符串是导致身份验证问题的最常见原因。

提示

有关连接字符串的更多信息,请参阅 Connection Guide 中的 Connection URI 部分。

如果连接字符串包含用户名和密码,请确保格式正确。如果用户名或密码包含以下任何字符,则必须对它们进行百分比编码

: / ? # [ ] @

以下示例显示如何对“#MyP@assword?”进行百分号编码:

console.log(encodeURIComponent('#MyP@assword?'));

这会产生以下输出:

"%23MyP%40assword%3F"

要使用用户名和密码,通过 SCRAM-SHA-256 成功对连接进行身份验证,必须在身份验证数据库中定义用户名。默认身份验证数据库是 admin 数据库。要使用不同的数据库进行身份验证,请在连接字符串中指定 authSource。以下示例指示驱动程序使用 users 作为身份验证数据库:

const { MongoClient } = require("mongodb");
const uri = "mongodb://<db_username>:<db_password>@<hostname>:<port>/?authSource=users";
const client = new MongoClient(uri);

当您发出请求后驱动程序无法发送命令时,可能会显示以下错误消息:

com.mongodb.MongoSocketWriteException: Exception sending message

以下各节描述您可以采取的可能解决问题的措施。

确认已使用正确的用户访问 MongoDB 部署。错误中的术语“message”可以是驱动程序发送的命令。如果使用无权发送命令的用户,驱动程序可能会生成此错误。

此外,请确保用户对要发送的消息具有适当的权限。MongoDB 使用基于角色的访问控制 (RBAC) 来控制对 MongoDB 部署的访问。有关如何在 MongoDB 中配置 RBAC 的更多信息,请参阅默认 MongoDB 端口

防火墙需要具有开放端口,用于与 MongoDB 实例通信。有关配置防火墙的更多信息,请参阅“连接错误”部分中的配置防火墙

每个 MongoClient 实例在其连接池中支持最大数量的并发打开连接。您可以配置定义此限制的参数 maxPoolSize。默认值为 100。如果打开的连接数已等于 maxPoolSize,则服务器将等待,直到连接可用。如果此等待时间超过 maxIdleTimeMS 值,驱动程序将返回错误。

有关连接池化工作原理的更多信息,请参阅连接池页面中的连接池概述

当网络无法快速将请求从驱动程序传送到服务器时,就会出现超时。出现这种情况时,您可能会收到类似以下的错误信息:

timed out while checking out a connection from connection pool: context canceled

如果收到此错误,请尝试以下操作来解决问题。

驱动程序在无法建立连接时可能会挂起,因为尝试访问无法访问的副本集节点需要很长时间。您可以使用 connectTimeoutMS 设置来限制驱动程序尝试建立连接所花费的时间。要了解有关此设置的更多信息,请参阅服务器手册中的超时选项

应确保 connectTimeoutMS 设置不低于副本集节点的最高网络延迟。如果从节点之一的延迟为 10000 毫秒,则将 connectTimeoutMS 设置为 9000 可防止驱动程序连接到该节点。

以下示例将 connectTimeoutMS 设置为 10000 毫秒。

const client = new MongoClient(uri, {
connectTimeoutMS: 10000,
});

从MongoDB Server版本 4.2 开始,如果客户端断开连接,服务器会终止聚合等运行的操作和查找操作。

其他操作,如写入操作,即使客户端断开连接,也会继续在 MongoDB 服务器上运行。如果应用程序在客户端断开连接后重试操作,这种行为可能会导致数据不一致。

如果应用程序和 MongoDB 之间的防火墙配置不正确,您可能会遇到意外的网络行为。这些防火墙在删除连接时可能过于激进,从而可能导致意外错误。

确认您的防火墙会执行以下行为:

  • 关闭连接时,防火墙会发送 FIN 数据包,从而告知驱动程序该套接字已关闭。

  • 防火墙允许 keepalive 消息。

提示

要学习;了解有关 keepalive 消息的更多信息,请参阅“连接选项”页面中的 keepAlive 连接选项 部分。

传递给驾驶员的连接字符串必须使用与服务器完全相同的主机名,如副本集配置中设立的那样。给定副本集的以下配置设置,为了使副本集发现和故障转移正常工作,驾驶员必须有权访问权限server1server2server3

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

后退

选择连接目标