连接故障排除
本页面针对您在使用 MongoDB Node.js 驱动程序连接到 MongoDB 部署时可能遇到的问题提供了可能的解决方案。
注意
此页面仅解决连接问题。如果您在使用 MongoDB 或驱动程序时遇到任何其他问题,请访问以下资源:
问题和帮助页面,其中包含有关如何报告错误、对驾驶员做出贡献以及查找更多资源的信息
MongoDB Community论坛,用于提问、讨论或获取一般技术支持
连接错误
如果驾驶员无法连接到指定托管,您可能会收到 MongoServerSelectionError
。
以下各节描述您可以采取的可能解决问题的措施。
配置防火墙
确认MongoDB 部署侦听的端口没有被同一网络上的防火墙阻止。 MongoDB默认使用端口 27017
。要学习;了解有关MongoDB使用的默认端口以及如何更改这些端口的更多信息,请参阅MongoDB Server手册中的默认MongoDB端口。
警告
请勿在防火墙中打开端口,除非您确定该端口是 MongoDB 部署使用的端口。
检查网络访问列表
验证您的IP地址是否列在集群的IP访问列表中。您可以在Atlas 用户界面的“网络访问”部分找到IP访问列表。要学习;了解有关如何配置IP访问列表的更多信息,请参阅Atlas文档中的配置IP访问列表条目指南。
ECONNREFUSED 错误
如果驾驶员尝试连接MongoDB实例时连接被拒绝,则会生成类似于以下内容的错误消息:
MongoServerSelectionError: connect ECONNREFUSED <IPv6 address>:<port>
以下各节描述您可以采取的可能解决问题的措施。
确保MongoDB和您的客户端使用相同的IP地址
在 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
的值来减少允许的最大连接数。或者,您可以增加操作系统中的文件限制。要学习;了解有关如何设立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
设置来限制驱动程序尝试建立连接所花费的时间。要了解有关此设置的更多信息,请参阅服务器手册中的超时选项。
应确保 connectTimeoutMS
设置不低于副本集节点的最高网络延迟。如果从节点之一的延迟为 10000 毫秒,则将 connectTimeoutMS
设置为 9000 可防止驱动程序连接到该节点。
以下示例将 connectTimeoutMS
设置为 10000 毫秒。
const client = new MongoClient(uri, { connectTimeoutMS: 10000, });
客户端在运行操作时断开连接
从MongoDB Server版本 4.2 开始,如果客户端断开连接,服务器会终止聚合等运行的操作和查找操作。
其他操作,如写入操作,即使客户端断开连接,也会继续在 MongoDB 服务器上运行。如果应用程序在客户端断开连接后重试操作,这种行为可能会导致数据不一致。
意外网络行为
如果应用程序和 MongoDB 之间的防火墙配置不正确,您可能会遇到意外的网络行为。这些防火墙在删除连接时可能过于激进,从而可能导致意外错误。
确认您的防火墙会执行以下行为:
关闭连接时,防火墙会发送
FIN
数据包,从而告知驱动程序该套接字已关闭。防火墙允许 keepalive 消息。
提示
要学习;了解有关 keepalive 消息的更多信息,请参阅“连接选项”页面中的 keepAlive 连接选项 部分。
副本集的连接字符串错误
传递给驾驶员的连接字符串必须使用与服务器完全相同的主机名,如副本集配置中设立的那样。给定副本集的以下配置设置,为了使副本集发现和故障转移正常工作,驾驶员必须有权访问权限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" } ] }