Docs 菜单

连接故障排除

此页面为您在使用 MongoDB Java 驱动程序连接到 MongoDB 部署时可能遇到的问题提供了可能的解决方案。

注意

本页仅解决连接问题。 如果在使用MongoDB或驾驶员时遇到其他问题,请访问以下资源:

如果您在尝试连接到服务器时出现问题,Java 驱动程序会返回一条错误消息。如果此错误类似如下消息,则表明驱动程序无法连接到 MongoDB 部署:

Error: couldn't connect to server 127.0.0.1:27017

以下各节介绍可能有助于解决问题的方法。

确认连接字符串中的主机名和端口号都准确无误。在此错误消息示例中,主机名为 127.0.0.1,端口为 27017。MongoDB Server 实例的默认端口值为 27017,但您可以将 MongoDB 配置为监听另一个端口。

连接副本集时,请在连接字符串中包含所有副本集主机。用逗号分隔连接字符串中的每个主机。这样,即使其中一个主机无法访问,驱动程序也能建立连接。

如要了解如何指定多个副本集主机,请参阅《连接指南》中的连接到副本集部分。

如果您的 MongoDB 部署托管在防火墙后面,请确保防火墙中开启 MongoDB 所监听的端口。如果您的部署监听默认网络端口,请确保端口 27017 在防火墙中处于开启状态。如果您的部署在不同的端口进行监听,请确保在防火墙上开启相应的端口。

警告

不要打开防火墙端口,除非您确定它是 MongoDB 部署监听的端口。

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

To learn more about how connection pooling works in the driver, see the Connection Pools page.

如果授权配置不正确,Java 驱动程序可能无法连接到 MongoDB 部署。在这些情况下,驱动程序会引发一条类似如下消息的错误消息:

Command failed with error 18 (AuthenticationFailed): 'Authentication failed.' on server localhost:27017.

以下各部分介绍了可能有助于解决问题的方法。

身份验证问题的最常见原因之一是 MongoDB 连接字符串中的凭证格式无效。

提示

有关如何使用连接字符串的更多信息,请参阅《连接指南》中的连接 URI

如果连接字符串包含用户名和密码,请确保其格式正确。

注意

如果您的用户名或密码包含以下任何字符,则必须 进行百分号编码 it:

: / ? # [ ] @

在连接字符串中使用百分比编码的用户名和密码。

确保您的凭证和身份验证机制正确。您可以在连接字符串的选项中指定身份验证凭证。

如果使用 MongoCredential 构造客户端,构建器方法将对应身份验证机制。如下代码显示了 SCRAM-SHA-256 身份验证机制的构建器方法:

MongoCredential credential = MongoCredential.createScramSha256Credential("<db_username>", "<authenticationDb>", "<dbpassword>");

To learn more about specifying authentication mechanisms, see the 身份验证机制 section.

使用基于用户名和密码的身份验证方法时,必须在身份验证数据库中定义用户名。

默认身份验证数据库是 admin 数据库。如要使用不同的数据库进行身份验证,请在连接字符串中指定 authSource 选项。

以下示例指示 MongoDB 使用 users 数据库作为身份验证数据库:

MongoClient mongoClient = MongoClients.create("mongodb://<db_username>:<db_password>@<hostname>:<port>/?authSource=users");

Java 驱动程序可能无法解析您的 DNS 连接。出现这种情况时,您可能会收到一条类似如下消息的错误消息:

com.mongodb.MongoSocketWriteException: Exception sending message

如果驱动程序报告此错误,请尝试以下部分中的方法来解决问题。

如果您正在连接到 MongoDB Atlas,而您的驱动程序无法找到 Atlas 数据库部署的 DNS 主机,该数据库部署则可能会暂停或删除。

确保 Atlas 中存在数据库部署。 如果集群暂停,您可以在 Atlas 用户界面或Atlas 命令行界面中恢复集群。

要了解如何恢复集群,请参阅 Atlas 文档中的恢复一个集群

验证连接字符串中的网络地址或主机名是否准确。

如果您的部署托管在MongoDB Atlas上,则可以按照连接到集群教程来查找Atlas连接string 。

如果您使用 Java 版本8或更早版本,则可能需要将证书添加到信任存储区。 您可以升级到更高版本的 JDK,或阅读 Atlas 文档中的安全常见问题解答说明,了解有关如何添加证书的信息。

当您通过驱动程序向服务器发送消息时,消息有时需要一段时间才会响应。当出现这种情况时,您可能会收到一条类似以下消息之一的错误消息:

Timed out after 30000 ms while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}.
No server chosen by ReadPreferenceServerSelector{readPreference=primary} from cluster description

如果收到这些错误之一,请尝试采用以下方法来解决问题。

maxConnectionTimeoutMS 选项表示 Java 驱动程序在超时之前等待连接的时间。默认值为 10000。如果您希望驱动程序永不超时,可以增大此值或者将其设置为 0

考虑设置 maxConnectionLifeTimemaxConnectionIdleTime。这两个参数将配置驱动程序保持与 MongoDB 实例连接的时间。有关这些参数的更多信息,请参阅连接池设置

即使某些服务器可用,您的应用程序也可能无法完成请求,从而导致驱动程序返回服务器选择超时异常。

此异常的类型为MongoTimeoutException 。 以下示例展示了当您尝试向无法访问主节点的副本集发送请求时出现的异常:

com.mongodb.MongoTimeoutException:
Timed out while waiting for a server that matches ReadPreferenceServerSelector{readPreference=primary}.
Client view of cluster state is
{type=REPLICA_SET,
servers=[
{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}},
{address=localhost:27018, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}},
{address=localhost:27019, type=REPLICA_SET_SECONDARY, roundTripTime=15.0 ms, state=CONNECTED}
]
}

该错误包括描述每个节点连接状态的集群状态视图,这可以帮助您识别连接问题的根源。

在前面的错误中,唯一连接的服务器localhost:27019是从节点。 因此,由于驱动程序无法选择满足primary读取偏好的服务器,因此请求超时。 在这种情况下,如果将读取偏好设置为secondarysecondaryPreferrednearest ,您仍然可以对连接的从节点执行读取操作。

You can also specify the serverSelectionTimeoutMS connection option to adjust the amount of time in which the driver must select a server. To learn more, see the 群集设置 guide.

本节将显示不属于更广泛类别的连接错误。

INFO: Exception in monitor thread while connecting to server ssc-cluster-01-shard-00-02.9cbnp.mongodb.net:27017

此日志行表示持续检查每个副本集成员或 mongos服务器状态的监控未能联系其中一个节点或服务器。这是服务器维护操作期间的预期消息,可以安全地忽略。

javax.net.ssl.SSLHandshakeException: extension (5) should not be presented in certificate_request

这是某些版本的 JDK 中存在的一个已知问题,当尝试使用 TLS 1.3 协议进行连接时,此问题可能会出现。

如果在连接到 MongoDB 实例或集群时遇到此错误,请将 JDK 更新到以下补丁版本之一或更高版本:

  • JDK 11.0.7

  • JDK 13.0.3

  • JDK 14.0.2

要了解有关此问题的更多信息,请参阅 OpenJDK Bug 系统跟踪器问题中的问题描述

虽然与特定的错误消息无关,但本节包含的信息可帮助解决连接问题。

可以使用 -Djavax.net.debug=all 系统属性启用与所有连接(包括使用 TLS/SSL 建立的那些连接)相关的调试级日志记录。

启用调试级别的日志记录可以帮助您诊断连接问题的根本问题。 要了解有关 TLS/SSL 日志记录消息的更多信息,请参阅 调试 SSL/TLS 连接 Java 文档。