

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

# 故障排除 FAQs
<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>

有时，您可能会看到预期会重试但却被抛出的异常。在这些情况下，以下步骤可能有助于解决问题。
+ **验证异常是否可重试。**有些异常是不可重试的，例如表示服务请求格式错误、权限不足和资源不存在的例外情况。SDK 不会自动重试此类异常。有关如何检查可重试异常的信息，请参阅。[检查异常是否可以重试](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 会为每个服务客户端保留一桶令牌。当 SDK 尝试请求但由于可重试异常而失败时，令牌数量会减少；当请求成功时，令牌计数会增加。

    默认情况下，如果此令牌桶的剩余代币数量达到 0 个，则该回路就会中断。电路中断后，SDK 会禁用重试，并且任何在第一次尝试时失败的当前和后续请求都会立即抛出异常。成功进行首次尝试后，SDK 会重新启用重试功能，为令牌存储桶返回足够的容量。这种行为是故意的，旨在防止服务中断和服务恢复期间的重试风暴。

    如果您希望 SDK 继续重试配置的最大尝试次数，请考虑通过在客户端配置中将该`retryStrategy.tokenBucket.useCircuitBreakerMode`属性设置为 false 来禁用断路器模式。将此属性设置为 false 后，SDK 客户端会等到令牌存储桶达到足够的容量，而不是在还剩 0 个令牌时放弃可能导致异常的进一步重试。

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

这些错误通常是由依赖项缺失或相互冲突造成的。请参阅[如何解决依赖冲突？](ts-faq-dep-conflict-resolution.md)了解更多信息。

### 我看见了 fo `NoClassDefFoundError` r `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 所需的依赖项发生冲突。例如，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`依赖于 a`ws.sdk.kotlin:aws-http:1.2.3`，后者依赖于`aws.sdk.kotlin:aws-core:1.2.3`，依此类推。

SDK 模块还使用特定的 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/)是一款流行的 HTTP 引擎，SDK 默认在 JVM 上使用该引擎。您的应用程序可能包含其他引入不同 OkHttp 版本的依赖项或框架。这可能会导致`okhttp3`命名空间中的类变为，例如`okhttp/coroutines/ExecuteAsyncKt`或`okhttp3/ConnectionListener`。`NoClassDefFoundError`发生这种情况时，通常应选择较新的版本来解决冲突。为了帮助您追踪这些冲突的根源，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，SDK 会提供。`OkHttp4Engine`有关如何配置 Gradle 并在代码`OkHttp4Engine`中使用的信息，请参阅[文档](https://github.com/smithy-lang/smithy-kotlin/tree/main/runtime/protocol/http-client-engines/http-client-engine-okhttp4)。