

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 排除连接问题
<a name="troubleshooting.connecting"></a>

连接遇到问题？ 以下是一些常见场景及如何解决。

**主题**
+ [无法连接到 Amazon DocumentDB 端点](#troubleshooting-connecting)
+ [测试与 Amazon DocumentDB 实例的连接](#troubleshooting.testing-connection)
+ [连接到无效终端节点](#troubleshooting.invalid-endpoint)
+ [影响连接数的驱动程序配置](#troubleshooting.driver.config)

## 无法连接到 Amazon DocumentDB 端点
<a name="troubleshooting-connecting"></a>

当您尝试连接到 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 端点。以下几个原因可能会导致出现此情况：

**Topics**
+ [从公有端点连接](#troubleshooting.cannot-connect.public-endpoints)
+ [跨区域连接](#troubleshooting.cannot-connect.different-regions)
+ [从不同的 Amazon 连接 VPCs](#troubleshooting.cannot-connect.different-vpcs)
+ [安全组阻止入站连接](#troubleshooting.cannot-connect.inbound-not-allowed)
+ [Java Mongo 驱动程序读取首选项问题](#troubleshooting-cannot-connect-java-mongo-issue)

### 从公有端点连接
<a name="troubleshooting.cannot-connect.public-endpoints"></a>

**您正在尝试直接通过笔记本电脑或本地开发计算机连接到 Amazon DocumentDB 集群。**

从公有端点（例如，您的笔记本电脑或本地开发机）直接连接到 Amazon DocumentDB 集群的尝试会失败。Amazon DocumentDB 仅面向虚拟私有云（VPC），并且当前不支持公共端点。因此，您无法从笔记本电脑或 VPC 外部的本地开发环境直接连接到 Amazon DocumentDB 集群。

要从 Amazon VPC 外部连接到 Amazon DocumentDB 集群，您可使用 SSH 隧道。有关更多信息，请参阅 [从 Amazon VPC 外部连接到 Amazon DocumentDB 集群](connect-from-outside-a-vpc.md)。此外，如果您的开发环境位于不同的 Amazon VPC 中，您还可以使用 VPC 对等，并从同一区域或不同区域中的另一个 Amazon VPC 连接到您的 Amazon DocumentDB 集群。

### 跨区域连接
<a name="troubleshooting.cannot-connect.different-regions"></a>

**您正在尝试连接到另一个区域中的 Amazon DocumentDB 集群。**

如果您尝试从集群区域以外某区域的 Amazon EC2 实例连接到 Amazon DocumentDB 集群，例如，尝试从美国西部（俄勒冈州）区域 (us-west-2) 连接到美国东部（弗吉尼亚州北部）区域 (us-east-1) 中的集群，连接将失败。

要验证您的 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-1a"
    ]
]
```

### 从不同的 Amazon 连接 VPCs
<a name="troubleshooting.cannot-connect.different-vpcs"></a>

**您正在尝试通过一个 VPC（不同于您的集群部署到的 Amazon VPC）连接到 Amazon DocumentDB 集群。**

如果您的 Amazon DocumentDB 集群和 Amazon EC2 实例位于相同但不在同一个亚马逊 VPC 中 AWS 区域，则除非在两个亚马逊之间启用 VPC 对等互连，否则您无法直接连接到您的 Amazon DocumentDB 集群。 VPCs

要验证 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'
```

### 安全组阻止入站连接
<a name="troubleshooting.cannot-connect.inbound-not-allowed"></a>

**您正在尝试连接到 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 文档中的以下主题：
+ [为您的 Linux 实例授权入站流量](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html)
+ [为您的 Windows 实例授权入站流量](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/authorizing-access-to-an-instance.html)

### Java Mongo 驱动程序读取首选项问题
<a name="troubleshooting-cannot-connect-java-mongo-issue"></a>

**客户端读取首选项未被接受，并且除非重启，某些客户端无法在失效转移后写入 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 记录更新，则客户端仍尝试向旧写入器（失效转移后现在是读取器）发出写入请求。这导致 Java 驱动程序未恰当处理的服务器端错误（不是主错误）（这仍在调查中）。因此，可能听任客户端处于不良状态，例如直到应用程序服务器重新启动为止。

对此有两种应变方法：
+ 通过连接字符串连接到 Amazon DocumentDB 的客户端将不会出现这个问题，因为设置读取首选项时`ClusterConnectionMode` 会设置成 `MULTIPLE`。

  ```
  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 实例的连接
<a name="troubleshooting.testing-connection"></a>

您可以使用常见的 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!
```

## 连接到无效终端节点
<a name="troubleshooting.invalid-endpoint"></a>

在连接到 Amazon DocumentDB 集群并且使用的是无效的集群端点时，将出现与以下内容类似的错误。

```
mongo --ssl \
   --host sample-cluster.node.us-east-1.docdb.amazonaws.com:27017 \
   --sslCAFile global-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]'
```

有关更多信息，请参阅 [了解 Amazon DocumentDB 端点](endpoints.md)。

## 影响连接数的驱动程序配置
<a name="troubleshooting.driver.config"></a>

使用客户端驱动程序连接到 Amazon DocumentDB 集群时，请务必考虑 `maxPoolSize` 配置参数。`maxPoolSize` 设置决定了客户端驱动程序可以在其连接池中保持的最大连接数。