

# REL05-BP01 实施轻松降级以将适用的硬依赖关系转换为软依赖关系
<a name="rel_mitigate_interaction_failure_graceful_degradation"></a>

 某个组件的依赖关系运行不正常时，该组件仍可在性能降低的条件下运行。例如，当依赖关系调用失败时，进行故障转移，使用预先确定的静态响应。 

 假设被服务 A 调用的服务 B 反过来调用服务 C。 

![\[图中显示若服务 B 调用服务 C 失败，服务 B 向服务 A 返回降级响应\]](http://docs.aws.amazon.com/zh_cn/wellarchitected/2022-03-31/framework/images/graceful-degradation.png)


 当服务 B 调用服务 C 时，它会收到错误或超时消息。而服务 B，因为缺少来自服务 C（及其所包含数据）的响应，则会返回它能够做出的响应。它可以是最后缓存的正确值，或服务 B 可以使用预先确定的静态响应取代它收到的来自服务 C 的响应。然后，向调用方（即服务 A）返回降级响应。若无此静态响应，服务 C 的故障将级联传递至服务 B 和服务 A，因此而丧失可用性。 

 按照硬依赖关系可用性等式中的倍乘系数（见 [https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/availability.html#dbedbedda68f9a15ACLX122](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/availability.html#dbedbedda68f9a15ACLX122)），C 的可用性的任何降低将严重影响 B 的有效可用性。通过返回静态响应，服务 B 能够缓解 C 中的故障的影响，而且，虽然被降级，可使服务 C 看起来似乎 100% 可用（假设它在错误的情况下可靠地返回静态响应）。注意，静态响应是返回错误的简单替代，而不是使用其他方式对响应进行重新计算的尝试。此类采用完全不同的机制试图达到相同结果的尝试被称作回退行为，是一种要被避免的反模式。 

 优雅降级的另一个例子是 *断路器模式*.当故障为临时性时，应采用重试策略。若情况并非如此，而且操作很有可能失败，则断路器模式会防止客户端执行可能失败的请求。系统照常处理请求时，断路器会处于关闭状态，让请求正常通过。当远程系统开始返回错误或出现高延迟，断路器就会打开，依赖项被忽略，或者结果会被更轻松获取但较不全面的响应（可能只是响应缓存）所取代。系统将定期尝试调用依赖项，以确定它是否已恢复。出现这种情况时，断路器将处于关闭状态。 

![\[显示断路器处于开启和关闭状态的图表。\]](http://docs.aws.amazon.com/zh_cn/wellarchitected/2022-03-31/framework/images/circuit-breaker.png)


 除了图表中显示的关闭和开启状态，在开启状态内的可配置时间段以后，断路器可能会变为半开启状态。在此状态中，它会以远低于正常水平的速率定期尝试调用服务。此探测器用于检查服务的运行状况。在半开启状态中多次成功以后，断路器会转为关闭，并恢复正常请求。 

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

## 实施指导
<a name="implementation-guidance"></a>
+  实施轻松降级以将适用的硬依赖关系转换为软依赖关系。某个组件的依赖关系运行不正常时，该组件仍可在性能降低的条件下运行。例如，当依赖关系调用失败时，进行故障转移，使用预先确定的静态响应。 
  +  通过返回静态响应，您的工作负载会缓解其依赖项中发生的故障。
    +  [Well-Architected 实验室：第 300 级：实施运行状况检查和管理依赖项以提高可靠性](https://wellarchitectedlabs.com/Reliability/300_Health_Checks_and_Dependencies/README.html) 
  +  在重试操作可能失败时检测到该情况，并防止您的客户端使用断路器模式进行失败调用。
    +  [CircuitBreaker](https://martinfowler.com/bliki/CircuitBreaker.html) 

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

 **相关文档：** 
+  [Amazon API Gateway：对 API 请求限流以提高吞吐量](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 
+  [CircuitBreaker（对《发布它！》一书中的“断路器”部分进行的总结）](https://martinfowler.com/bliki/CircuitBreaker.html) 
+  [AWS 中的错误重试和指数回退](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) 
+  [Michael Nygard《发布它！ 设计和部署生产就绪的软件》（Release It\$1 Design and Deploy Production-Ready Software）](https://pragprog.com/titles/mnee2/release-it-second-edition/) 
+  [Amazon Builders' Library：避免在分布式系统中回退](https://aws.amazon.com/builders-library/avoiding-fallback-in-distributed-systems) 
+  [Amazon Builders' Library：避免无法克服的队列积压](https://aws.amazon.com/builders-library/avoiding-insurmountable-queue-backlogs) 
+  [Amazon Builders' Library：缓存挑战和策略](https://aws.amazon.com/builders-library/caching-challenges-and-strategies/) 
+  [Amazon Builders' Library：为超时、重试和回退引入抖动](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) 

 **相关视频：** 
+  [重试、回退和抖动：AWS re:Invent 2019：介绍 Amazon Builders’ Library（DOP328）](https://youtu.be/sKRdemSirDM?t=1884) 

 **相关示例：** 
+  [Well-Architected 实验室：第 300 级：实施运行状况检查和管理依赖项以提高可靠性](https://wellarchitectedlabs.com/Reliability/300_Health_Checks_and_Dependencies/README.html) 