连接故障排除
在此页面上
本页面针对您在使用 MongoDB Node.js 驱动程序连接到 MongoDB 部署时可能遇到的问题提供了可能的解决方案。
注意
此页面仅解决连接问题。如果您在使用 MongoDB 或驱动程序时遇到任何其他问题,请访问以下资源:
Node.js驾驶员的常见问题解答 ( 常见问题解答 )
问题和帮助页面,其中包含有关报告错误、促进驱动程序发挥作用以及查找其他资源的信息
MongoDB Community 论坛,用于提问、讨论或获取一般技术支持
连接错误
以下错误消息指示驱动程序无法通过指定主机名或端口连接到服务器。多种情况都可能生成此错误消息。在此示例错误消息中,主机名是 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 及更高版本中,在客户端和主机都支持的情况下,DNS 解析器默认使用 IPv6
。例如,如果 MongoDB 使用 IPv4 而您的客户端使用 IPv6,则驱动程序将返回之前的错误消息。
您可以将 MongoDB 部署配置为在通过 mongod
或 mongos
启动时使用 IPv6
模式。有关如何指定 IPv6
模式的更多信息,请参阅服务器手册中的 IP 绑定。
作为替代方案,您可以在客户端中显式使用 IPv4
,具体方法是将 family: 4
指定为 MongoClient 的选项。
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.
以下各节描述您可以采取的可能解决问题的措施。
设置连接字符串
尝试使用以下方法连接到 MongoDB 时,无效的连接字符串是导致身份验证问题的最常见原因:SCRAM-SHA-256
。
提示
有关连接字符串的更多信息,请参阅《连接指南》中的连接 URI。
如果连接字符串包含用户名和密码,请确保格式正确。如果用户名或密码包含以下任何字符,则必须对它们进行百分比编码:
: / ? # [ ] @
以下示例显示如何对“#MyP@assword?”进行百分号编码:
console.log(encodeURIComponent('#MyP@assword?'));
这会产生以下输出:
"%23MyP%40assword%3F"
验证用户是否在身份验证数据库中
要使用用户名和密码,通过 SCRAM-SHA-256
成功对连接进行身份验证,必须在身份验证数据库中定义用户名。默认身份验证数据库是 admin
数据库。要使用不同的数据库进行身份验证,请在连接字符串中指定 authSource
。以下示例指示驱动程序使用 users
作为身份验证数据库:
const { MongoClient } = require("mongodb"); const uri = "mongodb://<username>:<password>@<hostname>:<port>/?authSource=users"; const client = new MongoClient(uri);
您可以尝试使用相同代码连接到本地设备上托管的 MongoDB 实例,检查这是否存在问题。在同一设备上部署无需任何授权即可连接。
发送消息时出错
当您发出请求后驱动程序无法发送命令时,可能会显示以下错误消息:
com.mongodb.MongoSocketWriteException: Exception sending message
以下各节描述您可以采取的可能解决问题的措施。
检查用户权限
确认已使用正确的用户访问 MongoDB 部署。错误中的术语“message”可以是驱动程序发送的命令。如果使用无权发送命令的用户,驱动程序可能会生成此错误。
此外,请确保用户对要发送的消息具有适当的权限。MongoDB 使用基于角色的访问控制 (RBAC) 来控制对 MongoDB 部署的访问。有关如何在 MongoDB 中配置 RBAC 的更多信息,请参阅默认 MongoDB 端口。
配置防火墙
防火墙需要具有开放端口,用于与 MongoDB 实例通信。有关配置防火墙的更多信息,请参阅“连接错误”部分中的配置防火墙。
检查连接数
每个 MongoClient
实例在其连接池中支持最大数量的并发打开连接。您可以配置定义此限制的参数 maxPoolSize
。默认值为 100
。如果打开的连接数已等于 maxPoolSize
,则服务器将等待,直到连接可用。如果此等待时间超过 maxIdleTimeMS
值,驱动程序将返回错误。
有关连接池化工作原理的更多信息,请参阅常见问题解答中的连接池化在节点驱动程序中是如何工作的?。
打开的连接过多
当驱动程序尝试打开连接但已达到最大连接数时,会创建以下错误消息:
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
。有关检查连接数的更多信息,请参阅“错误发送消息”部分中的检查连接数。