

# 工作负载架构
<a name="a-workload-architecture"></a>

**Topics**
+ [REL 3  如何设计工作负载服务架构？](w2aac19b9b7b5.md)
+ [REL 4  您如何在分布式系统中设计交互以预防发生故障？](w2aac19b9b7b7.md)
+ [REL 5  您如何在分布式系统中进行交互设计，从而缓解或经受住故障影响？](w2aac19b9b7b9.md)

# REL 3  如何设计工作负载服务架构？
<a name="w2aac19b9b7b5"></a>

使用面向服务的架构 (SOA) 或微服务架构构建高度可扩展的可靠工作负载。面向服务的架构 (SOA) 可通过服务接口使软件组件可重复使用。微服务架构则进一步让组件变得更小、更简单。

**Topics**
+ [REL03-BP01 选择如何划分工作负载](rel_service_architecture_monolith_soa_microservice.md)
+ [REL03-BP02 构建专注于特定业务领域和功能的服务](rel_service_architecture_business_domains.md)
+ [REL03-BP03 根据 API 提供服务合同](rel_service_architecture_api_contracts.md)

# REL03-BP01 选择如何划分工作负载
<a name="rel_service_architecture_monolith_soa_microservice"></a>

 在确定应用程序的弹性要求时，工作负载划分很重要。应尽可能避免使用整体式架构。相反，应仔细考虑哪些应用程序组件可以分解为多项微服务。根据您的应用程序要求，最终应尽可能采用服务导向型架构（SOA）与微服务组合的形式。能够实现无状态的工作负载更容易部署为微服务。 

 **期望结果：** 工作负载应该可支持、可扩展，并尽可能地松散耦合。 

 在选择如何划分工作负载时，要权衡其优点和复杂性。适用于即将首次发布的新产品的功能有别于从一开始就构建用于扩展的工作负载的需求。重构一个现有的整体架构时，您需要考虑应用程序对无状态分解的支持程度。通过将服务分解为较小的部分，可以让职责明确的小型团队来开发和管理它们。然而，较小的服务会带来复杂性，包括可能会增加延迟，调试变得更复杂，而且加重运营负担。 

 **常见反模式：** 
