

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

# 使用高性能 S3 客户端： AWS 基于 CRT 的 S3 客户端
<a name="crt-based-s3-client"></a>

 AWS 基于 CRT 的 S3 客户端（建立在[AWS 公共运行时 (CRT) 之上）](https://docs.aws.amazon.com/sdkref/latest/guide/common-runtime.html)是替代的 S3 异步客户端。它通过自动使用 Amazon S3 的[分段上传 API](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html) 和[字节范围提取](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance-guidelines.html#optimizing-performance-guidelines-get-range)，将对象传入或传出 Amazon Simple Storage Service (Amazon S3)，从而提高了性能和可靠性。

 AWS 基于 CRT 的 S3 客户端可提高网络故障时的传输可靠性。通过重试文件传输中失败的各个分段，而无需从头开始重新启动传输，从而提高可靠性。

此外， AWS 基于 CRT 的 S3 客户端还提供了增强的连接池和域名系统 (DNS) 负载平衡，这也提高了吞吐量。

您可以使用 AWS 基于 CRT 的 S3 客户端来代替 SDK 的标准 S3 异步客户端，并立即利用其提高的吞吐量。

**重要**  
 AWS 基于 CRT 的 S3 客户端目前不支持在客户端级别和请求级别[收集 SDK 指标](metrics.md)。

**AWS SDK 中基于 CRT 的组件**

本主题中介绍 AWS 的基于 CRT 的 *S3* 客户端和 AWS 基于 CRT 的 *HTTP* 客户端是软件开发工具包中的不同组件。

**AWS 基于 CRT 的 S3 客户端**是 S [3 AsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html) 接口的实现，用于与 Amazon S3 服务配合使用。它是基于 Java 的 `S3AsyncClient` 接口实现的替代方案，具有多种优势。

[AWS 基于 CRT 的 HTTP 客户端](http-configuration-crt.md)是该[SdkAsyncHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/async/SdkAsyncHttpClient.html)接口的实现，用于一般的 HTTP 通信。它是 Netty `SdkAsyncHttpClient` 接口实现的替代方案，具有多种优势。

尽管两个组件都使用[AWS 公共运行时](https://docs.aws.amazon.com/sdkref/latest/guide/common-runtime.html)中的库，但 AWS 基于 CRT 的 S3 客户端使用 [aws-c-s3 库](https://github.com/awslabs/aws-c-s3)并支持 [S3 分段上传 API](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html) 功能。由于 AWS 基于 CRT 的 HTTP 客户端仅供一般用途，因此它不支持 S3 分段上传 API 功能。

## 添加依赖项以使用 AWS 基于 CRT 的 S3 客户端
<a name="crt-based-s3-client-depend"></a>

要使用 AWS 基于 CRT 的 S3 客户端，请将以下两个依赖项添加到您的 Maven 项目文件中。示例显示了要使用的最低版本。在 Maven Central 存储库中搜索 [s3](https://central.sonatype.com/artifact/software.amazon.awssdk/s3) 和 [aws-crt](https://central.sonatype.com/artifact/software.amazon.awssdk.crt/aws-crt) 构件的最新版本。

```
<dependency>
  <groupId>software.amazon.awssdk</groupId>
  <artifactId>s3</artifactId>
  <version>2.27.21</version>
</dependency>
<dependency>
  <groupId>software.amazon.awssdk.crt</groupId>
  <artifactId>aws-crt</artifactId>
  <version>0.30.11</version>
</dependency>
```

## 创建 AWS 基于 CRT 的 S3 客户端的实例
<a name="crt-based-s3-client-create"></a>

 使用默认设置创建 AWS 基于 CRT 的 S3 客户端的实例，如以下代码片段所示。

```
S3AsyncClient s3AsyncClient = S3AsyncClient.crtCreate();
```

要配置客户端，请使用 AWS CRT 客户端生成器。您可以通过更改构建器方法从标准 S3 异步客户端切换到 AWS 基于 CRT 的客户端。

```
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;


S3AsyncClient s3AsyncClient = 
        S3AsyncClient.crtBuilder()
                     .credentialsProvider(DefaultCredentialsProvider.create())
                     .region(Region.US_WEST_2)
                     .targetThroughputInGbps(20.0)
                     .minimumPartSizeInBytes(8 * 1025 * 1024L)
                     .build();
```

**注意**  
 AWS CRT 客户端生成器目前可能不支持标准生成器中的某些设置。通过调用 `S3AsyncClient#builder()` 获取标准生成器。

## 使用 AWS 基于 CRT 的 S3 客户端
<a name="crt-based-s3-client-use"></a>

使用 AWS 基于 CRT 的 S3 客户端调用 Amazon S3 API 操作。以下示例演示了可通过提供的[PutObject](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html#putObject(java.util.function.Consumer,software.amazon.awssdk.core.async.AsyncRequestBody))和[GetObject](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html#getObject(java.util.function.Consumer,software.amazon.awssdk.core.async.AsyncResponseTransformer))操作 适用于 Java 的 AWS SDK。

```
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;


S3AsyncClient s3Client = S3AsyncClient.crtCreate();

// Upload a local file to Amazon S3.
PutObjectResponse putObjectResponse = 
      s3Client.putObject(req -> req.bucket(<BUCKET_NAME>)
                                   .key(<KEY_NAME>),
                        AsyncRequestBody.fromFile(Paths.get(<FILE_NAME>)))
              .join();

// Download an object from Amazon S3 to a local file.
GetObjectResponse getObjectResponse = 
      s3Client.getObject(req -> req.bucket(<BUCKET_NAME>)
                                   .key(<KEY_NAME>),
                        AsyncResponseTransformer.toFile(Paths.get(<FILE_NAME>)))
              .join();
```

## 上传未知大小的流
<a name="crt-stream-unknown-size"></a>

 AWS AWS 基于 CRT 的 S3 客户端的一个显著优势是它能够高效处理大小未知的输入流。当您需要从无法事先确定总大小的来源上传数据时，这特别有用。

```
public PutObjectResponse crtClient_stream_unknown_size(String bucketName, String key, InputStream inputStream) {

    S3AsyncClient s3AsyncClient = S3AsyncClient.crtCreate();
    ExecutorService executor = Executors.newSingleThreadExecutor();
    AsyncRequestBody body = AsyncRequestBody.fromInputStream(inputStream, null, executor);  // 'null' indicates that the
                                                                                            // content length is unknown.
    CompletableFuture<PutObjectResponse> responseFuture =
            s3AsyncClient.putObject(r -> r.bucket(bucketName).key(key), body)
                    .exceptionally(e -> {
                        if (e != null){
                            logger.error(e.getMessage(), e);
                        }
                        return null;
                    });

    PutObjectResponse response = responseFuture.join(); // Wait for the response.
    executor.shutdown();
    return response;
}
```

此功能有助于避免传统上传中的常见问题，即不正确的内容长度规格会导致对象被截断或上传失败。

## 配置限制
<a name="crt-based-s3-client-limitations"></a>

 AWS 基于 CRT 的 S3 客户端和基于 Java 的 S3 异步客户端[提供了类似的功能](examples-s3.md#s3-clients)，而 AWS 基于 CRT 的 S3 客户端则提供了性能优势。但是， AWS 基于 CRT 的 S3 客户端缺少基于 Java 的 S3 异步客户端所具有的配置设置。这些设置包括：
+ *客户端级别配置：*API 调用尝试超时、压缩执行拦截器、指标发布者、自定义执行属性、自定义高级选项、自定义计划执行器服务、自定义标头
+ *请求级别配置：*自定义签名者、API 调用尝试超时

有关配置差异的完整列表，请参阅 API 参考。


| 基于 Java 的 S3 异步客户端 | AWS 基于CRT的S3客户端 | 
| --- | --- | 
| 客户端级别配置[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sdk-for-java/latest/developer-guide/crt-based-s3-client.html)请求级别配置[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sdk-for-java/latest/developer-guide/crt-based-s3-client.html) | 客户端级别配置[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sdk-for-java/latest/developer-guide/crt-based-s3-client.html)请求级别配置[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/sdk-for-java/latest/developer-guide/crt-based-s3-client.html) | 