本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
重试
偶尔会由于意想不到的原因调用失败。 Amazon Web Services 服务 如果重试呼叫,某些错误,例如限制(超出速率)或暂时错误,可能会成功。 Amazon SDK for Java 2.x 具有检测此类错误并自动重试所有客户端默认启用的呼叫的内置机制。
本页介绍其工作原理、如何配置不同的模式以及如何定制重试行为。
重试策略
重试策略是中用来实现重试SDK的机制。每个SDK客户端都有在构建时创建的重试策略,该策略在生成客户端后无法修改。
重试策略具有以下职责。
-
将异常归类为可重试与否。
-
计算下次尝试之前等待的建议延迟。
-
维护一个令牌存储桶,该存储桶
提供了一种在很大一部分请求失败且重试失败时停止重试的机制。
注意
在 2.26.0 版本发布重试策略之前SDK,重试策略在中提供了重试机制。SDK重试策略API由软件包中的核心RetryPolicy
software.amazon.awssdk.core.retry
包中software.amazon.awssdk.retries
包含重试策略API元素。
重试策略API是作为统一核心组件接口和行为的 Amazon全局努力的一部分而引入的。SDKs
f SDK or Java 2.x 有三种内置的重试策略:标准、传统和自适应。所有三种重试策略都已预先配置为对一组可重试的异常进行重试。可重试错误的示例包括套接字超时、服务端限制、并发或乐观锁定失败以及暂时性服务错误。
标准重试策略
对于正常用例,建议RetryStrategy
采用标准重试策略AdaptiveRetryStrategy
,标准策略通常适用于所有重试用例。
默认情况下,标准重试策略执行以下操作。
-
根据构建时配置的条件进行重试。你可以用进行调整
StandardRetryStrategy.Builder
。#retryOnException -
重试 2 次,总共尝试 3 次。你可以用进行调整
StandardRetryStrategy.Builder#maxAttempts(int)
。 -
对于非限流异常,它使用
BackoffStrategy
退避策略,基本延迟为 100 毫秒,最大延迟为 20 秒。你可以用进行调整#exponentialDelay StandardRetryStrategy.Builder#backoffStrategy
。 -
对于限制异常,它使用
BackoffStrategy#exponentialDelay
退避策略,基本延迟为 1 秒,最大延迟为 20 秒。你可以用进行调整StandardRetryStrategy.Builder#throttlingBackoffStrategy
。 -
在下游故障频繁的情况下,执行断路(禁用重试)。总是执行第一次尝试,只禁用重试。调整为
StandardRetryStrategy.Builder#circuitBreakerEnabled
。
传统重试策略
传统的重试策略RetryStrategy
适用于普通用例,但是,它已被弃用,转而使用。StandardRetryStrategy
当您不指定其他策略时,这是客户端使用的默认重试策略。
它的特点是区别对待限制和非限流异常,对于限制异常,退避的基本延迟(500 毫秒)大于非限制异常的基本延迟(100 毫秒),并且限制异常不会影响令牌桶状态。
在内部大规模使用这种策略的经验 Amazon 表明,这并不比标准的重试策略好。此外,它无法保护下游服务免受重试风暴的影响,并可能导致客户端资源短缺。
默认情况下,旧版重试策略执行以下操作。
-
根据构建时配置的条件进行重试。你可以用进行调整
LegacyRetryStrategy.Builder
。#retryOnException -
重试 3 次,总共尝试 4 次。你可以用进行调整
LegacyRetryStrategy.Builder#maxAttempts(int)
。 -
对于非限流异常,它使用
BackoffStrategy#exponentialDelay
退避策略,基本延迟为 100 毫秒,最大延迟为 20 秒。你可以通过以下方式进行调整LegacyRetryStrategy.Builder#backoffStrategy.
-
对于限制异常,它使用
BackoffStrategy#exponentialDelay
退避策略,基本延迟为 500 毫秒,最大延迟为 20 秒。你可以用进行调整LegacyRetryStrategy.Builder#throttlingBackoffStrategy
。 -
在下游故障频繁的情况下,执行断路(禁用重试)。断路永远不会阻止第一次成功尝试。您可以使用调整此行为
LegacyRetryStrategy.Builder#circuitBreakerEnabled
。 -
断路器的状态不受限流异常的影响。
自适应重试策略
自适应重试策略RetryStrategy
适用于资源限制程度高的用例。
自适应重试策略包括标准策略的所有功能,并添加了客户端速率限制器,用于衡量受限制请求与非限制请求的比率。该策略使用此衡量标准来减慢请求速度,以保持在安全的带宽范围内,理想情况下会导致零限制错误。
默认情况下,自适应重试策略执行以下操作。
-
根据构建时配置的条件进行重试。你可以用进行调整
AdaptiveRetryStrategy.Builder
。#retryOnException -
重试 2 次,总共尝试 3 次。你可以用进行调整
AdaptiveRetryStrategy.Builder#maxAttempts(int)
。 -
使用动态退避延迟,该延迟基于下游资源的当前负载。
-
下游故障次数较多时,执行断路(禁用重试)。断路可能会阻止在中断情况下再次尝试以保护下游服务。
警告
自适应重试策略假设客户端使用单个资源(例如,一个 DynamoDB 表或一个 Amazon S3 存储桶)。
如果您使用单个客户机管理多个资源,则在客户端访问所有其他资源时,与一个资源相关的限制或中断会导致延迟增加和故障。当您使用自适应重试策略时,我们建议您为每种资源使用一个客户端。
我们还建议您在所有客户端对资源使用自适应重试策略的情况下使用此策略。
重要
在 Java 2.26.0 版本中发布的重试策略SDK包含了新的RetryMode.ADAPTIVE_V2
ADAPTIVE_V2
模式可以更正先前检测到限制错误时未能延迟第一次尝试的错误。
在 2.26.0 版本中,用户可以通过将ADAPTIVE_V2
模式设置为adaptive
环境变量、系统属性或配置文件设置来自动获得模式行为。这些设置没有adaptive_v2
价值。有关如何设置模式的信息,请参阅以下指定策略部分。
用户可以通过使用在代码中设置模式来获得之前的行为RetryMode.ADAPTIVE
。
摘要:重试策略默认值的比较
下表显示了每种重试策略属性的默认值。
策略 | 最大尝试次数 | 非限流错误的基本延迟 | 限制错误的基本延迟 | 令牌桶大小 | 每次非限制重试的代币成本 | 每次限制重试的代币成本 |
---|---|---|---|---|---|---|
Standard | 3 | 100 | 100 | 500 | 5 | 5 |
传统 | 4 | 100 | 500 | 500 | 5 | 0 |
自适应 | 3 | 100 | 100 | 500 | 5 | 5 |
指定策略
您可以通过四种方式为服务客户端指定策略。
在代码中
在构建客户端时,您可以使用重试策略配置 lambda 表达式。以下代码段配置了在 DynamoDB 服务客户端上使用默认值的标准重试策略。
DynamoDbClient client = DynamoDbClient.builder() .overrideConfiguration(o -> o.retryStrategy(RetryMode.STANDARD)) .build();
您可以指定RetryMode.LEGACY
或RetryMode.ADAPTIVE
代替RetryMode.STANDARD
。
作为配置文件设置
retry_mode
作为配置文件设置包含在共享 Amazon 配置文件中。指定standard
legacy
、或adaptive
作为值。如果设置为配置文件设置,则在配置文件处于活动状态时创建的所有服务客户端都使用具有默认值的指定重试策略。您可以通过在代码中配置重试策略来覆盖此设置,如前所示。
使用以下配置文件,所有服务客户端都使用标准的重试策略。
[profile dev] region = us-east-2 retry_mode = standard
作为JVM系统属性
您可以使用 system 属性为所有服务客户端配置重试策略,除非在代码中被覆盖。aws.retryMode
指定standard
legacy
、或adaptive
作为值。
调用 Java 时使用-D
开关,如以下命令所示。
java -Daws.retryMode=standard ...
或者,在创建任何客户端之前,在代码中设置系统属性,如以下代码段所示。
public void main(String[] args) { // Set the property BEFORE any Amazon service clients are created. System.setProperty("aws.retryMode", "standard"); ... }
使用环境变量
也可以使用值为standard
legacy
、或的AWS_RETRY_MODE
环境变量adaptive
。与配置文件设置或JVM系统属性一样,除非您在代码中配置客户端,否则环境变量会将所有服务客户端配置为指定的重试模式。
以下命令将当前 shell 会话standard
的重试模式设置为。
export AWS_RETRY_MODE=standard
自定义策略
您可以通过设置最大尝试次数、退避策略和可重试的异常来自定义任何重试策略。您可以自定义何时构建重试策略或何时构建客户端,方法是使用允许进一步完善配置策略的覆盖生成器。
自定义最大尝试次数
您可以配置客户端构造期间的最大尝试次数,如以下语句所示。以下语句将客户端的默认重试策略自定义为最多 5 次尝试——第一次尝试加上 4 次重试。
DynamoDbClient client = DynamoDbClient.builder() .overrideConfiguration(o -> o.retryStrategy(b -> b.maxAttempts(5))) .build();
或者,您可以构建策略并将其提供给客户端,如以下代码示例所示。以下代码将标准的最大 3 次尝试次数替换为 10 次,并使用自定义策略配置 DynamoDB 客户端。
StandardRetryStrategy strategy = AwsRetryStrategy.standardRetryStrategy() .toBuilder() .maxAttempts(10) .build(); DynamoDbClient client = DynamoDbClient.builder() .overrideConfiguration(o -> o.retryStrategy(strategy)) .build();
警告
我们建议您为每个客户端配置一个唯一的RetryStrategy
实例。如果共享一个RetryStrategy
实例,则一个客户端的失败可能会影响另一个客户端的重试行为。
您也可以使用外部设置而不是代码来设置所有客户端的最大尝试次数。您可以按照一指定策略节中所述配置此设置。
自定义可重试的异常
您可以配置其他异常,以便在客户端构建期间触发停用。此自定义是为引发的异常未包含在默认可重试异常集中的异常的边缘情况提供的。
以下代码片段显示了用于自定义重试异常的方法—— retryOnException
和。retryOnExceptionOrCause
如果SDK引发直接异常或者异常被封装,则这些retryOnExceptionOrCause
方法会添加一个可重试的异常。
DynamoDbClient client = DynamoDbClient.builder() .overrideConfiguration(o -> o.retryStrategy( b -> b.retryOnException(EdgeCaseException.class) .retryOnExceptionOrCause(WrappedEdgeCaseException.class))) .build();
自定义退避策略
您可以制定退避策略并将其提供给客户。
以下代码构建了一个BackoffStrategy
替换默认标准策略的指数延迟退避策略的。
BackoffStrategy backoffStrategy = BackoffStrategy.exponentialDelay(Duration.ofMillis(150), // The base delay. Duration.ofSeconds(15)); // The maximum delay. DynamoDbClient client = DynamoDbClient.builder() .overrideConfiguration(o -> o.retryStrategy( b -> b.backoffStrategy(backoffStrategy))) .build();
从 RetryPolicy
迁移到 RetryStrategy
RetryPolicy
(重试政策API)将在可预见的将来得到支持。如果您当前使用的实例RetryPolicy
来配置客户端,则一切都会像以前一样正常运行。在幕后,Java将其SDK改编为RetryStrategy
. 新的重试策略接口提供的功能与 a 相同,RetryPolicy
但创建和配置方式有所不同。