

# Amazon ECS 部署断路器如何检测故障
<a name="deployment-circuit-breaker"></a>

部署断路器是一种滚动更新机制，可确定任务是否达到稳定状态。部署断路器有一个选项，该选项可自动将失败的部署回滚到处于 `COMPLETED` 状态的部署。您可以自定义断路器计算失败次数的方法及其触发的阈值，以便回滚行为与应用程序的启动特征和对任务失败的容忍度相匹配。

当服务部署更改状态时，Amazon ECS 会向 EventBridge 发送服务部署状态更改事件。这提供了一种用于监控服务部署状态的编程方式。有关更多信息，请参阅 [Amazon ECS 服务部署状态更改事件](ecs_service_deployment_events.md)。建议您使用 `SERVICE_DEPLOYMENT_FAILED` 的 `eventName` 创建和监控 EventBridge 规则，以便您可以采取手动操作开始您的部署。有关更多信息，请参阅《Amazon EventBridge 用户指南》**中的 [Getting started with EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-get-started.html)。

当部署断路器确定部署失败时，它会查找处于 `COMPLETED` 状态的最新部署。这是其用作回滚部署的部署。当回滚开始时，部署将从 `COMPLETED` 更改为 `IN_PROGRESS`。这意味着在达到 `COMPLETED` 状态之前，该部署不能进行其他回滚。当部署断路器找不到处于 `COMPLETED` 状态的部署时，断路器不会启动新任务，部署将停止。

创建服务时，调度器会跟踪分两个阶段启动失败的任务。
+ 第 1 阶段：调度器监控任务以查看它们是否过渡到“正在运行”状态。
  + 成功：部署有可能过渡到“已完成”状态，因为有不止一项任务已过渡到“正在运行”状态。跳过故障标准，断路器进入第 2 阶段。
  + 失败 - 默认情况下，未转换到 RUNNING 状态的连续任务计入失败阈值（`resetOnHealthyTask` 是 `true`）。如果 `resetOnHealthyTask` 是 `false`，则无论运行正常的任务是否在各失败之间开始，所有任务失败都会累积。
+ 第 2 阶段：当至少有一个任务处于“正在运行”状态时，部署进入此阶段。断路器对正在评估的当前部署中的任务进行运行状况检查。经过验证的运行状况检查包括 Elastic Load Balancing、AWS Cloud Map 服务运行状况检查和容器运行状况检查。
  + 成功：至少有一个任务处于运行状态且运行状况检查已通过。
  + 失败：由于运行状况检查失败而被替换的任务已达到失败阈值。

对服务使用部署断路器方法时，请注意以下事项。EventBridge 生成规则。
+ `DescribeServices` 响应提供了对部署状态、`rolloutState` 和 `rolloutStateReason` 的深入了解。启动新部署时，部署状态将在 `IN_PROGRESS` 状态开始。当服务达到稳定状态时，部署状态将转换为`COMPLETED`。如果服务未能达到稳定状态并打开了断路器，则部署将转换为 `FAILED` 状态。`FAILED` 状态中的部署不会启动任何新任务。
+ 除了 Amazon ECS 为已启动和已完成的部署发送的服务部署状态更改事件外，Amazon ECS 还将在启用断路器的部署失败时发送事件。这些事件提供了有关部署失败的原因或部署是否由于回滚而启动的详细信息。有关更多信息，请参阅 [Amazon ECS 服务部署状态更改事件](ecs_service_deployment_events.md)。
+ 如果由于以前的部署失败并出现了回滚而启动了新部署，则服务部署状态更改事件的 `reason` 字段将指示部署是由于回滚而启动的。
+ 部署断路器仅支持使用滚动更新（`ECS`）部署控制器的 Amazon ECS 服务。
+ 您必须使用 Amazon ECS 控制台，或者在使用带有 CloudWatch 选项的部署断路器时必须使用 AWS CLI。这种方法的示例是，如果有关更多信息，请参阅**《AWS Command Line Interface 参考》中的 [使用定义的参数创建服务](create-service-console-v2.md#create-custom-service) 和 [create-service](https://docs.aws.amazon.com/cli/latest/reference/ecs/create-service.html)。

以下 `create-service` AWS CLI 示例显示如何在将部署断路器和回滚选项结合使用时创建 Linux 服务。

```
aws ecs create-service \
     --service-name {{MyService}} \
     --deployment-controller type={{ECS}} \
     --desired-count {{3}} \
     --deployment-configuration "deploymentCircuitBreaker={enable={{true}},rollback={{true}}}" \
     --task-definition {{sample-fargate:1}} \
     --launch-type {{FARGATE}} \
     --platform-family {{LINUX}} \
     --platform-version {{1.4.0}} \
     --network-configuration "awsvpcConfiguration={subnets=[{{subnet-12344321}}],securityGroups=[{{sg-12344321}}],assignPublicIp={{ENABLED}}}"
```

以下 `create-service` AWS CLI 示例说明如何使用自定义部署断路器配置创建服务，该配置使用固定故障计数 5 和累积失败跟踪。

```
aws ecs create-service \
     --service-name {{MyService}} \
     --deployment-controller type={{ECS}} \
     --desired-count {{10}} \
     --deployment-configuration "deploymentCircuitBreaker={enable={{true}},rollback={{true}},resetOnHealthyTask={{false}},thresholdConfiguration={type={{COUNT}},value={{5}}}}" \
     --task-definition {{sample-fargate:1}} \
     --launch-type {{FARGATE}} \
     --platform-family {{LINUX}} \
     --platform-version {{1.4.0}} \
     --network-configuration "awsvpcConfiguration={subnets=[{{subnet-12344321}}],securityGroups=[{{sg-12344321}}],assignPublicIp={{ENABLED}}}"
```

示例：

部署 1 处于 `COMPLETED` 状态。

部署 2 无法启动，所以断路器会回滚到部署 1。部署 1 会过渡到 `IN_PROGRESS` 状态。

部署 3 启动，但没有处于 `COMPLETED` 状态的部署，因此部署 3 无法回滚或启动任务。

## Failure threshold
<a name="failure-threshold"></a>

部署断路器使用失败阈值来确定何时将部署移动到 `FAILED` 状态。您可以配置失败计数方式和阈值本身。

### 失败计数模式
<a name="failure-counting-mode"></a>

`resetOnHealthyTask` 设置控制断路器如何计算部署期间的任务失败次数。

`true`（默认）  
每当任务达到正常状态时，失败计数都会重置为 0。只有连续的失败才计入阈值。此模式对于可能经过数次间歇性启动失败之后才会稳定的应用程序很有用。

`false`  
任务失败次数会在整个部署过程中累计。即使运行正常的任务在两次失败之间启动，失败计数也从不重置。当任何失败模式都表明部署存在问题时，此模式方便更快地进行检测。

### 阈值配置
<a name="threshold-configuration"></a>

`thresholdConfiguration` 设置定义了断路器何时触发。它包含 `type`，用于确定如何计算阈值，并且包含 `value`，用于指定要使用的百分比或计数。

`BOUNDED_PERCENT`（默认）  
Amazon ECS 将 `value` 乘以最新服务预期数量来计算失败阈值。此结果钳制在最小值 3 和最大值 200 之间。这是默认类型，默认值为 50。

`UNBOUNDED_PERCENT`  
Amazon ECS 将 `value` 乘以最新服务预期数量来计算失败阈值。结果没有最小值或最大值限制。对于预期数量较大、需要比例阈值但没有 200 上限的服务，请使用此类型。

`COUNT`  
Amazon ECS 直接将 `value` 用作失败阈值。无论服务预期数量如何，阈值都保持不变。如果您想要确切次数的容忍失败，例如，为了在开发环境中更快地回滚而设定较低的阈值，请使用此类型。

对于百分比类型（`BOUNDED_PERCENT` 和 `UNBOUNDED_PERCENT`），`value` 的有效范围为 1-100。在部署期间，Amazon ECS 在其计算中会持续使用最新服务预期数量。

### `BOUNDED_PERCENT` 如何计算阈值
<a name="bounded-percent-calculation"></a>

使用默认 `BOUNDED_PERCENT` 阈值类型时，部署断路器使用以下公式计算阈值。

```
Minimum threshold (3) <= ({{value}}/100) * {{desired task count}} => Maximum threshold (200)
```

当计算结果小于 3 时，阈值设置为 3。当结果大于 200 时，预置设置为 200。否则，阈值将设置为计算值（向上舍入）。

下表提供了使用默认值 50 的示例。


| 预期任务计数 | 计算 | Threshold | 
| --- | --- | --- | 
| 1 |  <pre>3 <= 0.5 * 1 => 200</pre>  | 3（计算值低于最低值） | 
| 25 |  <pre>3 <= 0.5 * 25 => 200</pre>  | 13（此值将向上舍入） | 
| 400 |  <pre>3 <= 0.5 * 400 => 200</pre>  | 200（计算值大于最高值） | 
| 800 |  <pre>3 <= 0.5 * 800 => 200</pre>  | 200（计算值大于最高值） | 

对于 `UNBOUNDED_PERCENT`，适用相同的计算，但没有最小值和最大值限制。例如，预期数量为 800、值为 50 的服务的阈值为 400。

部署状态检查分两个阶段。

1. 部署断路器监控部署中的任务并检查处于 `RUNNING` 状态的任务。调度器在当前部署中的任务位于 `RUNNING` 状态并进入下一阶段时忽略失败条件。当任务无法到达 `RUNNING` 状态时，部署断路器将失败次数增加 1。当故障计数等于阈值时，部署将标记为 `FAILED`。

1. 当有一个或多个任务处于 `RUNNING` 状态时，进入此阶段。部署断路器对当前部署中的任务的以下资源执行运行状况检查：
   + Elastic Load Balancing 负载均衡器
   + AWS Cloud Map 服务
   + Amazon ECS 容器运行状况检查

   当任务的运行状况检查失败时，部署断路器会将失败计数增加 1。当故障计数等于阈值时，部署将标记为 `FAILED`。

例如，当阈值为 3 时，断路器在故障计数设置为 0 的情况下启动。当任务无法到达 `RUNNING` 状态时，部署断路器将失败计数增加 1。当故障计数等于 3 时，部署将标记为 `FAILED`。

有关如何使用回滚选项的其他示例，请参阅 [Announcing Amazon ECS deployment circuit breaker](https://aws.amazon.com/blogs/containers/announcing-amazon-ecs-deployment-circuit-breaker/)（宣布推出 Amazon ECS 部署断路器）。