

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Amazon DocumentDB 的連線問題
<a name="performance-connection-issues"></a>

## 識別 - 找出問題
<a name="connection-identification"></a>

**常見原因**

連線問題通常來自三個主要區域：

當應用程式透過用戶端連線集區限制或伺服器端執行個體限制達到其對 Amazon DocumentDB 允許的連線上限時，就會發生連線集區耗盡。當新的連線請求排入佇列或拒絕時，此條件會導致應用程式效能降低、逾時和潛在的失敗。

當 Amazon DocumentDB 遇到過多並行身分驗證請求時，尤其是在短時間內處理超過 1，000 個新連線時，就會發生身分驗證過載。在身分驗證維護期間，Amazon DocumentDB 會在工作階段映射上保留專屬鎖定，導致後續身分驗證嘗試排入佇列，直到維護完成為止。

Amazon DocumentDB 中的組態問題通常來自聯網、安全和用戶端設定中的組態錯誤。這包括不正確的安全群組設定、不正確的 VPC 組態或 SSL/TLS 憑證問題等項目。了解適當的組態對於維護安全可靠的資料庫存取至關重要。

## 診斷 - 尋找根本原因
<a name="connection-diagnose"></a>

**連線集區**

連線集區會在建立 MongoClient 執行個體時初始化。每個集區會根據兩個關鍵參數維護連線：

minPoolSize - 維護的連線數下限

maxPoolSize - 允許的最大連線數

當請求需要連線時：

1. 集區會檢查可用的閒置連線

1. 如果不存在且集區大小 < maxPoolSize，則會建立新的連線

1. 如果位於 maxPoolSize，請求會進入等待佇列

1. 如果佇列已滿或已達到逾時，則會擲回 MongoWaitQueueFullException

等待佇列的行為會透過下列參數處理：

waitQueueTimeoutMS - 連線的等待時間上限

waitQueueSize - 佇列請求上限

以下是連線至每次建立新集區之 Amazon DocumentDB 的有問題方法範例：

```
for(Request request : requests) {
    MongoClient client = MongoClients.create(settings);
    // Process request
    client.close();
}
```

要監控的關鍵 CloudWatch 指標為：
+ `DatabaseConnections` - 在執行個體上以 1 分鐘的頻率開啟的連線數 （作用中和閒置）。
+ `DatabaseConnectionsMax` - 執行個體在 1 分鐘內開啟的資料庫連線 （作用中和閒置） 數目上限。
+ `DatabaseConnectionsLimit` - 執行個體在任何指定時間允許的並行資料庫連線數目上限 （作用中和閒置）。
+ `LowMemNumOperationsThrottled` - 由於 1 分鐘內可用記憶體不足而調節的請求數量。

