

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

# 在上设计高度可用的分布式系统 AWS
<a name="designing-highly-available-distributed-systems-on-aws"></a>

 前面的章节主要介绍了工作负载的理论可用性及其作用。它们是构建分布式系统时要记住的一组重要概念，可以为依赖项的选择和冗余的实现提供决策依据。

 我们还研究了MTTDMTTR、和与可用MTBF性的关系。这一部分将会基于之前的理论提供一些实用的指导。简而言之，高可用性的工程工作负载旨在增加MTBF和减少MTTR以及MTTD。

 最理想的结果是消除所有故障，但这并不现实。依赖项严重堆叠的大型分布式系统一定会发生故障。“一切都会失败”（参见 Werner VogelsCTO，Amazon.com，《[亚马逊网络服务 10 年的十个教训](https://www.allthingsdistributed.com/2016/03/10-lessons-from-10-years-of-aws.html)》。）和 “你无法立法防止失败 [所以] 专注于快速检测和响应。” （参见 Chris Pinkham，Amazon EC2 团队创始成员，《[为失败而ARC335设计：在上面架构弹性系统](https://d1.awsstatic.com/events/reinvent/2019/REPEAT_1_Designing_for_failure_Architecting_resilient_systems_on_AWS_ARC335-R1.pdf)》） AWS

 这意味着我们往往无法控制故障是否发生。我们可以控制的，是自己检测故障并采取措施的速度。因此，尽管提高可用性仍然MTBF是高可用性的重要组成部分，但客户可以控制的最重大变化是减少MTTD和MTTR。

**Topics**
+ [减少 MTTD](reducing-mttd.md)
+ [减少 MTTR](reducing-mttr.md)
+ [越来越多 MTBF](increasing-mtbf.md)

# 减少 MTTD
<a name="reducing-mttd"></a>

 减少故障意味着要尽快发现故障。MTTD缩短MTTD是基于可观察性，或者你如何对工作负载进行检测以了解其状态。客户应监控其工作负载关键子系统中的*客户体验*指标，以便主动识别问题何时发生（请参阅[附录1），MTTD并监控MTTR关键指标](appendix-1-mttd-and-mttr-critical-metrics.md)以了解有关这些指标的更多信息。)。 客户可以使用 [Amazon CloudWatch Synthetics](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries.html) 创建用于监控您APIs和控制台的*金丝雀*，从而主动衡量用户体验。还有许多其他运行状况检查机制可用于最大限度地减少运行状况，例如 [Elastic Load Balancing (ELB) 运行状况检查](https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-add-elb-healthcheck.html)、[Amazon Route 53 运行状况检查](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/health-checks-types.html)等。MTTD（参见 [Amazon Builders's Library — 实施运行状况检查](https://aws.amazon.com/builders-library/implementing-health-checks/)。） 

 您的监控机制还需要能够检测整个系统和单个子系统的部分故障。您的可用性、故障和延迟指标应使用故障隔离边界的维[CloudWatch 度作为指标](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#Dimension)维度。例如，假设一个属于基于单元的架构、use1-az1 AZ、useast-1 区域中的单个EC2实例，它是工作负载更新的一部分，也是其控制平面子系统的一部分。API当服务器推送其指标时，它可以使用其实例 ID、可用区、区域、API名称和子系统名称作为维度。这让您可以进行观测，并针对每个维度设置警报以便检测故障。

# 减少 MTTR
<a name="reducing-mttr"></a>

 发现故障后，剩下的MTTR时间是实际修复或减轻影响。要修复或缓解故障，您必须知道发生了什么问题。在这一阶段，有两组关键指标可以提供见解：*1/影响评估*指标和 2/*运营状况*指标。第一组指标可以告诉您故障的影响范围，并衡量受影响的客户、资源或工作负载的数量或百分比。第二组指标有助于确定产生影响的*原因*。发现原因后，操作人员和自动化机制可以响应和消除故障。有关这些[指标的更多信息，请参阅附录 1 MTTD 和MTTR关键](appendix-1-mttd-and-mttr-critical-metrics.md)指标。

**规则 9**  
可观察性和仪器化对于减少MTTD和MTTR至关重要。

## 绕过故障
<a name="route-around-failure"></a>

 减轻影响的最快方法是使用能够绕过故障的快速失效子系统。这种方法使用冗余，MTTR通过将故障子系统的工作快速转移到备用子系统来减少工作量。冗余范围从软件进程到EC2实例，再到多个区域AZs，再到多个区域。

 备用子系统可以将MTTR降至几乎为零。恢复时间仅仅是将工作重定向到备件所花费的时间。这通常以最小的延迟发生，并允许在定义的范围内完成工作SLA，从而保持系统的可用性。MTTRs这会产生轻微的、甚至可能难以察觉的延迟，而不是长时间的不可用。

 例如，如果您的服务使用的是 Application Load Balancer (ALB) 之后的EC2实例，则您可以以短至五秒的间隔配置运行状况检查，并且只需要两次失败的运行状况检查即可将目标标记为不健康。这意味着您可以在 10 秒钟内检测到故障，并停止向运行状况不佳的主机发送流量。在这种情况下，MTTR实际上与相同，MTTD因为一旦检测到故障，它也会得到缓解。

 这就是*高可用性*或*持续可用性*工作负载想要实现的目标。我们希望快速检测到发生故障的子系统，将其标记为故障，停止向其发送流量，然后将流量发送到冗余子系统，从而快速绕过工作负载中的故障。

 请注意，使用这种快速失效机制会让您的工作负载对瞬时错误非常敏感。在上面的示例中，我们应该确保负载均衡器运行状况检查仅对实例执行*浅层*或[https://aws.amazon.com/builders-library/implementing-health-checks/](https://aws.amazon.com/builders-library/implementing-health-checks/)运行状况检查，而不会对依赖项或工作流程执行测试（通常称为*深度*运行状况检查）。这有助于防止在影响工作负载的瞬时错误期间不必要地替换实例。

 可观测性和检测子系统故障的能力对于成功绕过故障至关重要。您必须知道影响范围，这样才能将受影响的资源标记为运行状况不佳或出现故障，然后停止服务，将其绕过。例如，如果单个可用区出现部分服务受损，则您的检测工具需要能够识别出存在可用区范围内的问题，以便绕过该可用区内的所有资源，直到其恢复为止。

 绕过故障可能还需要额外的工具，具体取决于环境。使用前面的示例，EC2实例位于后面ALB，假设一个可用区中的实例可能正在通过本地运行状况检查，但是孤立的可用区缺陷导致它们无法连接到另一可用区中的数据库。在这种情况下，负载均衡运行状况检查不会让这些实例停止服务。这就需要一种不同的自动化机制来[从负载均衡器中移除可用区](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-subnets.html)或让实例无法通过运行状况检查，而这又需要确定影响范围是否为可用区。对于未使用负载均衡器的工作负载，需要使用类似的方法来防止特定可用区中的资源接受工作单元或完全移除可用区的容量。

 在某些情况下，我们无法将工作自动转移到冗余子系统，例如在没有主节点选择机制的情况下将主数据库故障转移到辅助数据库。这是 [AWS 多区域架构](https://aws.amazon.com/blogs/architecture/disaster-recovery-dr-architecture-on-aws-part-i-strategies-for-recovery-in-the-cloud/)中的一种常见场景。这种类型的故障转移需要一定的停机时间才能完成，无法立即恢复，并且会让工作负载在一段时间内没有冗余，因此需要让人参与决策过程。

 MTTRs通过使用多区域故障转移自动化来绕过故障，可以采用不太严格的一致性模型的工作负载可以缩短时间。[Amazon S3 跨区域复制](https://docs.aws.amazon.com/AmazonS3/latest/userguide/replication.html)或 [Amazon DynamoDB 全局表](https://aws.amazon.com/dynamodb/global-tables/)等功能可以通过最终一致性复制来实现多区域故障转移。此外，当我们考虑CAP定理时，使用宽松的一致性模型是有益的。当有状态子系统的连接性受到网络故障影响时，如果工作负载重视可用性而不是一致性，它仍然可以提供非错误响应，这是绕过故障的另一种方式。

 我们可以通过两种不同的策略来绕过故障。第一种策略是预先配置足够的资源来处理故障子系统的全部负载，从而实现静态稳定性。这可以是单个EC2实例，也可以是整个可用区的容量。在故障期间尝试配置新资源会增加恢复路径中的控制平面MTTR并增加对控制平面的依赖性。但是，预先配置资源需要额外付费。

 第二种策略是将部分流量从出现故障的子系统路由到其他子系统，并[卸除](https://aws.amazon.com/builders-library/using-load-shedding-to-avoid-overload)剩余容量无法处理的多余流量。在性能下降期间，您可以扩展新资源以替换出现故障的容量。这种方法的使用时间更长MTTR，会产生对控制平面的依赖，但待机、备用容量的成本更低。

## 恢复到已知良好状态
<a name="return-to-a-known-good-state"></a>

 修复期间的另一种常见缓解措施是将工作负载恢复到先前的已知良好状态。如果导致故障的可能是近期发生的更改，则我们可以回滚该更改以便恢复到先前状态。

 如果导致故障的可能是瞬时情况，那么重新启动工作负载可能会减轻影响。我们来分析一下这两种场景。

 在部署过程中，最小化MTTD并MTTR依赖于可观察性和自动化。您的部署过程必须持续监视工作负载，以防出现错误率增加、延迟增加或异常情况。发现这些问题后，部署过程应该暂停。

 我们可以采用多种[部署策略](https://docs.aws.amazon.com/whitepapers/latest/overview-deployment-options/deployment-strategies.html)，例如就地部署、蓝绿部署和滚动部署。每种策略都可以利用不同的机制来恢复到已知良好状态。系统可以自动回滚到先前状态、将流量转移回蓝色环境，或者要求手动干预。

 CloudFormation [提供了自动回滚的功能](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-rollback-triggers.html)，这是其创建和更新堆栈操作的一部分，也是如此[AWS CodeDeploy](https://docs.aws.amazon.com/codedeploy/latest/userguide/deployments-rollback-and-redeploy.html#deployments-rollback-and-redeploy-automatic-rollbacks)。 CodeDeploy 还支持蓝/绿和滚动部署。

 要利用这些功能并最大限度地减少您的能力MTTR，请考虑通过这些服务自动部署所有基础架构和代码。在无法使用这些服务的情况下，可以考虑使用实现[传奇模式](https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/implement-the-serverless-saga-pattern-by-using-aws-step-functions.html) AWS Step Functions 来回滚失败的部署。

 在考虑*重启*时，我们有很多不同的方法。我们可以重启服务器（用时最长），也可以重新启动线程（用时最短）。下表列出了一些重启方法和完成的大致时间（体现数量级差异，数字并不准确）。

 


|  故障恢复机制  |  估计 MTTR  | 
| --- | --- | 
|  启动和配置新虚拟服务器  |  15 分钟  | 
|  重新部署软件  |  10 分钟  | 
|  重启服务器  |  5 分钟  | 
|  重启或启动容器  |  2 秒  | 
|  调用新无服务器函数  |  100 毫秒  | 
|  重启进程  |  10 毫秒  | 
|  重启线程  |  10 微秒  | 

 查看该表，使用容器和无服务器函数（例如 [AWS Lambda](https://aws.amazon.com/lambda/)）有一些明显的好处。MTTR它们MTTR比重启虚拟机或启动新虚拟机快几个数量级。但是，通过软件模块化来实现故障隔离也有好处。如果能讲故障限制在单个进程或线程内，那么从故障中恢复的速度要比重启容器或服务器快得多。

 作为一般的恢复方法，您可以从下到上做出选择：1/重启、2/重新引导、3/重新创建映像/重新部署、4/替换。但是，进入重新引导步骤后，绕过故障通常是更快的方法（一般最多需要 3-4 分钟）。因此，为了在尝试重启后最快速地缓解影响，请绕过故障，然后在后台继续恢复过程以恢复工作负载的容量。

**规则 10**  
 侧重于缓解影响，而不是解决问题。以最快的速度恢复正常运行。

## 故障诊断
<a name="failure-diagnosis"></a>

 检测到故障之后，修复过程进入诊断阶段。这是操作人员试图确定问题所在的阶段。这一过程可能包括查询日志、查看运行状况指标或登录主机进行故障排除。所有这些操作都需要时间，因此创建工具和运行手册来加快这些操作MTTR也有助于减少。

## 运行手册和自动化
<a name="runbooks-and-automation"></a>

 同样，在确定了问题和修复措施之后，操作人员通常需要执行一些步骤来实现修复目的。例如，在发生故障后，修复工作负载的最快方法可能是重启工作负载，而这可能涉及多个有序的步骤。您可以使用运行手册来自动执行这些步骤或为操作人员提供具体指导，从而加快修复流程并降低执行出现操作的风险。

# 越来越多 MTBF
<a name="increasing-mtbf"></a>

 提高可用性的最后一个要素是提高MTBF. 这既适用于软件，也适用于用于运行该软件的 AWS 服务。

## 越来越多的分布式系统 MTBF
<a name="increasing-distributed-system-mtbf"></a>

 增加的一种方法MTBF是减少软件中的缺陷。我们可以通过多种方式来实现这一目的。客户可以使用诸如 [Amazon CodeGuru Reviewer](https://aws.amazon.com/codeguru/) 之类的工具来查找和修复常见错误。在将软件部署到生产环境之前，您还应该对软件进行全面的同行代码审查、单元测试、集成测试、回归测试和负载测试。增加测试中的代码覆盖率有助于确保即使是不常见的代码执行路径也能得到测试。

 部署较小规模的更改也可以降低更改的复杂性，从而帮助防止意外结果。每项活动都提供了在缺陷被调用之前识别和修复缺陷的机会。

 防止故障的另一种方法是[定期测试](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/test-reliability.html)。实施混沌工程可以帮助测试工作负载如何发生故障、验证恢复程序，并有助于在生产环境中出现故障之前发现和修复故障。客户可以将 [AWS Fault Injection Simulator](https://aws.amazon.com/fis/) 用作混沌工程实验工具。

 建立容错能力是防止分布式系统出现故障的另一种方法。快速失效模块、采用指数回退和抖动的重试、事务和幂等性都是可以帮助工作负载获得容错能力的技术。

 交易是一组符合ACID属性的操作。这些特性如下所示：
+  **原子性** — 所有操作要么全部发生，要么全部不发生。
+  **一致性** — 每个事务都让工作负载处于有效状态。
+  **隔离性** — 并发执行的事务会让工作负载处于相同状态，如同它们是按顺序执行的一样。
+  **持久性** — 事务提交之后，即使工作负载出现故障，其所有影响也会保持不变。

 采用[指数回退和抖动](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/)的重试可以克服由海森堡错误、过载或其他条件引起的暂时故障。当事务具有幂等性时，它们可以多次重试而不会产生副作用。

 对于海森堡错误对容错硬件配置的影响，我们可以将其完全忽略，因为海森堡错误同时出现在主子系统和冗余子系统上的可能性微乎其微。（参见 Jim Gray，“[Why Do Computers Stop and What Can Be Done About It?](https://pages.cs.wisc.edu/~remzi/Classes/739/Fall2018/Papers/gray85-easy.pdf)”，1985 年 6 月，Tandem 技术报告 85.7。） 在分布式系统中，我们希望通过软件实现同样的结果。

 出现海森堡错误时，软件必须快速检测到错误的操作并快速失效，以便可以重试。这通过防御性编程以及验证输入、中间结果和输出来实现。此外，进程是隔离的，不与其他进程共享任何状态。

 这种模块化方法可以确保故障的影响范围受到限制。进程会独立失效。当某个进程失效时，软件应该使用“进程对”来重试该工作，这意味着新进程可以承担失效进程的工作。为了保持工作负载的可靠性和完整性，应将每项操作视为一项ACID事务。

 这可以让进程的失效不会因为中止事务并回滚所做的任何更改而破坏工作负载的状态。这可以让恢复过程在已知良好状态下重试事务并正常重启。这就是软件容许海森堡错误的方式。

 但是，您的目标不应该是让软件能够容许海森堡错误。您必须在工作负载进入生产环境之前就发现并消除缺陷，因为任何程度的冗余都无法实现正确的结果。（参见 Jim Gray，“[Why Do Computers Stop and What Can Be Done About It?](https://www.hpl.hp.com/techreports/tandem/TR-85.7.pdf)”，1985 年 6 月，Tandem 技术报告 85.7。） 

 增加的最终方法MTBF是缩小失败的影响范围。正如前面的[容错能力和故障隔离](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/use-fault-isolation-to-protect-your-workload.html)部分所述，实现这一目标的主要方式是通过模块化来创建故障容器，从而实现*故障隔离*。降低故障率可以提高可用性。 AWS 使用诸如将服务划分为控制平面和数据平面、[可用区独立性](https://aws.amazon.com/builders-library/static-stability-using-availability-zones) (AZI)、[区域隔离](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/)、[基于单元的架构](https://www.youtube.com/watch?v=swQbA4zub20)和[洗牌分片等技术来提供故障隔离](https://aws.amazon.com/builders-library/workload-isolation-using-shuffle-sharding)。这些模式也可以由 AWS 客户使用。

 例如，假设工作负载将不同客户置于其基础架构的不同故障容器中，每个容器最多为 5% 的客户提供服务。其中一个故障容器中发生了一个事件，该事件让 10% 的请求延迟超过了客户端超时时间。在这次事件中，对于 95% 的客户来说，该服务具有 100% 的可用性。对于剩余 5% 的客户来说，该服务具有 90% 的可用性。这时的可用性为 1 − (5% *的**客户*******************×10% *的****************************请求*) = 99.5%，而不是 100% 的客户的 10% 的请求无效（可用性为 90%）。

**规则 11**  
故障隔离通过降低总体故障率来缩小影响范围并增加工作负载。MTBF

## 依赖性增加 MTBF
<a name="increasing-dependency-mtbf"></a>

 增加 AWS 依赖性的第一种方法MTBF是使用[故障隔离](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/use-fault-isolation-to-protect-your-workload.html)。许多 AWS 服务在可用区提供一定程度的隔离，这意味着一个可用区的故障不会影响另一个可用区的服务。

 在多个中使用冗余EC2实例可AZs提高子系统的可用性。AZI在单个区域内提供备用功能，允许您提高AZI服务的可用性。

 但是，并非所有 AWS 服务都在可用区级别运行。许多其他服务可以提供区域性隔离。在这种情况下，如果区域性服务的设计可用性无法实现您的工作负载所需的总体可用性，则您可以考虑采用多区域方法。每个区域都对服务进行隔离的实例化，相当于创建备件。

 有多种服务可以帮助简化多区域服务的构建。例如：
+  [Amazon Aurora 全球数据库](https://aws.amazon.com/rds/aurora/global-database/) 
+  [Amazon DynamoDB 全局表](https://aws.amazon.com/dynamodb/global-tables/) 
+  [亚马逊 ElastiCache (RedisOSS) — 全球数据存储](https://aws.amazon.com/elasticache/redis/global-datastore/) 
+  [AWS 全球加速器](https://aws.amazon.com/global-accelerator/) 
+  [Amazon S3 跨区域复制](https://docs.aws.amazon.com/AmazonS3/latest/userguide/replication.html) 
+  [Amazon Route 53 应用程序恢复控制器](https://aws.amazon.com/route53/application-recovery-controller/) 

 本文并未深入探讨构建多区域工作负载的策略，但您应该权衡多区域架构的可用性优势和实现所需可用性目标所需的额外成本、复杂性和运营实践。

 下一个增加依赖性的方法MTBF是将工作负载设计为静态稳定。例如，您有一个提供产品信息的工作负载。当客户针对产品发出请求时，您的服务会向外部元数据服务发出请求以检索产品详细信息。然后，您的工作负载会将所有这些信息返回给用户。

 但是，如果元数据服务不可用，您的客户发出的请求就会失败。因此，您可以将元数据异步拉取或推送到本地服务，用于回复请求。这样您就无需从关键路径同步调用元数据服务。

 此外，因为您的服务在元数据服务不可用时仍然保持可用，所以您可以在计算可用性时删除这个依赖项。本示例假设元数据不会经常更改，并且提供过时的元数据要好于请求失败。另一个类似的例子是 [serve-stale](https://www.rfc-editor.org/rfc/rfc8767)DNS，它允许在TTL过期后将数据保存在缓存中，并在刷新后的答案不容易获得时用于响应。

 增加依赖性的最后一种方法MTBF是缩小失败的影响范围。如上文所述，故障不是一个二元事件，存在着不同的程度。利用模块化设计，我们可以将故障限制在故障容器所服务的请求或用户范围内。

 这样可以减少事件期间的故障，从而通过限制影响范围来最终提高整个工作负载的可用性。

## 减少常见的影响源
<a name="reducing-common-sources-of-impact"></a>

 1985年，Jim Gray 在 Tandem Computers 的一项研究中发现，故障主要源自两种事物：软件和操作。（参见 Jim Gray，“[Why Do Computers Stop and What Can Be Done About It?](https://www.hpl.hp.com/techreports/tandem/TR-85.7.pdf)”，1985 年 6 月，Tandem 技术报告 85.7。） 即使在 36 年之后，情况仍然如此。尽管技术取得了进步，但这些问题并没有简单的解决方案，而且故障的主要原因也没有改变。本节开头探讨了如何解决软件故障，因此这里的重点将放在操作和降低故障频率上。

### 稳定性与功能的比较
<a name="stability-compared-with-features"></a>

 如果再看一次 [分布式系统可用性](distributed-system-availability.md) 部分的软件与硬件故障率图表，我们可以发现软件的每个版本都会引入缺陷。这意味着工作负载的任何变化都会提高故障风险。这些变化通常是新功能之类的东西，会带来必然的结果。可用性更高的工作负载会更重视稳定性而不是新功能。因此，提高可用性的一种最简单的方法，就是降低部署频率或减少提供的功能。部署频率更高的工作负载的可用性天然低于比不频繁部署的工作负载。但是，不添加新功能的工作负载无法满足客户需求，并且作用会随着时间的推移而降低。

 那么，我们如何继续创新并安全地发布新功能呢？ 答案是标准化。正确的部署方式是什么？ 如何确定部署顺序？ 测试标准是什么？ 不同阶段之间要等待多长时间？ 单元测试是否涵盖了足够的软件代码？ 标准化可以回答这些问题，并防止由于未进行负载测试、跳过部署阶段或过快地部署到太多主机等而引发问题。

 实现标准化的方法是推行自动化。自动化可以减少人为错误，让计算机处理其擅长的任务，即以同样的方式反复执行同样的操作。将标准化与自动化结合的方法是设定目标。目标包括不进行手动更改、仅通过临时授权系统访问主机、为每个API系统编写负载测试等。卓越运营是一种文化规范，可能需要进行重大变革。根据目标来确定和跟踪效果有助于推动文化变革，这将对工作负载的可用性产生广泛影响。[AWS Well-Architected 卓越运营支柱](https://docs.aws.amazon.com/wellarchitected/latest/operational-excellence-pillar/welcome.html)针对卓越运营供了全面的最佳实践。

### 操作人员安全
<a name="operator-safety"></a>

 导致故障的运营事件的另一个主要引发因素是人。人会犯错误。他们可能会使用错误的凭证、输入错误的命令、过早按回车键，或者错过关键步骤。始终采取手动操作会导致错误，从而引发故障。

 造成操作人员错误的一项主要原因是用户界面混乱、不直观或不一致。Jim Gray 在 1985 年的研究中还指出，“要求操作人员提供信息或执行某些功能的界面必须简单、一致并能容许操作人员错误。” （参见 Jim Gray，“[Why Do Computers Stop and What Can Be Done About It?](https://www.hpl.hp.com/techreports/tandem/TR-85.7.pdf)”，1985 年 6 月，Tandem 技术报告 85.7。） 这一见解在今天仍然是正确的。在过去的三十年中，整个行业中有许多例子表明，混乱或复杂的用户界面、缺乏确认或说明，甚至只是不友好的人类语言就导致操作人员犯下了错误。

**规则 12**  
让操作员可以轻松采取正确操作。

### 防止过载
<a name="preventing-overload"></a>

 最后一个常见影响来源是您的客户，即工作负载的实际用户。成功的工作负载往往会被大量使用，但有时这种使用量会超出工作负载的扩展能力。可能出现的情况有很多，比如磁盘已满、线程池耗尽、网络带宽饱和，或者达到数据库连接限制。

 没有万无一失的方法可以消除这些故障，但是通过运行状况指标对容量和使用情况进行主动监控，我们就能在可能发生这些故障时提前收到警告。[卸除负载](https://aws.amazon.com/builders-library/using-load-shedding-to-avoid-overload)、[断路器](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/design-interactions-in-a-distributed-system-to-mitigate-or-withstand-failures.html)以及[采用指数回退和抖动的重试](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/)等技术可以帮助我们尽可能减少影响并提高成功率，但这些都是发生故障之后采取的措施。基于运行状况指标的自动扩展可以帮助降低过载导致的故障的发生频率，但可能无法足够快地响应使用率的变化。

 如果您需要确保客户具有持续可用的容量，则必须在可用性和成本之间做出权衡。要确保容量不足不会导致不可用，您可以为每位客户提供配额并确保扩展工作负载的容量，以便提供 100% 的分配配额。当客户超过配额时，他们会受到限制，这不是故障，也不会影响可用性的计算。您还需要密切跟踪您的客户群并预测未来的使用情况，以便预置足够的容量。这样可以确保您的工作负载不会因为客户过度使用而产生故障。
+  [Amazon Builders' Library – 通过卸除负载来避免过载](https://aws.amazon.com/builders-library/using-load-shedding-to-avoid-overload/) 
+  [Amazon Builders' Library – Fairness in multi-tenant systems](https://aws.amazon.com/builders-library/fairness-in-multi-tenant-systems) 

我们来看一个提供存储服务的工作负载。工作负载中的每台服务器可以支持每秒 100 次下载，为客户提供每秒 200 次下载的配额，共有 500 个客户。要支持这一数量的客户，该服务需要提供每秒 10 万次的下载容量，这需要 1000 台服务器。如果任何客户超出其配额，他们就会受到限制，这可以确保其他所有客户都有足够的容量。这是一个简单的示例，说明了一种在不拒绝工作单元的情况下避免过载的方法。