

# REL05-BP03 控制与限制重试调用
<a name="rel_mitigate_interaction_failure_limit_retries"></a>

使用指数回退来重试请求，每次重试之间的间隔会逐渐延长。在两次重试之间引入抖动来随机调整重试间隔。限制最大重试次数。

 **期望结果：**分布式软件系统中的常见组件包括服务器、负载均衡器、数据库和 DNS 服务器。在正常运行期间，这些组件对请求的响应可能是临时错误或者受限制错误，也能是无论如何重试都会持续存在的错误。当客户端向服务发出请求时，请求会消耗资源，包括内存、线程、连接、端口或任何其他有限的资源。控制和限制重试策略用于释放资源并最大限度地减少资源消耗，这样就可以避免承受压力的系统组件不堪重负。

 当客户端请求超时或收到错误响应时，客户端应决定是否重试。如果进行重试，则会按照最大重试次数值，采用指数回退和抖动方法进行重试。因此，后端服务和进程可以缓解负载并缩短自我修复时间，从而加快恢复速度并成功处理服务请求。

 **常见反模式：**
+  实施重试，但没有添加指数回退、抖动和最大重试次数值。指数回退和抖动有助于避免因无意间按照相同间隔协调进行重试，从而导致的人为流量峰值。
+  实施重试但没有测试重试的效果，或者假设 SDK 中已经内置了重试而不测试重试场景。
+  无法理解依赖项发布的错误代码，导致重试所有错误，包括那些有明确原因的错误，这些错误指出缺乏权限、配置错误或其他预计需要手动干预才能解决的情况。
+  没有解决可观测性实践，包括监控反复出现的服务故障并发出警报，以便了解和解决潜在问题。
+  在内置或第三方重试功能便已足够时，开发自定义重试机制。
+  在应用程序堆栈的多层进行重试，而重试方法导致重试尝试复杂化，进一步加剧了重试风暴中的资源消耗。一定要了解这些错误对您的应用程序以及所依赖的依赖项有何影响，然后仅在一个级别实施重试。
+  重试非幂等的服务调用，导致意外的副作用，例如重复的结果。

 **建立此最佳实践的好处：**重试有助于客户端在请求失败时获得预期的结果，但也会消耗更多的服务器时间来获取所需的成功响应。当故障比率很低或者是临时性故障时，重试效果很好。当故障是由资源过载导致时，重试会导致情况进一步恶化。通过在客户端重试中添加指数回退和抖动，服务器可以从因资源过载导致的故障中恢复。抖动可避免请求同时出现造成峰值，指数回退可以减少因在正常请求负载中增添重试而导致的负载上升。最后，务必要配置最大重试次数或用时，避免产生导致亚稳态故障的积压。

 **在未建立这种最佳实践的情况下暴露的风险等级：**高 

## 实施指导
<a name="implementation-guidance"></a>

 控制与限制重试调用。在逐渐延长的间隔以后使用指数回退进行重试。引入抖动来随机调整重试间隔，并限制重试的最大次数。

 默认情况下，一些 AWS SDK 实施重试和指数回退。在适用于工作负载的情况下，使用这些内置 AWS 实施。在调用幂等性服务时，以及重试可以提高客户端可用性时，在工作负载中实施类似的逻辑。根据应用场景确定超时以及何时停止重试。为重试应用场景构建和演练测试场景。

## 实施步骤
<a name="implementation-steps"></a>
+  对于应用程序所依赖的服务，确定应用程序堆栈中最适合实施重试的层。
+  请注意，现有的 SDK 会针对您选择的语言，实施采用了指数回退和抖动方法的成熟重试策略，相比您自己编写重试实施，使用这些实施方法会更好。
+  请先验证[服务是否具有幂等性](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/)，再实施重试。实施重试后，请确保在生产环境中进行测试，并定期进行演练。
+  调用 AWS 服务 API 时，请使用 [AWS SDK](https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html) 和 [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-retries.html)，并了解重试配置选项。确定默认值是否适用于应用场景，进行测试，并根据需要进行调整。

## 资源
<a name="resources"></a>

 **相关最佳实践：**
+  [REL04-BP04 使变异操作幂等](rel_prevent_interaction_failure_idempotent.md) 
+  [REL05-BP02 限制请求](rel_mitigate_interaction_failure_throttle_requests.md) 
+  [REL05-BP04 快速失效机制和限制队列](rel_mitigate_interaction_failure_fail_fast.md) 
+  [REL05-BP05 设置客户端超时](rel_mitigate_interaction_failure_client_timeouts.md) 
+  [REL11-BP01 监控工作负载的所有组件以检测故障](rel_withstand_component_failures_monitoring_health.md) 

 **相关文档：**
+  [Error Retries and Exponential Backoff in AWS](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) 
+  [Amazon Builders' Library：超时、重试和抖动回退](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 
+ [ Exponential Backoff and Jitter ](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/)
+ [Making retries safe with idempotent APIs](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/)

 **相关示例：**
+ [Spring Retry](https://github.com/spring-projects/spring-retry)
+ [Resilience4j Retry](https://resilience4j.readme.io/docs/retry)

 **相关视频：**
+  [Retry, backoff, and jitter: AWS re:Invent 2019: Introducing The Amazon Builders' Library (DOP328)](https://youtu.be/sKRdemSirDM?t=1884) 

 **相关工具：**
+ [AWS SDKs and Tools: Retry behavior](https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html)
+ [AWS Command Line Interface: AWS CLI retries](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-retries.html)