請參閱[配額和限制](limits.md#limits.instance)，了解每個執行個體類別的限制。

應用程式層級連線集區問題的常見警告訊號包括：
+ 增加連線擷取時間
+ 增加等待佇列大小
+ 逾時例外狀況數量增加

**身分驗證過載**

連線至 Amazon DocumentDB 的流程如下所示：

連線請求 → SSL 交握 → 身分驗證 → 工作階段建立 → 連線就緒

處理 >1，000 個新連線時，在完成 SSL 交握後，其他連線請求將進入身分驗證佇列。在這些過載事件期間，您應用程式的平均連線時間將會增加。

要監控的關鍵 CloudWatch 指標為：
+ `DatabaseConnections` - 在執行個體上以 1 分鐘的頻率開啟的連線數 （作用中和閒置）。
+ `DatabaseConnectionsMax` - 執行個體在 1 分鐘內開啟的資料庫連線 （作用中和閒置） 數目上限。
+ `DatabaseConnectionsLimit` - 執行個體在任何指定時間允許的並行資料庫連線數目上限 （作用中和閒置）。

**組態問題**

最常見的組態問題是嘗試從無法存取私有網路環境的環境連線至私有 Amazon DocumentDB 叢集端點時所造成。Amazon DocumentDB 是僅限虛擬私有雲端 (VPC)，目前不支援公有端點。您無法從筆記型電腦或 VPC 外部的本機開發環境直接連線至 Amazon DocumentDB 叢集。

這將出現如下錯誤：

```
Error: couldn't connect to server...
Failed to connect to...
exception: connect failed
connection attempt failed
```

不正確的安全群組組態也可能導致連線失敗。根據預設，Amazon DocumentDB 叢集會接聽 TCP 連接埠 27017 上的連線。如果嘗試連線到與部署叢集時不同的連接埠，或者如果叢集的傳入安全群組組態中未涵蓋應用程式，您的應用程式將會失敗。

不正確的憑證管理也可能導致連線問題。根據預設，系統會為新建立的 Amazon DocumentDB 叢集啟用傳輸中加密。啟用傳輸中加密時，必須使用 TLS 的安全連線，才能使用 global-bundle.pem 憑證連線至叢集。如果您嘗試使用不正確的憑證，您將會收到錯誤，例如：

```
unable to get local issuer certificate
```

如果嘗試連接到啟用 TLS 的叢集，但未指定 TLS 參數，您將會收到錯誤，例如：

```
Server selection timed out after 30000 ms
```

## 解決 - 修正問題
<a name="connection-resolve"></a>

**連線集區**：實作或調整集區大小以符合工作負載需求，以檢閱連線集區。最佳集區組態取決於您的工作負載和需求。您應該保留 minPoolSize，讓核心連線準備就緒且可用，如果集區已用盡，則 maxWaitTime 短到可以快速失敗。

以下是如何重複使用單一集區而不每次建立新集區的範例：

```
MongoClient client = MongoClients.create(settings); 
    for(Request request : requests) { 
    // Process request
}
```

**身分驗證過載**：透過實作漸進式連線提升，並一次限制 1，000 個新連線來管理身分驗證。使用連線集區有效地重複使用已驗證的連線。若要避免 Amazon DocumentDB 叢集的連線超載，請實作連線漸進升級策略。

```
public class ConnectionManager {
    private static final int BATCH_SIZE = 100;
    private static final int DELAY_MS = 1000;
    
    public void establishConnections(int totalRequired) {
        int established = 0;
        while (established < totalRequired) {
            int batch = Math.min(BATCH_SIZE, totalRequired - established);
            createConnections(batch);
            Thread.sleep(DELAY_MS);
            established += batch;
        }
    }
}
```

您也可以設定連線集區設定，以限制允許的連線總數。

```
MongoClientSettings settings = MongoClientSettings.builder()
    .applyToConnectionPoolSettings(builder -> {
        builder.maxSize(500)                     // Limit total connections
               .minSize(10)                      // Maintain base connections
               .maxConnectionLifeTime(3600000)   // Rotate connections hourly
    })
    .applyToServerSettings(builder -> {
        builder.heartbeatFrequency(10000)        // Regular server checks
    })
    .build();
```

**組態問題**：確保您的應用程式可存取 Amazon DocumentDB 資源所在的私有 VPC 和子網路。如果使用 VPC 對等互連，請參閱開發人員指南對 VPC 對等互連進行故障診斷以取得更多資訊。您也可以檢閱 知識中心文章[如何疑難排解從網際網路到 VPC 內 Amazon EC2 執行個體的連線問題？](https://repost.aws/knowledge-center/instance-vpc-troubleshoot)

對於安全群組組態，您必須在 Amazon DocumentDB 安全群組中包含傳入規則，以允許來自應用程式的連線。

```
{
  "SecurityGroupIngress": [
    {
      "IpProtocol": "tcp",
      "FromPort": 27017,
      "ToPort": 27017,
      "SourceSecurityGroupId": "<application-security-group>",
      "Description": "DocumentDB access from application tier"
    }
  ],
  "SecurityGroupEgress": [
    {
      "IpProtocol": "-1",
      "FromPort": -1,
      "ToPort": -1,
      "CidrIp": "0.0.0.0/0"
    }
  ]
}
```

如果叢集設定為 TLS 加密，請下載名為 global-bundle.pem 的 Amazon DocumentDB 的 TLS 憑證，並在連線至叢集時使用它。

```
wget https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
```

**長期解決方案**

透過升級至較大的執行個體類別或新增僅供讀取複本來分配連線負載，可能需要執行個體擴展。適當的負載平衡實作可確保整個叢集的最佳資源使用率。

應用程式變更應著重於實作強大的連線處理、全方位監控，以及遵循連線集區最佳實務。這包括適當的錯誤處理和連線生命週期管理。

架構改善可能涉及針對可變工作負載採用 Amazon DocumentDB Serverless、實作複雜的重試邏輯，以及設計容錯能力。考慮重組應用程式架構，以更好地處理連線管理。

## 最佳實務
<a name="connection-best-practices"></a>

**連線集區**

透過適當的連線集區管理和監控，應用程式可以維持穩定的資料庫連線，同時防止可能影響系統可靠性和效能的耗盡情況。根據工作負載的特性，設定適當的逾時並調整集區大小。

連線集區設定範例

```
MongoClientSettings settings = MongoClientSettings.builder()
    .applyToConnectionPoolSettings(builder ->
        builder.maxSize(10))
    .applyToConnectionPoolSettings(builder ->
        builder.maxWaitQueueSize(2))
    .applyToConnectionPoolSettings(builder ->
        builder.maxConnectionIdleTime(10, TimeUnit.MINUTES))
    .build();
```

如需詳細資訊，請參閱：https：//[https://aws.amazon.com/blogs/database/building-resilient-applications-with-amazon-documentdb-with-mongodb-compatibility-part-1-client-configuration/](https://aws.amazon.com/blogs/database/building-resilient-applications-with-amazon-documentdb-with-mongodb-compatibility-part-1-client-configuration/)

**身分驗證過載**

一律根據您的工作負載為參數實作具有適當值的連線集區。使用逐步建立連線技術，並盡可能維持持久性連線。實作適當的連線清除，以確保不會浪費閒置資源。

**組態問題**

確定您已設定從應用程式到 Amazon DocumentDB 資源的適當路由。使用 TLS 進行傳輸中的加密，並實作最低權限存取。驗證您的 Amazon DocumentDB 登入資料並驗證連線字串值。