

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

# 使用的最佳实践 AWS SDK for Java 2.x
<a name="best-practices"></a>

## 通过配置 API 超时来防止请求挂起
<a name="bestpractice5"></a>

SDK 为某些超时选项（例如连接超时和套接字超时）提供[默认值](https://github.com/aws/aws-sdk-java-v2/blob/a0c8a0af1fa572b16b5bd78f310594d642324156/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java#L134)，但不为 API 调用超时或单个 API 调用尝试超时提供默认值。为单个尝试和整个请求都设置超时是一种很好的做法。当存在可能导致请求尝试花费更长时间才能完成的临时问题或出现严重的网络问题时，这将确保您的应用程序以最佳方式快速失败。

您可以使用 `[ClientOverrideConfiguration\$1apiCallAttemptTimeout](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html#apiCallAttemptTimeout())` 和 `[ClientOverrideConfiguration\$1apiCallTimeout](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html#apiCallTimeout())` 为服务客户端发出的所有请求配置超时。

以下示例演示使用自定义超时值配置 Amazon S3 客户端。

```
S3Client.builder()
        .overrideConfiguration(
             b -> b.apiCallTimeout(Duration.ofSeconds(<custom value>))
                   .apiCallAttemptTimeout(Duration.ofMillis(<custom value>)))
        .build();
```

**`apiCallAttemptTimeout`**  
此设置设定单次 HTTP 尝试的时长，超过该时长之后可以重试 API 调用。

**`apiCallTimeout`**  
此属性的值配置整个执行的时间，包括所有重试尝试。

除了在服务客户端上设置这些超时值之外，您还可以使用 [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/RequestOverrideConfiguration.html#apiCallTimeout()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/RequestOverrideConfiguration.html#apiCallTimeout()) 和 `[RequestOverrideConfiguration\$1apiCallAttemptTimeout()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/RequestOverrideConfiguration.html#apiCallAttemptTimeout())` 来配置单个请求。

以下示例使用自定义超时值配置单个 `listBuckets` 请求。

```
s3Client.listBuckets(lbr -> lbr.overrideConfiguration(
        b -> b.apiCallTimeout(Duration.ofSeconds(<custom value>))
               .apiCallAttemptTimeout(Duration.ofMillis(<custom value>))));
```

将这些属性一起使用时，可以对所有重试尝试所花费的总时间设置硬性限制。您还可以将单个 HTTP 请求设置为在慢速请求时快速失败。

## 通过重复使用服务客户端来提高性能
<a name="bestpractice1"></a>

每个[服务客户端](work-witih-clients.md)都维护自己的 HTTP 连接池。新请求可以重复使用池中已存在的连接，以缩短建立新连接的时间。我们建议共享单个客户端实例，以避免因未得到有效使用的连接池过多而产生的开销。所有服务客户端都是线程安全的。

如果您不想共享客户端实例，请在不需要该客户端时在示例上调用 `close()` 以释放资源。

## 通过关闭未使用的服务客户端来防止资源泄漏
<a name="bestpractice-close-client"></a>

如果不再需要某个服务客户端，请关闭该[服务客户端](work-witih-clients.md)以释放线程等资源。如果您不想共享客户端实例，请在不需要该客户端时在示例上调用 `close()` 以释放资源。

## 通过关闭输入流来防止连接池耗尽
<a name="bestpractice2"></a>

对于流式传输操作（例如 `[S3Client\$1getObject](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#getObject(java.util.function.Consumer,java.nio.file.Path))`），如果您直接使用 `[ResponseInputStream](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/ResponseInputStream.html)`，建议执行以下操作：
+ 尽快读取输入流中的所有数据。
+ 请尽快关闭输入流。

我们之所以提出这些建议，是因为输入流是来自 HTTP 连接的直接数据流，并且在读取流中的所有数据并关闭流之前，底层 HTTP 连接无法重复使用。如果不遵守这些规则，则客户端可能会因为分配太多已打开但未使用的 HTTP 连接而耗尽资源。

## 针对您的应用程序工作负载优化 HTTP 性能
<a name="bestpractice3"></a>

SDK 提供了一组适用于一般用例的[默认 http 配置](https://github.com/aws/aws-sdk-java-v2/blob/master/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java)。我们建议客户根据其用例调整其应用程序的 HTTP 配置。

作为一个很好的起点，SDK 提供了[智能配置默认值](http-configuration.md#http-config-smart-defaults)功能。此功能从版本 2.17.102 开始提供。根据您的用例选择一种模式，该模式将提供合理的配置值。

## 使用适用于异步客户端的 OpenSSL 提高 SSL 性能
<a name="bestpractice4"></a>

默认情况下，SDK 的 [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html) 使用 JDK 的默认 SSL 实现作为 `SslProvider`。我们的测试发现，OpenSSL 的性能比 JDK 的默认实现要好。Netty 社区也[建议使用 OpenSSL](https://netty.io/wiki/requirements-for-4.x.html#tls-with-openssl)。

要使用 OpenSSL，请将 `netty-tcnative` 添加到您的依赖项中。有关配置的详细信息，请参阅 [Netty 项目文档](https://netty.io/wiki/forked-tomcat-native.html)。

在为项目配置了 `netty-tcnative` 后，`NettyNioAsyncHttpClient` 实例将自动选择 OpenSSL。或者，您可以使用 `NettyNioAsyncHttpClient` 生成器显式设置 `SslProvider`，如以下代码段所示。

```
NettyNioAsyncHttpClient.builder()
                        .sslProvider(SslProvider.OPENSSL)
                        .build();
```

## 使用 SDK 指标监控应用程序性能
<a name="bestpractice6"></a>

适用于 Java 的 SDK 可以[收集应用程序中服务客户端的指标](metrics.md)。您可以使用这些指标来识别性能问题、查看总体使用趋势、查看返回的服务客户端异常或深入了解特定问题。

我们建议您收集指标，然后分析 Amazon CloudWatch 日志，以便更深入地了解应用程序的性能。