连接故障排除
本页内容
本页面提供了在使用MongoDB Java驱动连接到MongoDB部署时可能遇到的问题的潜在解决方案。
注意
本页面仅解决连接问题。如果您在使用MongoDB或驱动时遇到其他问题,请访问以下资源
的问题 & 帮助页面,了解如何报告错误、为驱动程序做出贡献以及找到更多资源
的MongoDB 社区论坛用于提问、讨论或一般技术支持
的常见问题解答(FAQ)页面,了解有关Java驱动的常见问题答案
服务器连接错误
当尝试连接到服务器时发生问题时,Java驱动会返回一个错误消息。如果此错误消息类似于以下消息,则表示驱动程序无法连接到MongoDB部署
Error: couldn't connect to server 127.0.0.1:27017
以下各节描述了可能有助于解决问题的方法。
检查连接字符串
请验证连接字符串中的主机名和端口号是否准确。在示例错误消息中,主机名是127.0.0.1
,端口号是27017
。MongoDB服务器实例的默认端口号为27017
,但您可以配置MongoDB监听其他端口。
当连接到副本集时,请在连接字符串中包含所有副本集主机。使用逗号分隔连接字符串中的每个主机。这允许驱动程序在其中一个主机不可达时建立连接。
有关指定多个副本集主机的说明,请参阅连接指南中的连接到副本集部分。
配置防火墙
如果您的MongoDB部署位于防火墙后面,请确保MongoDB监听的端口在防火墙中已打开。如果您的部署监听默认网络端口,请确保防火墙中已打开端口27017
。如果您的部署监听不同的端口,请确保该端口在防火墙中已打开。
警告
除非您确定它是MongoDB部署监听的端口,否则不要打开防火墙端口。
检查连接数
每个MongoClient
实例都支持连接池中最大并发打开连接数。配置参数maxPoolSize
定义了这个值,默认设置为100
。如果打开的连接数等于maxPoolSize
,则服务器会等待直到有连接可用。如果等待时间超过maxIdleTimeMS
值,则驱动程序会返回错误。
要了解更多关于驱动程序中连接池如何工作,请参阅FAQ中的Java驱动程序中的连接池是如何工作的?。
认证错误
如果Java驱动程序没有正确配置授权,可能无法连接到MongoDB部署。在这些情况下,驱动程序会引发类似于以下消息的错误:
Command failed with error 18 (AuthenticationFailed): 'Authentication failed.' on server localhost:27017.
以下部分描述了可能有助于解决该问题的方法。
检查凭据格式
认证问题最常见的原因之一是 MongoDB 连接字符串中凭据格式无效。
提示
有关连接字符串的更多信息,请参阅连接指南中的 连接 URI。
如果您的连接字符串包含用户名和密码,请确保它们格式正确。
注意
验证认证机制
确保您的凭据和认证机制正确。您可以在连接字符串的选项中指定您的认证凭据。
如果您使用 MongoCredential
构建客户端,则构建方法对应于认证机制。以下代码显示了 SCRAM-SHA-256
认证机制的构建方法
MongoCredential credential = MongoCredential.createScramSha256Credential("<db_username>", "<authenticationDb>", "<dbpassword>");
验证用户是否在身份验证数据库中
当使用基于用户名和密码的身份验证方法时,用户名必须在身份验证数据库中定义。
默认身份验证数据库是admin
数据库。若要使用不同的数据库进行身份验证,请在连接字符串中指定authSource
选项。
以下示例指导MongoDB使用users
数据库作为身份验证数据库
MongoClient mongoClient = MongoClients.create("mongodb://<db_username>:<db_password>@<hostname>:<port>/?authSource=users");
DNS解析错误
Java驱动可能无法解析您的DNS连接。当这种情况发生时,您可能会收到类似于以下错误消息的提示
com.mongodb.MongoSocketWriteException: Exception sending message
如果驱动程序报告此错误,请尝试以下部分中的方法来解决该问题。
检查数据库部署可用性
如果您正在连接到MongoDB Atlas且您的驱动程序找不到Atlas数据库部署的DNS主机,数据库部署可能已暂停或被删除。
请确保数据库部署存在于Atlas中。如果集群已暂停,您可以在Atlas UI或Atlas命令行界面中恢复集群。
要了解如何恢复集群,请参阅Atlas文档中的恢复一个集群。
检查网络地址
请确认您的连接字符串中的网络地址或主机名是否准确。
如果您的部署托管在MongoDB Atlas上,您可以按照连接到您的集群教程找到您的Atlas连接字符串。
安全证书错误
如果您使用Java版本8或更早版本,可能需要在信任存储中添加证书。您可以选择升级到较新版本的JDK,或者阅读Atlas文档中的安全FAQ以获取添加证书的说明。
超时错误
当您通过驱动程序向服务器发送消息时,有时消息响应需要一段时间。在这种情况下,您可能会收到类似于以下消息的错误信息
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
maxConnectionTimeoutMS
选项表示 Java 驱动程序在超时之前等待连接的时间。默认值为 10000
。您可以增加此值或将它设置为 0
,如果想让驱动程序永远不会超时。
设置 maxConnectionLifeTime
和 maxConnectionIdleTime
考虑设置 maxConnectionLifeTime
和 maxConnectionIdleTime
。这些参数配置了驱动程序维护到 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
读取偏好的服务器。在这种情况下,如果你将读取偏好设置为 secondary
、secondaryPreferred
或 nearest
,你仍然可以对连接的从节点执行读取操作。
你还可以指定 serverSelectionTimeoutMS
连接选项来调整驱动器选择服务器所需的时间。有关更多信息,请参阅连接选项指南。
其他错误
本节展示了不属于更广泛类别的连接错误。
监控线程异常
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系统跟踪器中的问题描述。
调试技巧
虽然与特定错误消息无关,但本节包含有助于解决连接问题过程的信息。
关于TLS/SSL的详细日志记录
您可以使用系统属性 -Djavax.net.debug=all
来启用与所有连接相关的调试级别日志记录,包括使用TLS/SSL建立的连接。
启用调试级别日志记录可以帮助您诊断连接问题的根本原因。有关TLS/SSL日志消息的更多信息,请参阅 调试SSL/TLS连接 Java文档。