+  如示例所示， [微服务 *Death Star*](https://mrtortoise.github.io/architecture/lean/design/patterns/ddd/2018/03/18/deathstar-architecture.html) 是这样一种情况：原子组件变得高度相互依赖，牵一发而动全身，使组件像一块整体一样死板而又脆弱。

 **建立此实践的好处：** 
+  更多特定分段可以提高敏捷性、组织灵活性和可扩展性。 
+  减小了服务中断的影响。 
+  应用程序组件可能有不同的可用性要求，可通过更加原子化的分段来满足这些要求。 
+  支持工作负载的团队职责分明。 

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

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

 请根据工作负载的分段方式选择架构类型。选择 SOA 或微服务架构（极少数情况下是整体架构）。即便在刚开始选择整体架构，您必须确保它是模块化的，而且由于您的产品随着采用的用户增加而扩展，它最终也可转变成为 SOA 或微服务架构。SOA 和微服务各自提供较小的区段，它们是现代可扩展和可靠架构的首选，但您需要认真权衡利弊，尤其在部署微服务架构时。 

 一项主要的权衡是您现在使用的是分布式计算架构，可能更难实现用户延迟要求，还增加了调试和跟踪用户交互的复杂性。您可以使用 AWS X-Ray 来帮助解决此问题。需要考虑的另一个影响是，您管理的应用程序数量增加时，运营复杂性也会随之增加，这要求部署多个相互独立组件。 

![\[整体架构、服务导向型架构和微服务架构之间的比较图\]](http://docs.aws.amazon.com/zh_cn/wellarchitected/2022-03-31/framework/images/monolith-soa-microservices-comparison.png)


## 实施步骤
<a name="implementation-steps"></a>
+  确定构建或重构应用程序所需的适当架构。SOA 和微服务分别提供较小分段，这是现代可扩展的可靠架构的首选。要在实现较小分段的同时避免一些微服务复杂性，SOA 是很好的折中方案。有关更多详细信息，请参阅 [微服务利弊权衡](https://martinfowler.com/articles/microservice-trade-offs.html). 
+  如果您的工作负载适合，并且您的组织可以支持，则应使用微服务架构来实现最佳敏捷性和可靠性。有关更多详细信息，请参阅 [在 AWS 上实施微服务。](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/introduction.html) 
+  考虑遵循 [*Strangler Fig* 模式，](https://martinfowler.com/bliki/StranglerFigApplication.html) 将整体架构重构为较小的组件。这包括逐步用新的应用程序和服务替换特定的应用程序组件。[AWS Migration Hub Refactor Spaces](https://docs.aws.amazon.com/migrationhub-refactor-spaces/latest/userguide/what-is-mhub-refactor-spaces.html) 作为增量重构的起点。有关更多详细信息，请参阅 [使用绞杀者模式无缝迁移本地传统工作负载](https://aws.amazon.com/blogs/architecture/seamlessly-migrate-on-premises-legacy-workloads-using-a-strangler-pattern/)。
+  实施微服务可能需要采用一种服务发现机制，让这些分布式服务能够相互通信。[AWS App Mesh](https://docs.aws.amazon.com/app-mesh/latest/userguide/what-is-app-mesh.html) 可用于服务导向型架构，以实现可靠的发现和服务访问。 [AWS Cloud Map](https://aws.amazon.com/cloud-map/) 也可用于动态的基于 DNS 的服务发现。
+  如果您要从整体架构迁移到 SOA，[Amazon MQ](https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/welcome.html) 可作为服务总线来帮助弥合这一差距（在云中重新设计传统应用程序时）。
+  对于具有单个共享数据库的现有整体架构，请选择将数据重组为较小分段的方式。可以按业务部门、访问模式或数据结构来划分。在重构过程的这一阶段，应选择是使用关系型还是非关系型（NoSQL）数据库来继续操作。有关更多详细信息，请参阅 [从 SQL 到 NoSQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SQLtoNoSQL.html).

 **实施计划的工作量级别：** 高 

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

 **相关最佳实践：** 
+  [REL03-BP02 构建专注于特定业务领域和功能的服务](rel_service_architecture_business_domains.md) 

 **相关文档：** 
+  [Amazon API Gateway：使用 OpenAPI 配置 REST API](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html) 
+  [什么是服务导向型架构？](https://aws.amazon.com/what-is/service-oriented-architecture/) 
+  [边界上下文（领域驱动设计的中心模式）](https://martinfowler.com/bliki/BoundedContext.html) 
+  [在 AWS 上实施微服务](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/introduction.html) 
+  [微服务利弊权衡](https://martinfowler.com/articles/microservice-trade-offs.html) 
+  [微服务 – 一个全新架构术语的定义](https://www.martinfowler.com/articles/microservices.html) 
+  [AWS 上的微服务](https://aws.amazon.com/microservices/) 
+  [什么是 AWS App Mesh？](https://docs.aws.amazon.com/app-mesh/latest/userguide/what-is-app-mesh.html) 

 **相关示例：** 
+  [迭代应用程序现代化研讨会](https://catalog.us-east-1.prod.workshops.aws/workshops/f2c0706c-7192-495f-853c-fd3341db265a/en-US/intro) 

 **相关视频：** 
+  [利用 AWS 上的微服务实现卓越](https://www.youtube.com/watch?v=otADkIyugzY) 

# REL03-BP02 构建专注于特定业务领域和功能的服务
<a name="rel_service_architecture_business_domains"></a>

 面向服务的架构（SOA，Service-Oriented Architecture）采用由业务需求定义的划分明确的功能来构建服务。微服务则使用领域模型和有界上下文对此进行进一步限制，使每项服务都只用于一种用途。专注于特定功能让您可以区分不同服务的可靠性要求，并且更有针对性地锁定投资目标。简洁的业务问题和与每项服务关联的小型团队也简化了组织扩展。 

 在设计微服务架构时，借助于领域驱动设计 (DDD) 对使用实体的业务问题进行建模十分有帮助。以 Amazon.com 网站为例，实体可能包括包装、配送、时间表、价格、折扣和货币。然后，该模型会使用 [https://martinfowler.com/bliki/BoundedContext.html](https://martinfowler.com/bliki/BoundedContext.html)进一步细分为更小的模型，具有相似功能和属性的实体在边界上下文中被分到一组。因此，在 Amazon.com 例子中，包装、配送和时间表是装运上下文的一部分，而价格、折扣和货币是定价上下文的一部分。通过将模型细分为不同的上下文，即可得到如何确定微服务边界的模板。 

![\[如何确定微服务边界的模型模板\]](http://docs.aws.amazon.com/zh_cn/wellarchitected/2022-03-31/framework/images/building-services.png)


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

## 实施指导
<a name="implementation-guidance"></a>
+  根据业务领域及各自的功能设计工作负载。专注于特定功能让您可以区分不同服务的可靠性要求，并且更有针对性地锁定投资目标。简洁的业务问题和与每项服务关联的小型团队也简化了组织扩展。 
  +  执行领域分析，为您的工作负载制定领域驱动设计 (DDD) 方案。然后，您可以选择一个架构类型，以满足您的工作负载需求。
    +  [如何将整体式架构分解为多项微服务](https://martinfowler.com/articles/break-monolith-into-microservices.html) 
    +  [在被遗留系统包围时通过 DDD 开始着手](https://domainlanguage.com/wp-content/uploads/2016/04/GettingStartedWithDDDWhenSurroundedByLegacySystemsV1.pdf) 
    +  [Eric Evans“领域驱动设计：解决软件核心的复杂性”](https://www.amazon.com/gp/product/0321125215) 
    +  [在 AWS 上实施微服务](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/introduction.html) 
+ 将服务分解成尽可能小的组件。借助微服务架构，您可以将工作负载分解成功能最小的组件，以便支持组织的可扩展性和敏捷性。
  +  根据工作负载及其设计目标、限制和任何其他使用注意事项来定义 API。
    +  定义 API。
      +  API 定义应允许增加参数。 
    +  定义设计可用性。
      + 您的 API 可以具有针对不同功能的多个设计目标。
    +  设置限制 
      +  通过测试来确定工作负载的功能限制。

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

 **相关文档：** 
+  [Amazon API Gateway：使用 OpenAPI 配置 REST API](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html) 
+  [边界上下文（领域驱动设计的中心模式）](https://martinfowler.com/bliki/BoundedContext.html) 
+  [Eric Evans“领域驱动设计：解决软件核心的复杂性”](https://www.amazon.com/gp/product/0321125215) 
+  [在被遗留系统包围时通过 DDD 开始着手](https://domainlanguage.com/wp-content/uploads/2016/04/GettingStartedWithDDDWhenSurroundedByLegacySystemsV1.pdf) 
+  [如何将整体式架构分解为多项微服务](https://martinfowler.com/articles/break-monolith-into-microservices.html) 
+  [在 AWS 上实施微服务](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/introduction.html) 
+  [微服务利弊权衡](https://martinfowler.com/articles/microservice-trade-offs.html) 
+  [微服务 – 一个全新架构术语的定义](https://www.martinfowler.com/articles/microservices.html) 
+  [AWS 上的微服务](https://aws.amazon.com/microservices/) 

# REL03-BP03 根据 API 提供服务合同
<a name="rel_service_architecture_api_contracts"></a>

 服务合同是团队之间关于服务集成的成文协议，它包括机器可读的 API 定义、速率限制和性能预期。版本控制策略让客户能够继续使用现有的 API，并在更新的 API 准备就绪时将他们的应用程序迁移到此类 API。只要遵守合同，即可随时进行部署。服务提供商团队可以使用自己选择的技术堆栈来满足 API 合同要求。同样，服务使用者可以使用自己的技术。 

 微服务将面向服务的架构（SOA，Service-Oriented Architecture）的概念提升到创建具有最小功能集的服务。每项服务都会发布一个 API，以及使用相应服务的设计目标、限制和其他注意事项。这会通过调用 *应用程序* 建立合同。这可以实现三个主要优势： 
+  服务具有一个需要解决的简明的业务问题，以及出现该业务问题的小型团队。这有助于更好地扩展组织。 
+  只要满足 API 和其他合同要求，团队就可以随时进行部署。 
+  只要满足 API 和其他合同要求，团队就可以使用他们想用的任何技术堆栈。 

 Amazon API Gateway 是一种完全托管式服务，可以帮助开发人员轻松创建、发布、维护、监控和保护任意规模的 API。它负责处理多达数十万个并发 API 调用的接受和处理过程中涉及的所有任务，包括流量管理、授权和访问控制、监控以及 API 版本管理。采用 OpenAPI 规范 (OAS)，亦即之前的 Swagger 规范，您可以定义 API 合同并将其导入到 API Gateway。然后，您便可以通过 API Gateway 对 API 进行版本控制与部署。 

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

## 实施指导
<a name="implementation-guidance"></a>
+  按照不同 API 提供服务合同：服务合同是团队之间关于服务集成的记录在案的协议，它包括机器可读的 API 定义、速率限制和性能预期等。 
  +  [Amazon API Gateway：使用 OpenAPI 配置 REST API](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html) 
    +  版本控制策略让客户能够继续使用现有的 API，并在更新的 API 准备就绪时将他们的应用程序迁移到此类 API。
    +  Amazon API Gateway 是一种完全托管式服务，可以帮助开发人员轻松创建任意规模的 API。采用 OpenAPI 规范（OAS，OpenAPI Specification），亦即之前的 Swagger 规范，您可以定义 API 合同并将其导入到 API Gateway。然后，您便可以通过 API Gateway 对 API 进行版本控制与部署。

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

 **相关文档：** 
+  [Amazon API Gateway：使用 OpenAPI 配置 REST API](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api.html) 
+  [边界上下文（领域驱动设计的中心模式）](https://martinfowler.com/bliki/BoundedContext.html) 
+  [在 AWS 上实施微服务](https://docs.aws.amazon.com/whitepapers/latest/microservices-on-aws/introduction.html) 
+  [微服务利弊权衡](https://martinfowler.com/articles/microservice-trade-offs.html) 
+  [微服务 – 一个全新架构术语的定义](https://www.martinfowler.com/articles/microservices.html) 
+  [AWS 上的微服务](https://aws.amazon.com/microservices/) 

# REL 4  您如何在分布式系统中设计交互以预防发生故障？
<a name="w2aac19b9b7b7"></a>

分布式系统依赖于通信网络实现组件（例如服务器或服务）的互联。尽管这些网络中存在数据丢失或延迟，但是您的工作负载必须可靠运行。分布式系统组件的运行方式不得对其他组件或工作负载产生负面影响。这些最佳实践能够预防故障，并改善平均故障间隔时间（MTBF）。

**Topics**
+ [REL04-BP01 确定需要哪种类型的分布式系统](rel_prevent_interaction_failure_identify.md)
+ [REL04-BP02 实施松耦合的依赖关系](rel_prevent_interaction_failure_loosely_coupled_system.md)
+ [REL04-BP03 持续工作](rel_prevent_interaction_failure_constant_work.md)
+ [REL04-BP04 使所有响应幂等](rel_prevent_interaction_failure_idempotent.md)

# REL04-BP01 确定需要哪种类型的分布式系统
<a name="rel_prevent_interaction_failure_identify"></a>

 硬性实时分布式系统需要同步并快速地做出响应，而软性实时系统有更宽松的以分钟计的时间窗口，或更多响应。离线系统会对响应进行批处理或异步处理。硬性实时分布式系统具有最严格的可靠性要求。 

 硬性实时分布式系统 [要面对分布式系统中的](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 最艰巨的挑战，又被称作请求/回复服务。因为收到请求的时间不可预测，而响应必须迅速（例如，客户正急切地等待响应）。此类示例包括，前端 Web 服务器、指令管道、信用卡交易，以及每个 AWS API 和语音通话。

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

## 实施指导
<a name="implementation-guidance"></a>
+  确定需要哪种类型的分布式系统。分布式系统要应对的挑战包括延迟、扩展、了解联网 API、对数据进行集结与解集，以及 Paxos 等算法的复杂性。随着系统规模扩大并呈现出更明显的分布态势，我们现在需要在日常生活中面对过去只存在于理论中的边缘情况。 
  +  [Amazon Builders' Library：分布式系统相关挑战](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
    +  硬性实时分布式系统需要快速的同步响应。
    +  软性实时系统则有更宽松的以分钟计的时间窗口，或更好响应。
    +  离线系统会对响应进行批处理或异步处理。 
    +  硬性实时分布式系统具有最严格的可靠性要求。

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

 **相关文档：** 
+  [Amazon EC2：确保幂等性](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html) 
+  [Amazon Builders' Library：分布式系统相关挑战](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [Amazon Builders' Library：可靠性、持续工作和安然无忧](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 
+  [什么是 Amazon EventBridge？](https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html) 
+  [什么是 Amazon Simple Queue Service？](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html) 

 **相关视频：** 
+  [2019 年 AWS 纽约峰会：介绍事件驱动型架构和 Amazon EventBridge（MAD205）](https://youtu.be/tvELVa9D9qU) 
+  [AWS re:Invent 2018：闭环系统和开放思维：如何掌控不同规模的系统（ARC337）（包括松耦合、持续工作和静态稳定性）](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019：迁移到事件驱动型架构（SVS308）](https://youtu.be/h46IquqjF3E) 

# REL04-BP02 实施松耦合的依赖关系
<a name="rel_prevent_interaction_failure_loosely_coupled_system"></a>

 队列系统、流系统、工作流和负载均衡器等依赖关系是松耦合的。松耦合有助于隔离某个组件的行为与依赖于它的其他组件的行为，从而提升弹性和敏捷性。 

 如果对一个组件的更改会强迫其他依赖于它的组件也发生更改，则它们之间的关系为 *紧密* 耦合。 *松散* 耦合会打破这种依赖关系，使存在依赖关系的组件只需了解经过版本控制而且已发布的接口。在依赖项之间实施松散耦合将隔离一个组件中的故障，防止对其他组件造成影响。 

 松散耦合让您可以为组件增加额外的代码或功能，同时在最大程度上降低依赖于它的组件的风险。而且，随着您可以横向扩展，或甚至更改依赖项的底层实施，可扩展性也得到改善。 

 要通过松散耦合进一步提升弹性，在可能的情况下采用异步组件交互。若确定对请求进行注册已足够，则此模型适用于无需立即响应的任何交互。它包含一个生成事件的组件和另外一个使用事件的组件。两个组件不会通过直接点对点交互，但通常经由中间持久存储层集成，例如，SQS 队列或诸如 Amazon Kinesis 或 AWS Step Functions 流数据平台。 

![\[显示队列系统和负载均衡器等依赖关系是松耦合的图表\]](http://docs.aws.amazon.com/zh_cn/wellarchitected/2022-03-31/framework/images/loosely-coupled-dependencies.png)


 Amazon SQS 队列和 Elastic Load Balancer 只是为松散耦合增加中间层的两种方式。您还可以使用 Amazon EventBridge 在 AWS 云 中构建事件驱动型架构，而前者可从其依赖的服务（事件使用器）中提取客户端（事件产生器）。当您需要进行高吞吐量、基于推送的多对多消息收发时，Amazon Simple Notification Service（Amazon SNS）是可供选择的高效解决方案。通过 Amazon SNS 主题，您的发布者系统可以呈扇形将消息分发到大量订阅者终端节点以便进行并行处理。 

 虽然队列具有多项优点，但在大多数硬性实时系统中，早于阈值时间（通常为秒）的请求应被视为过时（客户端已放弃而且不再等待响应）而不被处理。因此，较新（而且可能依然有效）的请求会被处理。 

 **常见反模式：** 
+  将单一实例作为工作负载的一部分部署。 
+  直接在工作负载层之间调用 API，不具备故障转移或异步处理请求的功能。 

 **建立此最佳实践的好处：** 松耦合有助于隔离某个组件的行为与依赖于它的其他组件的行为，从而提升弹性和敏捷性。组件中的故障相互隔离。 

 **未建立此最佳实践暴露的风险等级：** 高 

## 实施指导
<a name="implementation-guidance"></a>
+  实施松耦合的依赖关系。队列系统、流系统、工作流和负载均衡器等依赖关系是松耦合的。松耦合有助于隔离某个组件的行为与依赖于它的其他组件的行为，从而提升弹性和敏捷性。 
  +  [AWS re:Invent 2019：迁移到事件驱动型架构（SVS308）](https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html) 
  +  [什么是 Amazon EventBridge？](https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html) 
  +  [什么是 Amazon Simple Queue Service？](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html) 
    +  您可借助 Amazon EventBridge 构建松耦合的分布式事件驱动型架构。
      +  [2019 年 AWS 纽约峰会：介绍事件驱动型架构和 Amazon EventBridge（MAD205）](https://youtu.be/tvELVa9D9qU) 
    +  如果对一个组件的更改会强迫其他依赖于它的组件也发生更改，则它们之间的关系为紧耦合。松耦合会打破这种依赖关系，使存在依赖关系的组件只需了解经过版本控制而且已发布的接口。
    +  让组件在可能的情况下进行异步交互。此模型适用于无需立即响应，只需确认请求已注册就足够的任何交互。
      +  [AWS re:Invent 2019：使用 Amazon SQS 和 Lambda 的可扩展无服务器事件驱动型应用程序（API304）](https://youtu.be/2rikdPIFc_Q) 

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

 **相关文档：** 
+  [AWS re:Invent 2019：迁移到事件驱动型架构（SVS308）](https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html) 
+  [Amazon EC2：确保幂等性](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html) 
+  [Amazon Builders' Library：分布式系统相关挑战](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [Amazon Builders' Library：可靠性、持续工作和安然无忧](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 
+  [什么是 Amazon EventBridge？](https://docs.aws.amazon.com/eventbridge/latest/userguide/what-is-amazon-eventbridge.html) 
+  [什么是 Amazon Simple Queue Service？](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html) 

 **相关视频：** 
+  [2019 年 AWS 纽约峰会：介绍事件驱动型架构和 Amazon EventBridge（MAD205）](https://youtu.be/tvELVa9D9qU) 
+  [AWS re:Invent 2018：闭环系统和开放思维：如何掌控不同规模的系统（ARC337）（包括松耦合、持续工作和静态稳定性）](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019：迁移到事件驱动型架构（SVS308）](https://youtu.be/h46IquqjF3E) 
+  [AWS re:Invent 2019：使用 Amazon SQS 和 Lambda 的可扩展无服务器事件驱动型应用程序（API304）](https://youtu.be/2rikdPIFc_Q) 

# REL04-BP03 持续工作
<a name="rel_prevent_interaction_failure_constant_work"></a>

 系统会在负载中存在剧烈快速更改时失败。例如，如果您的工作负载执行的一项运行状况检查监控着数千个服务器的运行状况，每次都应发送相同大小的有效负载（当前状态的完整快照）。无论是否有服务器或有多少服务器发生故障，运行状况检查系统都会持续工作，而不会有剧烈、快速的变动。 

 例如，如果运行状况检查系统正在监控 100000 个服务器，它的标称负载低于通常而言较低的服务器故障率。但如果发生重大事件使一半的服务器运行不正常，则运行状况检查系统会因为尝试更新通知系统以及向其客户端传送状态而变得不堪重负。因此，运行状况检查系统每次应发送当前状态的完整快照。100000 个服务器的运行状况，若每个以一个比特代表，则仅需要 12.5-KB 有效负载。无论是没有服务器发生故障还是所有服务器都发生故障，运行状况检查系统都会持续工作，而大幅度骤变也不会威胁到系统的稳定性。这实际上是 Amazon Route 53 处理端点（例如 IP 地址）的运行状况检查来确定最终用户如何路由到这些端点的方式。 

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

## 实施指导
<a name="implementation-guidance"></a>
+  持续工作，使系统不会在负载出现骤变时失败。 
+  实施松耦合的依赖关系。队列系统、流系统、工作流和负载均衡器等依赖关系是松耦合的。松耦合有助于隔离某个组件的行为与依赖于它的其他组件的行为，从而提升弹性和敏捷性。 
  +  [Amazon Builders' Library：可靠性、持续工作和安然无忧](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 
  +  [AWS re:Invent 2018：闭环系统和开放思维：如何掌控不同规模的系统（ARC337）（包括持续工作）](https://youtu.be/O8xLxNje30M?t=2482) 
    +  例如，如果运行状况检查系统正在监控 10 万台服务器工程设计工作负载，不论成功或失败的次数，有效负载大小均能保持稳定。

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

 **相关文档：** 
+  [Amazon EC2：确保幂等性](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html) 
+  [Amazon Builders' Library：分布式系统相关挑战](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [Amazon Builders' Library：可靠性、持续工作和安然无忧](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 

 **相关视频：** 
+  [2019 年 AWS 纽约峰会：介绍事件驱动型架构和 Amazon EventBridge（MAD205）](https://youtu.be/tvELVa9D9qU) 
+  [AWS re:Invent 2018：闭环系统和开放思维：如何掌控不同规模的系统（ARC337）（包括持续工作）](https://youtu.be/O8xLxNje30M?t=2482) 
+  [AWS re:Invent 2018：闭环系统和开放思维：如何掌控不同规模的系统（ARC337）（包括松耦合、持续工作和静态稳定性）](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019：迁移到事件驱动型架构（SVS308）](https://youtu.be/h46IquqjF3E) 

# REL04-BP04 使所有响应幂等
<a name="rel_prevent_interaction_failure_idempotent"></a>

 幂等服务承诺每个请求只完成一次，因此发起多个相同请求与进行单个请求的效果相同。幂等服务使客户端可以轻松进行重试，而不必担心错误地处理多次。要执行此操作，客户端可以发出具有幂等性令牌的 API 请求，每当重复请求时都会使用同一令牌。幂等服务 API 使用令牌返回响应，该响应与首次完成请求时返回的响应相同。 

 在分布式系统中，至多（客户端仅发起一个请求）或至少（持续发起请求直到客户端收到成功确认）执行某项操作一次并不难。难就难在要保证某项操作具有幕等性，亦即它被 *恰好* 执行一次，从而使发起多个相同的请求与发起一个请求的效果相同。在 API 中使用幕等性令牌，服务可以一次或多次收到变异请求，而不会创建重复记录或产生副作用。 

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

## 实施指导
<a name="implementation-guidance"></a>
+  使所有响应幂等。幂等服务承诺每个请求只完成一次，因此发起多个相同请求与进行单个请求的效果相同。 
  +  客户端可以发出具有幂等性令牌的 API 请求，每当重复请求时都会使用同一令牌。幂等服务 API 使用令牌返回响应，该响应与首次完成请求时返回的响应相同。
    +  [Amazon EC2：确保幂等性](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html) 

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

 **相关文档：** 
+  [Amazon EC2：确保幂等性](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Run_Instance_Idempotency.html) 
+  [Amazon Builders' Library：分布式系统相关挑战](https://aws.amazon.com/builders-library/challenges-with-distributed-systems/) 
+  [Amazon Builders' Library：可靠性、持续工作和安然无忧](https://aws.amazon.com/builders-library/reliability-and-constant-work/) 

 **相关视频：** 
+  [2019 年 AWS 纽约峰会：介绍事件驱动型架构和 Amazon EventBridge（MAD205）](https://youtu.be/tvELVa9D9qU) 
+  [AWS re:Invent 2018：闭环系统和开放思维：如何掌控不同规模的系统（ARC337）（包括松耦合、持续工作和静态稳定性）](https://youtu.be/O8xLxNje30M) 
+  [AWS re:Invent 2019：迁移到事件驱动型架构（SVS308）](https://youtu.be/h46IquqjF3E) 

# REL 5  您如何在分布式系统中进行交互设计，从而缓解或经受住故障影响？
<a name="w2aac19b9b7b9"></a>

分布式系统依赖于通信网络以便使组件互相连接（如服务器或服务等）。尽管这些网络中存在数据丢失或延迟，但是您的工作负载必须可靠运行。分布式系统组件的运行方式不得对其他组件或工作负载产生负面影响。这些最佳实践使工作负载能够承受压力或故障，从中更快地恢复，并且降低此类伤害的影响。其结果是缩短平均恢复时间（MTTR）。

**Topics**
+ [REL05-BP01 实施轻松降级以将适用的硬依赖关系转换为软依赖关系](rel_mitigate_interaction_failure_graceful_degradation.md)
+ [REL05-BP02 限制请求](rel_mitigate_interaction_failure_throttle_requests.md)
+ [REL05-BP03 控制与限制重试调用](rel_mitigate_interaction_failure_limit_retries.md)
+ [REL05-BP04 快速失效机制和限制队列](rel_mitigate_interaction_failure_fail_fast.md)
+ [REL05-BP05 设置客户端超时](rel_mitigate_interaction_failure_client_timeouts.md)
+ [REL05-BP06 尽可能使服务为无状态](rel_mitigate_interaction_failure_stateless.md)
+ [REL05-BP07 实施紧急杠杆](rel_mitigate_interaction_failure_emergency_levers.md)

# 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) 

# REL05-BP02 限制请求
<a name="rel_mitigate_interaction_failure_throttle_requests"></a>

 限制请求是对需求意外增加做出响应的缓解模式。部分请求会得到执行，但超出定义限制的请求会被拒绝，并返回说明它们已被限制的消息。客户端预期将会回退，并且放弃请求或以较低速率进行重试。 

 您的服务应设计为可以应对每个节点或单元格所能处理的已知请求容量。此容量可以通过负载测试确定。然后，您需要跟踪请求到达速率，如果临时到达速率超过此限制，则相应的响应是发出信号表明请求已被限制。这允许用户进行重试，或许会向可能具有可用容量的另一个节点或单元格发出请求。Amazon API Gateway 提供一些限制请求的方法。Amazon SQS 和 Amazon Kinesis 可对请求进行缓冲，平滑请求速率并降低对可异步处理的请求进行限制的需求。 

 **未建立此最佳实践暴露的风险等级：** 高 

## 实施指导
<a name="implementation-guidance"></a>
+  限制请求。这是对按需求意外增加做出响应的缓解模式。部分请求会得到执行，但超出定义限制的请求会被拒绝，并返回说明它们已被限制的消息。客户端预期将会回退，并且放弃请求或以较低速率进行重试。 
  +  使用 Amazon API Gateway 
    +  [对 API 请求限流以提高吞吐量](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 

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

 **相关文档：** 
+  [Amazon API Gateway：对 API 请求限流以提高吞吐量](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 
+  [AWS 中的错误重试和指数回退](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) 
+  [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/timeouts-retries-and-backoff-with-jitter/) 
+  [对 API 请求限流以提高吞吐量](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 

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

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

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

 分布式软件系统中的常见组件包括服务器、负载均衡器、数据库和 DNS 服务器。在操作中，受故障影响，任何此类组件都可能开始生成错误。处理错误的默认方式为，在客户端实施重试。此方法可提高应用程序的可靠性和可用性。不过，如果规模较大，而且客户端在错误发生时立即重试失败的操作，网络中的新请求和重试请求可能会快速导致饱和，并争用网络带宽。这可能导致 *重试风暴，* 从而降低服务的可用性。此模式可能会继续，直到发生全系统故障。 

 为避免出现此情况，应使用回退算法，如常用的 *指数回退* 。指数回退算法会逐渐降低执行重试的速率，从而避免网络阻塞。 

 很多开发工具包和软件库（包括 AWS 的开发工具包和软件库）都实施此类算法的一种版本。但是， **别心存侥幸地认为已采用回退算法，始终要进行测试和验证。** 

 仅依靠回退还不够，因为在分布式系统中，所有客户端都可能同步回退，形成重试调用集群。Marc Brooker 在他的博文 [指数回退和抖动](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-italics%0djitter/)中解释了如何修改指数回退中的 wait() 函数以防止形成重试调用集群。他给出的解决办法 *是* 在 wait() 函数中增加抖动。要避免过长时间的重试，实施应为回退设置一个最大值限制。 

 最后，务必要配置 *最大重试次数* 或已用时间，在此以后，重试将失败。AWS 开发工具包将默认实施此操作，而且也可以对它进行配置。针对堆栈中较低的服务，最大重试限制为 0 或 1 可以限制风险，而且在将重试委派给堆栈较高的服务时依然有效。 

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

## 实施指导
<a name="implementation-guidance"></a>
+  控制与限制重试调用。在逐渐延长的间隔以后使用指数回退进行重试。引入抖动使此类重试间隔随机化，并限制重试的最大次数。 
  +  [AWS 中的错误重试和指数回退](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) 
    + 默认情况下，Amazon SDK 实施重试和指数回退。在调用自己的依赖服务时，您需要在依赖关系层中执行类似的逻辑。根据您的使用案例确定超时以及何时停止重试。

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

 **相关文档：** 
+  [Amazon API Gateway：对 API 请求限流以提高吞吐量](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 
+  [AWS 中的错误重试和指数回退](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) 
+  [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) 

# REL05-BP04 快速失效机制和限制队列
<a name="rel_mitigate_interaction_failure_fail_fast"></a>

 如果工作负载无法成功响应请求，则快速试错。这样可释放与请求关联的资源，并允许该服务在资源不足的情况下恢复。如果工作负载能够成功响应，但请求速率过高，则使用队列来对请求进行缓冲。不过，不要允许使用长队列，它可能导致处理已被客户端放弃的过时请求。 

 此最佳实践适用于请求的服务器端，或接收方。 

 请注意，可在系统的多个级别创建队列，它们可能严重妨碍快速恢复的能力，因为需要先处理较旧的过时请求（虽然不再需要响应），然后才会处理较新的请求。另外还要注意队列所在的位置。它们通常会隐藏在工作流或记录到数据库的工作中。 

 **未建立此最佳实践暴露的风险等级：** 高 

## 实施指导
<a name="implementation-guidance"></a>
+  快速失效机制和限制队列。如果工作负载无法成功响应请求，则快速试错。这样可释放与请求关联的资源，并允许该服务在资源不足的情况下恢复。如果工作负载能够成功响应，但请求速率过高，则使用队列来对请求进行缓冲。不过，不要允许使用长队列，它可能导致处理已被客户端放弃的过时请求。 
  +  在服务面临压力时执行快速失效机制。
    +  [快速试错](https://www.martinfowler.com/ieeeSoftware/failFast.pdf) 
  +  限制队列：在基于队列的系统中，如果在停止处理后消息仍不断涌入，则消息债务可能造成大量积压，从而增加处理时间。工作完成太晚，以至于结果无法发挥作用，从根本上导致了队列原本要避免的可用性打击问题。
    +  [Amazon Builders' Library：避免无法克服的队列积压](https://aws.amazon.com/builders-library/avoiding-insurmountable-queue-backlogs) 

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

 **相关文档：** 
+  [AWS 中的错误重试和指数回退](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) 
+  [快速试错](https://www.martinfowler.com/ieeeSoftware/failFast.pdf) 
+  [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) 

# REL05-BP05 设置客户端超时
<a name="rel_mitigate_interaction_failure_client_timeouts"></a>

 适当设置超时，对它们进行系统性验证，而且不要依靠默认值，因为默认值通常设置得过高。 

 此最佳实践适用于请求的客户端，或发送方。 

 为任何远程调用和大体上任何跨流程调用设置连接超时和请求超时。许多框架具有内置超时功能，但仍需谨慎，因为许多默认值为无限值或过高。过高的值会降低超时的实用性，因为客户端等待超时发生时，系统会继续消耗资源。过低的值可能因为要重试过多请求而导致后端流量增加以及延迟变长。在有些情况下，由于要对全部请求进行重试，从而可能导致完全中断。 

 要了解关于 Amazon 如何利用超时、重试和抖动回退的更多信息，请参阅 [https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/?did=ba_card&trk=ba_card](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/?did=ba_card&trk=ba_card). 

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

## 实施指导
<a name="implementation-guidance"></a>
+  为任何远程调用和大体上任何跨流程调用设置连接超时和请求超时。许多框架具有内置超时功能，但仍需谨慎，因为许多默认值为无限值或过高。过高的值会降低超时的实用性，因为客户端等待超时发生时，系统会继续消耗资源。过低的值可能因为要重试过多请求而导致后端流量增加以及延迟变长。在有些情况下，由于要对全部请求进行重试，从而可能导致完全中断。 
  +  [AWS 开发工具包：重试次数和超时](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/retries-timeouts.html) 

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

 **相关文档：** 
+  [AWS 开发工具包：重试次数和超时](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/retries-timeouts.html) 
+  [Amazon API Gateway：对 API 请求限流以提高吞吐量](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html) 
+  [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/) 

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

# REL05-BP06 尽可能使服务为无状态
<a name="rel_mitigate_interaction_failure_stateless"></a>

 服务应该不需要状态，或者在不同的客户端请求之间卸载状态，磁盘上和内存中本地存储的数据不存在依赖关系。这使任意替换服务器成为可能，而且不会对可用性产生影响。Amazon ElastiCache 或 Amazon DynamoDB 是卸载状态的理想目标位置。 

![\[在此无状态 Web 应用程序中，会话状态会被卸载到 Amazon ElastiCache。\]](http://docs.aws.amazon.com/zh_cn/wellarchitected/2022-03-31/framework/images/stateless-webapp.png)


 当用户或服务与应用程序进行交互，它们通常会执行一系列交互并构成一次会话。对于用户来说，会话是他们在使用应用程序时持续存在于请求之间的特殊数据。无状态应用程序是无需掌握之前交互而且不会存储会话信息的应用程序。 

 若采用无状态设计，则您可以使用无服务器计算服务，如 AWS Lambda 或 AWS Fargate。 

 除了服务器替换，无状态应用程序的另一项优点是，由于任何可用的计算资源（如 EC2 实例和 AWS Lambda 函数）都可以处理任何请求，因此它们可以进行横向扩展。 

 **未建立此最佳实践暴露的风险等级：** 中 

## 实施指导
<a name="implementation-guidance"></a>
+  让应用程序无状态。无状态应用程序支持水平扩展，并且可以承受单个节点故障。 
  +  删除可能存储在请求参数中的状态。
  +  在检查是否需要状态之后，将任何状态追踪移动到具有弹性的多区域缓存或数据存储（如 Amazon ElastiCache、Amazon RDS、Amazon DynamoDB 或第三方分布式数据解决方案）。存储无法移动到弹性数据存储的状态。
    +  某些数据（例如 cookie）可能在标头或查询参数中传递。 
    +  进行重构，从而删除可能在请求中快速传递的状态。
    +  提交请求时实际上并不需要某些数据，这些数据可以按需检索。
    +  删除可以异步检索的数据。
    +  确定满足所需状态要求的数据存储。 
    +  考虑针对非关系型数据使用 NoSQL 数据库。

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

 **相关文档：** 
+  [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/) 

# REL05-BP07 实施紧急杠杆
<a name="rel_mitigate_interaction_failure_emergency_levers"></a>

 紧急杠杆是可帮助您的工作负载减轻可用性影响的快速流程。 

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

## 实施指导
<a name="implementation-guidance"></a>
+  实施紧急杠杆。这些是可帮助您的工作负载减轻可用性影响的快速流程。即使未找到根本原因，它们也可以运行。理想的紧急杠杆可通过提供完全确定的激活与停用标准，将解析器的认知负担降低到零。杠杆通常需要手动操作，但也可实现自动化 
  +  杠杆示例包括， 
    +  阻止所有机器人流量 
    +  为静态页面而非动态页面提供服务 
    +  减少对依赖项的调用频率 
    +  限制来自依赖项的调用 
  +  关于实施和使用紧急杠杆的提示 
    +  当杠杆被激活时，求少不求多 
    +  保持简单，避免双模态行为 
    +  定期测试您的杠杆 
  +  以下为非紧急杠杆的操作示例 
    +  添加容量 
    +  号召依赖您的服务的客户端服务所有者，要求他们降低调用 
    +  更改代码并将其释放 