Amazon SDK for Java 2.x 的最佳做法 - Amazon SDK for Java 2.x
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

Amazon SDK for Java 2.x 的最佳做法

本部分列出了使用适用于 Java 的 SDK 2.x 的最佳实践。

如果可能,请重复使用 SDK 客户端

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

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

关闭来自客户端操作的输入流

对于流式传输操作(例如 S3Client#getObject),如果您直接使用 ResponseInputStream,建议执行以下操作:

  • 尽快读取输入流中的所有数据。

  • 请尽快关闭输入流。

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

根据性能测试调整 HTTP 配置

SDK 提供了一组适用于一般用例的默认 http 配置。我们建议客户根据其用例调整其应用程序的 HTTP 配置。

作为一个很好的起点,SDK 提供了智能配置默认值功能。此功能从版本 2.17.102 开始提供。根据您的用例选择一种模式,该模式将提供合理的配置值。

对基于 Netty 的 HTTP 客户端使用 OpenSSL

默认情况下,SDK 的 NettyNioAsyncHttpClient 使用 JDK 的默认 SSL 实现作为 SslProvider。我们的测试发现,OpenSSL 的性能比 JDK 的默认实现要好。Netty 社区也建议使用 OpenSSL

要使用 OpenSSL,请将 netty-tcnative 添加到您的依赖项中。有关配置的详细信息,请参阅 Netty 项目文档

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

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

配置 API 超时

SDK 为某些超时选项(例如连接超时和套接字超时)提供默认值,但不为 API 调用超时或单个 API 调用尝试超时提供默认值。为单个尝试和整个请求都设置超时是一种很好的做法。当存在可能导致请求尝试花费更长时间才能完成的临时问题或出现严重的网络问题时,这将确保您的应用程序以最佳方式快速失败。

您可以使用 ClientOverrideConfiguration#apiCallAttemptTimeoutClientOverrideConfiguration#apiCallTimeout 为服务客户端发出的所有请求配置超时。

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

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

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

apiCallTimeout

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

除了在服务客户端上设置这些超时值之外,您还可以使用 RequestOverrideConfiguration#apiCallTimeout()RequestOverrideConfiguration#apiCallAttemptTimeout() 来配置单个请求。

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

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

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

使用指标

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

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