本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
连接问题
连接时遇到问题? 以下内容介绍一些常见的情况并以及如何解决这些问题。
主题
无法连接到亚马逊 DocumentDB 终端节点
当你尝试连接到 Amazon DocumentDB 时,以下是你可能收到的最常见的错误消息之一。
connecting to: mongodb://docdb-2018-11-08-21-47-27.cluster-ccuszbx3pn5e.us-east-
1.docdb.amazonaws.com:27017/
2018-11-14T14:33:46.451-0800 W NETWORK [thread1] Failed to connect to
172.31.91.193:27017 after 5000ms milliseconds, giving up.
2018-11-14T14:33:46.452-0800 E QUERY [thread1] Error: couldn't connect to server
docdb-2018-11-08-21-47-27.cluster-ccuszbx3pn5e.us-east-1.docdb.amazonaws.com:27017,
connection attempt failed :
connect@src/mongo/shell/mongo.js:237:13
@(connect):1:6
exception: connect failed
此错误消息通常意味着您的客户端(本示例中的 mongo shell)无法访问 Amazon DocumentDB 终端节点。以下几个原因可能会导致出现此情况:
从公共终端节点连接
您正在尝试直接从笔记本电脑或本地开发计算机连接到 Amazon DocumentDB 集群。
尝试直接从公共终端节点(例如您的笔记本电脑或本地开发机器)连接到 Amazon DocumentDB 集群将失败。Amazon DocumentDB 仅限虚拟私有云 (VPC),目前不支持公共终端节点。因此,您无法从 VPC 之外的笔记本电脑或 Amazon DocumentDB 集群直接连接到 Amazon DocumentDB 集群。
要从亚马逊 VPC 外部连接到 Amazon DocumentDB 集群,您可以使用 SSH 隧道。有关更多信息,请参阅从亚马逊 VPC 外部连接到亚马逊 DocumentDB 集群:此外,如果您的开发环境位于不同的 Amazon VPC 中,您也可以使用 VPC 对等连接,从相同区域或其他区域的另一个 Amazon VPC 连接到您的 Amazon DocumentDB 集群。
跨区域连接
您正在尝试连接到另一个区域的 Amazon DocumentDB 集群。
如果您尝试从集群所在区域以外的区域的 Amazon EC2 实例连接到 Amazon DocumentDB 集群(例如,尝试从美国西部(俄勒冈州)区域(us-west-2)连接到 Amazon EC2 集群,连接将失败。
要验证您的 Amazon DocumentDB 集群的区域,请运行以下命令。区域位于终端节点中。
aws docdb describe-db-clusters \ --db-cluster-identifier sample-cluster \ --query 'DBClusters[*].Endpoint'
此操作的输出将类似于下文。
[
"sample-cluster.node.us-east-1.docdb.amazonaws.com"
]
要验证您的 EC2 实例的区域,请运行以下命令。
aws ec2 describe-instances \ --query 'Reservations[*].Instances[*].Placement.AvailabilityZone'
此操作的输出将类似于下文。
[
[
"us-east-1
a"
]
]
从不同的亚马逊 VPC 连接
您正在尝试从与您的集群部署到的 Amazon VPC 不同的 VPC 连接到 Amazon DocumentDB 集群。
如果您的 Amazon DocumentDB 集群和Amazon EC2 实例位于同一Amazon Web Services 区域个 Amazon VPC 中,但不在同一个亚马逊 VPC 中,则您无法直接连接到您的 Amazon DocumentDB 集群,除非在两个 Amazon VPC 之间启用 VPC 对等连接。
要验证您的 Amazon DocumentDB 实例的 Amazon VPC,请运行以下命令。
aws docdb describe-db-instances \ --db-instance-identifier sample-instance \ --query 'DBInstances[*].DBSubnetGroup.VpcId'
要验证您的 Amazon EC2 实例的 Amazon VPC,请运行以下命令。
aws ec2 describe-instances \ --query 'Reservations[*].Instances[*].VpcId'
安全组阻止入站连接
您正在尝试连接到 Amazon DocumentDB 集群,并且该集群的安全组不允许在集群的端口(默认端口:27017)上进行入站连接。
假设您的 Amazon DocumentDB 集群和 Amazon EC2 实例都在同一个区域和 Amazon VPC 中,并且使用相同的 Amazon VPC 安全组。如果您无法连接到 Amazon DocumentDB 集群,则可能的原因是您的集群的安全组(即防火墙)不允许在您为 Amazon DocumentDB 集群选择的端口(默认端口为 27017)上进行入站连接。
要验证您的 Amazon DocumentDB 集群的端口,请运行以下命令。
aws docdb describe-db-clusters \ --db-cluster-identifier sample-cluster \ --query 'DBClusters[*].[DBClusterIdentifier,Port]'
要为集群获取 Amazon DocumentDB 安全组,请运行以下命令。
aws docdb describe-db-clusters \ --db-cluster-identifier sample-cluster \ --query 'DBClusters[*].[VpcSecurityGroups[*],VpcSecurityGroupId]'
要查看您的安全组的入站规则,请参阅 Amazon EC2 文档中的以下主题:
Java Mongo 驱动程序读取首选项问题
不支持客户端读取首选项,有些客户端在故障转移后除非重新启动,否则无法写入 Amazon DocumentDB。
这个问题最初在 Java Mongo Driver 3.7.x 中发现,当客户端使用MongoClientSettings
和建立与 Amazon DocumentDB 的连接时,就会发生在链接该方法时。applyToClusterSettings
可以使用几种不同的方法定义MongoClient群集设置,例如hosts()
requiredReplicaSetName()
、和mode()
。
如果客户端在hosts()
方法中仅指定一台主机,则将模式设置为ClusterConnectionMode.SINGLE
而不是。ClusterConnectionMode.MULTIPLE
这会导致客户端忽略读取首选项,仅连接到中配置的服务器hosts()
。因此,即使客户端设置按如下方式初始化,所有读取仍会转到主服务器而不是辅助服务器。
final ServerAddress serverAddress0 = new ServerAddress("cluster-endpoint", 27317)); final MongoCredential credential = MongoCredential.createCredential("xxx", "admin", "xxxx".toCharArray()); final MongoClientSettings settings = MongoClientSettings.builder() .credential(credential) .readPreference(ReadPreference.secondaryPreferred()) .retryWrites(false) .applyToSslSettings(builder -> builder .enabled(false)) .applyToClusterSettings(builder -> builder.hosts( Arrays.asList(serverAddress0 )) .requiredReplicaSetName("rs0")) .build(); MongoClient mongoClient = MongoClients.create(settings);
故障转移案例
使用上述客户端连接设置,如果集群写入器终端节点出现故障转移和 DNS 记录更新延迟,则客户端仍会尝试向旧写入器(故障转移后现在是读取器)发出写入操作。这会导致服务器端错误(不是 master),Java 驱动程序无法正确处理该错误(此问题仍在调查中)。因此,例如,在应用程序服务器重新启动之前,客户机可能处于不良状态。
有两种解决方法:
-
通过连接字符串连接到 Amazon DocumentDB 的客户端不会出现此问题,因为在设置读取首选项
MULTIPLE
时ClusterConnectionMode
将设置为。MongoClientURI mongoClientURI = new MongoClientURI("mongodb://usr:pass:cluster-endpoint:27317/test?ssl=false&replicaSet=rs0&readpreference=secondaryPreferred"); MongoClient mongoClient = MongoClients.create(mongoClientURI.getURI());
或者使用带有该
applyConnectionString
方法的MongoClientSettings
生成器。final MongoClientSettings settings = MongoClientSettings.builder() .credential(credential) .applyConnectionString(new ConnectionString("usr:pass:cluster-endpoint:27317/test?ssl=false&replicaSet=rs0&readpreference=secondaryPreferred")) .retryWrites(false) .applyToSslSettings(builder → builder .enabled(false)) .build(); MongoClient mongoClient = MongoClients.create(settings);
-
明确设置
ClusterConnectionMode
为MULTIPLE
。只有在使用applyToClusterSettings
和时才需要这样做hosts().size() == 1
。final ServerAddress serverAddress0 = new ServerAddress("cluster-endpoint", 27317)); final MongoCredential credential = MongoCredential.createCredential("xxx","admin", "xxxx".toCharArray()); final MongoClientSettings settings = MongoClientSettings.builder() .credential(credential) .readPreference(ReadPreference.secondaryPreferred()) .retryWrites(false) .applyToSslSettings(builder → builder .enabled(false)) .applyToClusterSettings(builder → builder .hosts(Arrays.asList(serverAddress0)) .requiredReplicaSetName("rs0")) .mode(ClusterConnectionMode.MULTIPLE)) .build(); MongoClient mongoClient = MongoClients.create(settings);
测试与Amazon DocumentDB 实例的连接
您可以使用常见的 Linux 或 Windows 工具测试与集群的连接。
从 Linux 或 Unix 终端测试此连接,方法为输入以下命令(将 cluster-endpoint
替换为终端节点并将 port
替换为实例的端口)。
nc -zv cluster-endpoint port
以下是示例操作和返回值的示例:
nc -zv docdbTest.d4c7nm7stsfc0.us-west-2.docdb.amazonaws.com 27017 Connection to docdbTest.d4c7nm7stsfc0.us-west-2.docdb.amazonaws.com 27017 port [tcp/*] succeeded!
连接到无效的端点
连接到 Amazon DocumentDB 集群且您使用的集群终端节点无效时,会出现类似以下内容的错误。
mongo --ssl \ --host sample-cluster.node.us-east-1.docdb.amazonaws.com:27017 \ --sslCAFile rds-combined-ca-cn-bundle.pem \ --username <user-name> \ --password <password>
该输出类似于以下示例:
MongoDB shell version v3.6
connecting to: mongodb://sample-cluster.node.us-east-1.docdb.amazonaws.com:27017/
2018-11-14T17:21:18.516-0800 I NETWORK [thread1] getaddrinfo("sample-cluster.node.us-east-1.docdb.amazonaws.com") failed:
nodename nor servname provided, or not known 2018-11-14T17:21:18.537-0800 E QUERY [thread1] Error: couldn't initialize
connection to host sample-cluster.node.us-east-1.docdb.amazonaws.com, address is invalid :
connect@src/mongo/shell/mongo.js:237:13@(connect):1:6
exception: connect failed
要获取集群的有效终端节点,请运行以下命令:
aws docdb describe-db-clusters \ --db-cluster-identifier sample-cluster \ --query 'DBClusters[*].[Endpoint,Port]'
要获取实例的有效终端节点,请运行以下命令:
aws docdb describe-db-instances \ --db-instance-identifier sample-instance \ --query 'DBInstances[*].[Endpoint.Address,Endpoint.Port]'
有关更多信息,请参阅了解亚马逊 DocumentDB: