

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

# 多可用区可观测性
<a name="multi-az-observability"></a>

 为了能够在单个可用区发生隔离事件期间撤出可用区，首先您必须能够检测到故障已实际上隔离到单个可用区。这要求对系统在每个可用区中的行为具备高可见性。许多 AWS 服务提供的 out-of-the-box 指标可以提供有关您的资源的运营见解。例如，Amazon EC2 提供了许多指标，例如CPU利用率、磁盘读取和写入以及网络流入和流出的流量。

 但是，随着您使用这些服务构建工作负载，需要了解的指标就不仅仅是这些标准指标了。您希望了解您的工作负载为客户提供了何种体验。此外，您的指标需要与生成这些指标的可用区保持一致。只有获得这些见解，您才能够检测到各种不同可见度的灰色故障。为此，您需要进行分析；

 要进行分析，就需要编写显式代码。该代码应该执行各种工作，例如记录任务花费了多长时间、对成功或失败的项目计数、收集有关请求的元数据等等。您还需要提前定义阈值，以定义哪些是正常情况以及哪些是异常情况。您应该针对工作负载中的延迟、可用性和错误计数制定目标并规定不同严重程度阈值。Amazon Builders’ Library 的文章[分析分布式系统来获得操作可视性](https://aws.amazon.com/builders-library/instrumenting-distributed-systems-for-operational-visibility/)提供了许多最佳实操。

 指标既应从服务器端生成，也应从客户端生成。生成客户端指标和了解客户体验的最佳实操是使用[金丝雀](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries.html)，该软件可以定期探测您的工作负载和记录指标。

 除了生成这些指标外，您还需要了解其上下文。执行此操作的一种方法是使用[维度](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#Dimension)。维度为指标提供了唯一的身份，并有助于您了解这些指标传达的信息。对于那些用于识别工作负载中故障的指标（例如，延迟、可用性或错误数），您需要使用与[故障隔离边界](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/use-fault-isolation-to-protect-your-workload.html)一致的维度。

 例如，如果您使用 [M odel-view-controller](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (MVC) Web 框架在一个区域、多个可用区中运行 Web 服务，则应使用`Region`、[https://docs.aws.amazon.com/ram/latest/userguide/working-with-az-ids.html](https://docs.aws.amazon.com/ram/latest/userguide/working-with-az-ids.html)、`Controller``Action`、和`InstanceId`作为维度集的维度（如果您使用的是微服务，则可以使用服务名称和HTTP方法而不是控制器和操作名称）。这样做，是因为您希望使用这些边界隔离不同类型的故障，而不希望 Web 服务代码中本来只会影响产品展列的错误对主页产生影响。同样，您也不会指望单个EC2实例的EBS容量已满会影响其他EC2实例提供您的 Web 内容。可用区 ID 维度使您可以通过一致的方式确定可用区在不同 AWS 账户中的影响。您可以通过多种不同的方式在工作负载中找到可用区 ID。请参阅[附录 A – 获取可用区 ID](appendix-a-getting-the-availability-zone-id.md)，了解一些示例。

 虽然本文档在示例中主要使用亚马逊EC2作为计算资源，但`InstanceId`可以用亚马逊弹性容器[服务 (亚马逊ECS) 的容器 ID 和亚马逊弹性](https://aws.amazon.com/ecs/) [Kubernetes Ser](https://aws.amazon.com/eks/) vice (A EKS mazon) 计算资源作为维度的组成部分。

 如果您的工作负载有区域端点，则您的金丝雀还可以在其指标中使用 `Controller`、`Action`、`AZ-ID` 和 `Region` 维度。如果这样，请调整您的金丝雀，使其在其测试的可用区中运行。这样可以确保，如果金丝雀正在测试的某个可用区受到隔离的可用区事件的影响，金丝雀记录的指标不会因此使其测试的其他可用区看起来有异常。例如，您的金丝雀可以使用其区域名称测试网络负载均衡器 (NLB) 或 Application Load Balancer (ALB) 后面的服务的每个[区域DNS](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#dns-name)终端节点。

![该图显示了在 Sy CloudWatch nthetics 上运行的金丝雀或测试每个区域端点的 AWS Lambda 函数 NLB](http://docs.aws.amazon.com/zh_cn/whitepapers/latest/advanced-multi-az-resilience-patterns/images/canary-testing-for-zonal-impact.png)


 通过生成具有这些维度的指标，您可以建立 [Amazon CloudWatch 警报](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)，当可用性或延迟发生变化时，这些警报会通知您。您也可以使用[控制面板](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Dashboards.html)快速分析这些数据。为了高效使用指标和日志，Amazon CloudWatch 提供了[嵌入式指标格式](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format.html) (EMF)，使您能够在日志数据中嵌入自定义指标。 CloudWatch自动提取自定义指标，以便您可以对其进行可视化并发出警报。 AWS 为不同的编程语言提供了多个[客户端库](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Libraries.html)，便于入门EMF。它们可以与亚马逊EC2、亚马逊ECSEKS[AWS Lambda](https://aws.amazon.com/lambda/)、亚马逊和本地环境一起使用。通过将指标嵌入到日志中，您还可以使用 [Amazon CloudWatch 贡献者见解](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContributorInsights.html)来创建显示贡献者数据的时间序列图表。这样，我们就可以显示按维度（如 `AZ-ID`、`InstanceId` 或 `Controller`）和日志中的任何其他字段（如 `SuccessLatency` 或 `HttpResponseCode`）分组的数据。

```
{ 
  "_aws": { 
    "Timestamp": 1634319245221, 
    "CloudWatchMetrics": [ 
      { 
        "Namespace": "workloadname/frontend", 
        "Metrics": [ 
          { "Name": "2xx", "Unit": "Count" }, 
          { "Name": "3xx", "Unit": "Count" }, 
          { "Name": "4xx", "Unit": "Count" }, 
          { "Name": "5xx", "Unit": "Count" }, 
          { "Name": "SuccessLatency", "Unit": "Milliseconds" } 
        ], 
        "Dimensions": [ 
          [ "Controller", "Action", "Region", "AZ-ID", "InstanceId"], 
          [ "Controller", "Action", "Region", "AZ-ID"], 
          [ "Controller", "Action", "Region"] 
        ] 
      }
    ], 
    "LogGroupName": "/loggroupname" 
  }, 
  "CacheRefresh": false, 
  "Host": "use1-az2-name.example.com", 
  "SourceIp": "34.230.82.196", 
  "TraceId": "|e3628548-42e164ee4d1379bf.", 
  "Path": "/home", 
  "OneBox": false, 
  "Controller": "Home", 
  "Action": "Index", 
  "Region": "us-east-1", 
  "AZ-ID": "use1-az2", 
  "InstanceId": "i-01ab0b7241214d494", 
  "LogGroupName": "/loggroupname", 
  "HttpResponseCode": 200,
  "2xx": 1, 
  "3xx": 0, 
  "4xx": 0, 
  "5xx": 0, 
  "SuccessLatency": 20 
}
```

此日志有三组维度。这三个维度按粒度排序，从实例到可用区再到区域（`Controller` 和 `Action` 始终包含在本示例中）。借助它们，您可以在您的工作负载中创建警报，以指示单个实例、单个可用区或整个 AWS 区域内的特定控制器操作何时受到影响。这些维度用于计算 2xx、3xx、4xx 和 5xx HTTP 响应指标的计数，以及成功请求指标的延迟（如果请求失败，它还将记录失败的请求延迟指标）。该日志还记录其他信息，例如HTTP路径、请求者的源 IP 以及此请求是否需要刷新本地缓存。然后，这些数据点可用于计算每个API工作负载提供的可用性和延迟。

**关于为可用性指标使用HTTP响应代码的说明**  
通常，您可以将 2xx 和 3xx 响应视为成功，将 5xx 视为失败。4xx 响应代码介于二者之间，通常是由于客户端错误而生成的。[400 响应](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes)可能是参数超出范围所致，也可能是所请求内容不存在造成的。您不会将这些响应计入工作负载的可用性范畴，但是，它也可能是软件错误造成的。  
例如，如果您引入了更严格的输入验证，拒绝了之前本来可以成功的请求，那么 400 响应可能视作可用性下降。或者，也许是您在限制客户，因此返回 429 响应。虽然限制客户可以保护您的服务，使其维持可用性，但从客户的角度来看，则是您的服务未能处理他们的请求。您需要决定是否将 4xx 响应代码是纳入可用性计算中。

虽然本节概述了使用 CloudWatch 作为收集和分析指标的方法，但这并不是您可以使用的唯一解决方案。您也可以选择将指标发送到 Amazon Managed Service for Prometheus 和 Amazon Managed Grafana（一种 Amazon DynamoDB 表），还可以使用第三方监控解决方案。关键在于，您的工作负载生成的指标必须包含有关工作负载故障隔离边界的上下文。

借助所生成指标的维度与故障隔离边界一致的工作负载，您可以实现检测可用区隔离故障的可观测性。以下部分介绍了三种用于检测因单个可用区受损而导致故障的补充方法。

**Topics**
+ [使用 CloudWatch 复合警报进行故障检测](failure-detection-with-cloudwatch-composite-alarms.md)
+ [使用异常值检测进行故障检测](failure-detection-using-outlier-detection.md)
+ [对单实例区域资源进行故障检测](failure-detection-of-single-instance-zonal-resources.md)
+ [Summary](summary.md)