

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

# 疑難排解常見問答集
<a name="troubleshooting-faqs"></a>

當您 適用於 Kotlin 的 AWS SDK 在應用程式中使用 時，您可能會遇到本主題中列出的一些問題。使用下列建議來協助找出根本原因並解決錯誤。

## 如何修正「連線已關閉」問題？
<a name="ts-faq-connection-closed"></a>

您可能會遇到「連線關閉」問題，例如下列其中一種類型的例外狀況：
+ `IOException: unexpected end of stream on <URL>`
+ `EOFException: \n not found: limit=0`
+ `HttpException: AWS_ERROR_HTTP_CONNECTION_CLOSED: The connection has closed or is closing.; crtErrorCode=2058; HttpErrorCode(CONNECTION_CLOSED)`

這些例外狀況表示從 SDK 到服務的 TCP 連線意外關閉或重設。您的主機、 AWS 服務或 NAT 閘道、代理或負載平衡器等中介方可能已關閉連線。

這些類型的例外狀況會自動重試，但仍然會出現在 SDK 日誌中，視您的記錄組態而定。如果將例外狀況擲入您的程式碼中，表示作用中的重試策略已耗盡其設定的限制，例如最大嘗試次數或重試權杖儲存貯體。如需重試策略的詳細資訊，請參閱本指南的 [中的重試次數 適用於 Kotlin 的 AWS SDK](retries.md)一節。另請參閱[為什麼在達到嘗試次數上限之前擲回例外狀況？](#ts-faq-exceptions-before-max)。

### 使用 OkHttpEngine 進行閒置連線監控
<a name="ts-faq-connection-closed-okhttp"></a>

如果您使用 `OkHttpEngine`並經常遇到`IOException: unexpected end of stream on <URL>`例外狀況，[請考慮啟用閒置連線監控](http-client-config.md#http-idle-connection-monitoring)。此功能會偵測遠端伺服器何時具有仍在連線集區中的封閉連線，這可以減少這些例外狀況的發生。

## 為什麼在達到嘗試次數上限之前擲回例外狀況？
<a name="ts-faq-exceptions-before-max"></a>

有時您可能會看到預期會重試的例外狀況，但會改為擲回。在這些情況下，下列步驟可能有助於解決問題。
+ **確認例外狀況可重試。**有些例外狀況無法重試，例如表示服務請求格式不正確、缺少許可和不存在的資源等。開發套件不會自動重試這類例外狀況。如需如何檢查可重試例外狀況的資訊，請參閱 [檢查例外狀況是否可重試](retries.md#retries-check-exception-retryable)。
+ **確認例外狀況已擲入您的程式碼中。**有些例外狀況會在日誌訊息中顯示為資訊，但實際上不會擲入您的程式碼中。例如，由於 SDK 會自動執行多個backoff-and-retry週期，因此可能會記錄可重試的例外狀況，例如調節錯誤。只有在設定的重試設定未處理 SDK 操作時，才會擲回例外狀況。
+ **驗證您設定的重試設定。**如需重試策略和重試政策的詳細資訊，請參閱本指南的 [中的重試次數 適用於 Kotlin 的 AWS SDK](retries.md)一節。確保您的程式碼使用您預期的設定或自動預設值。
+ **請考慮調整您的重試設定。**驗證先前項目但問題未解決後，您可以考慮調整重試設定。
  + **增加最大嘗試次數。**根據預設， 操作的嘗試次數上限為 3 次。如果您發現這不夠，且預設設定仍然發生例外狀況，請考慮在用戶端組態中增加 `retryStrategy.maxAttempts` 屬性。如需詳細資訊，請參閱[設定最大嘗試次數](retries.md#retires-max-attempts)。
  + **增加延遲設定。**在基礎條件有機會解決之前，某些例外狀況可能會嘗試過快。如果您懷疑確實如此，請考慮增加用戶端組態中的 `retryStrategy.delayProvider.initialDelay`或 `retryStrategy.delayProvider.maxBackoff` 屬性。如需詳細資訊，請參閱[設定延遲和退避](retries.md#retries-delays-backoff)。
  + **停用斷路器模式。**軟體開發套件預設會維護每個服務用戶端的字符儲存貯體。當 SDK 嘗試請求，但失敗並出現可重試的例外狀況時，字符計數會減少；當請求成功時，字符計數會遞增。

    根據預設，如果此字符儲存貯體達到剩餘 0 個字符，則電路會中斷。電路中斷後，開發套件會停用重試，且任何在第一次嘗試時失敗的目前和後續請求都會立即擲回例外狀況。開發套件會在初次嘗試成功傳回足夠的容量給字符儲存貯體後重新啟用重試。此行為是刻意的，旨在防止在服務中斷和服務復原期間重試風暴。

    如果您希望軟體開發套件繼續重試直到設定的嘗試次數上限，請考慮在用戶端組態中將 `retryStrategy.tokenBucket.useCircuitBreakerMode` 屬性設定為 false，以停用斷路器模式。將此屬性設定為 false 時，SDK 用戶端會等到字符儲存貯體達到足夠的容量，而不是放棄進一步的重試，這可能會在剩餘 0 個字符時導致例外狀況。

## 如何修正 `NoSuchMethodError`或 NoClassDefFoundError？
<a name="ts-faq-nusuchmethod"></a>

這些錯誤最常見的原因是相依性遺失或衝突。如需詳細資訊，請參閱[如何解決相依性衝突？](ts-faq-dep-conflict-resolution.md)。

### 我看到適用於 `NoClassDefFoundError`的 `okhttp3/coroutines/ExecuteAsyncKt`
<a name="ts-faq-nusuchmethod-okhttp"></a>

這表示 OkHttp 的相依性問題。如需詳細資訊，請參閱[解決應用程式中的 OkHttp 版本衝突](ts-faq-dep-conflict-resolution.md#okhttp-dep-conflicts)。

# 如何解決相依性衝突？
<a name="ts-faq-dep-conflict-resolution"></a>

當您使用 時 適用於 Kotlin 的 AWS SDK，它需要特定 AWS 和第三方相依性才能正常運作。如果這些相依性在執行時間遺失或未預期的版本，您可能會看到 `NoSuchMethodError`或 等錯誤`NoClassDefFoundError`。這些相依性問題通常分為兩個群組：
+ SDK/Smithy 相依性衝突
+ 第三方相依性衝突

當您建置 Kotlin 應用程式時，可能會使用 Gradle 來管理相依性。在 SDK 服務用戶端上新增相依性到您的專案，會自動包含所有必要的相關相依性。不過，如果您的應用程式有其他相依性，它們可能會與 SDK 所需的相依性衝突。例如，開發套件依賴 OkHttp，這是您的應用程式可能也會使用的熱門 HTTP 用戶端。為了協助您發現這些衝突，Gradle 提供便利的任務，列出專案的相依性：

```
./gradlew dependencies
```

當您遇到相依性衝突時，您可能需要採取動作。您可以在本機命名空間中指定特定版本的相依性或影子相依性。Gradle 相依性解析是一個複雜的主題，在 *Gradle 使用者手冊*的下列章節中進行了討論：
+ [ 了解相依性解析 ](https://docs.gradle.org/current/userguide/dependency_resolution.html)
+ [ 相依性限制和衝突解決 ](https://docs.gradle.org/current/userguide/dependency_constraints_conflicts.html)
+ [ 對齊相依性版本 ](https://docs.gradle.org/current/userguide/dependency_version_alignment.html)

## 在專案中管理 SDK 和 Smithy 相依性
<a name="sdk-smithy-dep-conflicts"></a>

當您使用 SDK 時，請記住，其模組通常依賴其他版本編號相符的 SDK 模組。例如， `aws.sdk.kotlin:s3:1.2.3`取決於 `ws.sdk.kotlin:aws-http:1.2.3`，這取決於 `aws.sdk.kotlin:aws-core:1.2.3`，以此類推。

開發套件模組也會使用特定的 Smithy 模組版本。雖然 Smithy 模組版本不會與 SDK 版本編號同步，但它們必須符合 SDK 的預期版本。例如， `aws.sdk.kotlin:s3:1.2.3`可能取決於 `aws.smithy.kotlin:serde:1.1.1`，這取決於 `aws.smithy.kotlin:runtime-core:1.1.1`，以此類推。

若要避免相依性衝突，請將所有 SDK 相依性一起升級，並針對任何明確的 Smithy 相依性執行相同的動作。考慮使用我們的 [Gradle 版本目錄](setup-create-project-file.md)來保持版本同步，並消除 SDK 和 Smithy 版本之間的映射猜測。

請記住，SDK/Smithy 模組中的次要版本更新可能包括重大變更，如我們的[版本控制政策](https://github.com/awslabs/aws-sdk-kotlin/blob/main/VERSIONING.md#versioning-policy)所述。在次要版本之間升級時，請仔細檢閱變更日誌並徹底測試執行時間行為。

## 解決應用程式中的 OkHttp 版本衝突
<a name="okhttp-dep-conflicts"></a>

[OkHttp](https://square.github.io/okhttp/) 是開發套件預設在 JVM 上使用的熱門 HTTP 引擎。您的應用程式可能包含具有不同 OkHttp 版本的其他相依性或架構。這可能會導致`okhttp3`命名空間中`NoClassDefFoundError`類別的 ，例如 `okhttp/coroutines/ExecuteAsyncKt`或 `okhttp3/ConnectionListener`。發生這種情況時，您通常應該選擇較新的版本來解決衝突。為了協助您追蹤這些衝突的來源，Gradle 提供了有用的任務。您可以執行下列動作來列出所有相依性：

```
./gradlew dependencies
```

例如，如果 SDK 依賴 OkHttp，`5.0.0-alpha.14`而 Spring Boot 等其他相依性依賴 OkHttp`4.12.0`，則您應該使用 `5.0.0-alpha.14 version`。您可以使用 Gradle 中的`constraints`區塊來執行此操作：

```
dependencies {
    constraints {
        implementation("com.squareup.okhttp3:okhttp:4.12.0")
    }
}
```

或者，如果您必須使用 OkHttp 4.x，開發套件會提供 `OkHttp4Engine`。如需如何在程式碼`OkHttp4Engine`中設定 Gradle 和使用 的資訊，請參閱 [文件](https://github.com/smithy-lang/smithy-kotlin/tree/main/runtime/protocol/http-client-engines/http-client-engine-okhttp4)。