连接故障排除
本页内容
本页面提供了使用MongoDB Node.js驱动连接到MongoDB部署时可能遇到的问题的潜在解决方案。
注意
本页面仅针对连接问题。如果您遇到MongoDB或驱动程序的其他问题,请访问以下资源
有关Node.js驱动程序的常见问题解答 (FAQ)
有关问题与帮助的页面,该页面包含有关报告错误、为驱动程序做出贡献和查找更多资源的详细信息
有关Node.js驱动程序的MongoDB社区论坛用于提问、讨论或一般技术支持
连接错误
以下错误信息表示驱动程序无法连接到指定主机名或端口的服务器。多种情况可以生成此错误信息。在此示例错误信息中,主机名是127.0.0.1
,端口号是27017
Error: couldn't connect to server 127.0.0.1:27017
以下部分描述了您可以采取的操作来解决此问题。
检查您的连接字符串
验证连接字符串中的主机名和端口号是否都准确。MongoDB实例的默认端口号为27017
,但您可以将MongoDB配置为在其他端口上进行通信。
配置您的防火墙
验证您的MongoDB部署所监听的端口不会被同一网络中的防火墙阻止。MongoDB默认使用端口27017
。有关MongoDB使用的默认端口以及如何更改端口的更多信息,请参阅默认MongoDB端口。
警告
除非您确定它正是您的MongoDB部署所使用的端口,否则不要在防火墙中打开端口。
ECONNREFUSED 错误
如果驱动程序尝试连接到MongoDB实例时连接被拒绝,则会生成此错误消息
MongoServerSelectionError: connect ECONNREFUSED <IPv6 address>:<port>
以下部分描述了您可以采取的操作来解决此问题。
确保MongoDB和您的客户端使用相同的协议
在 Node.js v17 及更高版本中,当客户端和主机都支持 IPv6 时,DNS 解析器默认使用 IPv6
。例如,如果 MongoDB 使用 IPv4 而您的客户端使用 IPv6,驱动程序将返回之前的错误消息。
您可以通过在启动 mongod
或 mongos
时配置 MongoDB 部署使用 IPv6
模式。有关如何指定 IPv6
模式的更多信息,请参阅服务器手册中的 IP 绑定。
作为替代方案,您可以通过指定 family: 4
作为 MongoClient 的 选项,显式地在客户端使用 IPv4
。
const client = new MongoClient(uri, { family: 4, });
ECONNRESET 错误
如果驱动程序在调用 client.connect()
时连接被重置,将生成此错误消息
MongoServerSelectionError: connect ECONNRESET ::<IP address>:<port>
以下部分描述了一种可能有助于解决问题的方法。
控制文件描述符数量
文件描述符是与打开的进程相关联的唯一标识符。在大多数操作系统中,每个从驱动程序发出的打开连接都与文件描述符相关联。操作系统通常对单个进程使用的文件描述符数量有限制。如果连接数量超过此限制,可能会发生 ECONNRESET
错误。
您可以通过设置 maxPoolSize
来设置最大连接数。为了解决此错误,您可以减少最大允许连接数,通过设置 maxPoolSize
的值。或者,您也可以增加操作系统的文件描述符限制。
警告
在更改操作系统的配置时请始终谨慎。
认证错误
如果Node.js驱动程序没有正确配置认证,则可能无法连接到MongoDB实例。如果您使用 SCRAM-SHA-256
进行认证,并且驱动程序无法连接,驱动程序可能会抛出一个类似于以下消息的错误
Command failed with error 18 (AuthenticationFailed): 'Authentication failed.' on server <hostname>:<port>.
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时最常见的认证问题原因。
提示
有关连接字符串的更多信息,请参阅连接指南中的连接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);
您可以通过尝试使用相同代码连接到本地机器上托管的MongoDB实例来检查这是否是问题。同一台机器上的部署不需要任何授权即可连接。
错误发送消息
当驱动程序在您发出请求后无法发送命令时,可能会显示以下错误消息
com.mongodb.MongoSocketWriteException: Exception sending message
以下部分描述了您可以采取的操作来解决此问题。
检查用户权限
请确认您已使用正确的用户访问MongoDB部署。错误中的“消息”可以是驱动程序发送的命令。如果您使用的是没有发送命令权限的用户,驱动程序可能会生成此错误。
同时确保用户具有发送消息所需的适当权限。MongoDB使用基于角色的访问控制(RBAC)来控制对MongoDB部署的访问。有关如何在MongoDB中配置RBAC的更多信息,请参阅默认MongoDB端口。
配置您的防火墙
防火墙需要开放一个端口以与MongoDB实例进行通信。有关配置防火墙的更多信息,请参阅连接错误部分中的配置您的防火墙。
检查连接数
每个MongoClient
实例在其连接池中支持的最大并发打开连接数。您可以通过配置参数maxPoolSize
来定义此限制。默认值为100
。如果已打开的连接数等于maxPoolSize
,则服务器等待直到有连接变得可用。如果此等待时间超过maxIdleTimeMS
值,驱动程序将返回错误。
有关连接池如何工作的更多信息,请参阅FAQ中的Node驱动程序中连接池是如何工作的?。
打开连接过多
当驱动程序尝试打开连接但达到最大连接数时,它将创建以下错误消息
connection refused because too many open connections
以下部分描述了一种可能有助于解决问题的方法。
检查连接数量
为了创建更多的开放连接,增加 maxPoolSize
的值。有关检查连接数量的更多信息,请参阅错误发送消息部分的 检查连接数量。
超时错误
当网络无法快速将请求从驱动程序发送到服务器时,它可能会超时。当这种情况发生时,您可能会收到类似以下消息的错误
timed out while checking out a connection from connection pool: context canceled
如果您收到此错误,请尝试以下操作以解决问题。
设置 connectTimeoutMS
当驱动程序无法在过长的时间内建立连接(因为它尝试连接无法到达的副本集节点)时,它可能会挂起。您可以使用 connectTimeMS
设置来限制驱动程序尝试建立连接的时间。有关此设置的更多信息,请参阅服务器手册中的 超时选项。
确保 connectTimeoutMS
设置不低于集合成员的最高网络延迟。如果集合的一个辅助成员的延迟为 10000 毫秒,将 connectTimeoutMS
设置为 9000 将防止驱动程序连接到该成员。
以下示例将 connectTimeoutMS
设置为 10000 毫秒。
const client = new MongoClient(uri, { connectTimeoutMS: 10000, });
检查连接数
到服务器的连接数可能超过 maxPoolSize
。有关检查连接数的更多信息,请参阅错误发送消息部分中的检查连接数。