

# 保护您的 Amazon ECS 任务不被横向缩减事件终止
<a name="task-scale-in-protection"></a>

您可以使用 Amazon ECS 任务缩容保护来保护任务，防止任务因服务自动扩缩或部署导致的横向缩减事件而终止。

某些应用程序需要一种机制来保护任务关键型任务不会在利用率低的时段或服务部署期间因横向缩减事件而终止。例如：
+ 您有一个队列处理异步应用程序，例如视频转码任务，即使累积服务利用率很低，其中某些任务也需要运行数小时。
+ 您的游戏应用程序将游戏服务器作为 Amazon ECS 任务运行，即使所有用户都已注销，该任务也需要继续运行，以减少服务器重启的启动延迟。
+ 部署新的代码版本时，需要任务才能继续运行，因为重新处理会很昂贵。

若要防止属于您的服务的任务在横向缩减事件中终止，请将该 `ProtectionEnabled` 属性设置为 `true`。如果将 `ProtectionEnabled` 设置为 true，则默认情况下任务的保护期为 2 小时。然后您可以使用 `ExpiresInMinutes` 属性来自定义保护期限。您可以保护您的任务最少 1 分钟，最多 2880 分钟（48 小时）。如果您使用的是 AWS CLI，则可以指定 `--protection-enabled` 选项。

任务完成其必要工作后，您可以将该 `ProtectionEnabled` 属性设置为 `false`，从而允许任务因随后的横向缩减事件而终止。如果您使用的是 AWS CLI，则可以指定 `--no-protection-enabled` 选项。

## 任务缩容保护机制
<a name="task-scale-in-protection-mechanisms"></a>

您可以使用 Amazon ECS 容器代理端点或 Amazon ECS API 设置和获取任务缩容保护。
+ **Amazon ECS 容器代理端点**

  对于那些可以自行确定是否需要保护的任务，我们建议使用 Amazon ECS 容器代理端点。将此方法用于基于队列或任务处理的工作负载。

  当容器开始处理工作时（例如，通过使用 SQS 消息），您可以通过容器内的任务缩容保护端点路径 `$ECS_AGENT_URI/task-protection/v1/state` 设置 `ProtectionEnabled` 属性。在横向缩减事件期间，Amazon ECS 不会终止此任务。当您的任务完成它的工作后，您可以使用相同的端点清除 `ProtectionEnabled` 属性，从而使任务有资格在随后的横向缩减事件期间终止。

  有关 Amazon ECS 容器代理端点的更多信息，请参阅[Amazon ECS 任务缩容保护端点](task-scale-in-protection-endpoint.md)。
+ **Amazon ECS API**

  如果您的应用程序具有跟踪活动任务状态的组件，则可以使用 Amazon ECS API 来设置和检索任务缩容保护。使用 `UpdateTaskProtection` 将一个或多个任务标记为受保护。使用 `GetTaskProtection` 检索保护状态。

  这种方法的示例是，如果您的应用程序将游戏服务器会话作为 Amazon ECS 任务托管。当用户登录到服务器上的会话（任务）时，您可以将该任务标记为受保护。用户注销后，您可以清除专门针对此任务的保护，也可以定期清除对不再处于活动会话状态的类似任务的保护，具体取决于您保留空闲服务器的要求。

  有关更多信息，请参阅《Amazon Elastic Container Service API 参考》**中的 [UpdateTaskProtection](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_UpdateTaskProtection.html) 和 [GetTaskProtection](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_GetTaskProtection.html)。

您可以将这两种方法结合起来。例如，使用 Amazon ECS 代理端点从容器内设置任务保护，并使用 Amazon ECS API 移除对外部控制器服务的任务保护。

## 注意事项
<a name="task-scale-in-protection-considerations"></a>

在使用任务缩容保护之前，请注意以下几点：
+ 只有通过服务部署的任务才支持任务缩容保护。
+ 对于从 Amazon ECS 托管实例上运行的服务部署的任务，支持任务缩容保护。
+ 建议使用 Amazon ECS 容器代理端点，因为 Amazon ECS 代理具有内置的重试机制和更简单的接口。
+ 您可以通过在已开启保护的任务上调用 `UpdateTaskProtection` 来重置任务缩容保护到期时间。
+ 确定任务需要多长时间才能完成其必要工作，并相应地设置 `expiresInMinutes` 属性。如果您设置的保护到期时间超过必要的时间，则将产生成本，并在部署新任务时面临延迟。
+ Amazon ECS 容器代理 `1.65.0` 或更高版本支持任务缩容保护。通过将代理更新为最新版本，您可以使用较旧版本的 Amazon ECS 容器代理在 Amazon EC2 实例上添加对此功能的支持。有关更多信息，请参阅 [更新 Amazon ECS 容器代理](ecs-agent-update.md)。
+ 部署注意事项：
  + 如果服务使用滚动更新，则将创建新任务，但运行旧版本的任务要等到 `protectionEnabled` 清除或过期后才会终止。您可以将部署配置中的 `maximumPercentage` 参数调整为允许在保护旧任务时创建新任务的值。
  + 如果应用了蓝绿更新，则包含受保护任务的蓝色部署不会被移除（如果任务有 `protectionEnabled`）。流量将转移到即将出现的新任务，而较旧的任务只有在 `protectionEnabled` 被清除或过期时才会被删除。根据 CodeDeploy 或 CloudFormation 更新的超时时间，部署可能会超时，较旧的蓝色任务可能仍然存在。
  + 如果您使用 CloudFormation，则更新堆栈有 3 小时的超时时间。因此，如果您将任务保护设置为 3 小时以上，则您的 CloudFormation 部署可能会导致故障和回滚。

    在您的旧任务受到保护期间，CloudFormation 堆栈会显示 `UPDATE_IN_PROGRESS`。如果任务缩容保护被移除或在 3 小时内过期，则您的部署将成功并变为 `UPDATE_COMPLETE` 状态。如果部署在 `UPDATE_IN_PROGRESS` 状态停滞超过 3 个小时，将会失败并显示 `UPDATE_FAILED` 状态，然后将回滚到旧任务集。
  + 如果受保护的任务使部署（滚动或蓝绿）无法达到稳定状态，Amazon ECS 将发送服务事件，以便您可以采取补救措施。在尝试更新任务的保护状态时，如果您收到 `DEPLOYMENT_BLOCKED` 错误消息，则表示该服务的受保护任务数量超过了该服务所需的任务数。要纠正这个错误，可以执行下列操作：
    + 等待当前的任务保护过期。然后设置任务保护。
    + 确定哪些任务可以停止。然后，对这些任务使用 `UpdateTaskProtection` 并将 `protectionEnabled` 选项设置为 `false`。
    + 增加服务的所需任务计数，以大于受保护任务的数量。

## 任务缩容保护所需的 IAM 权限
<a name="task-scale-in-protection-iam"></a>

该任务必须拥有具有以下权限的 Amazon ECS 任务角色：
+ `ecs:GetTaskProtection`：允许 Amazon ECS 容器代理调用 `GetTaskProtection`。
+ `ecs:UpdateTaskProtection`：允许 Amazon ECS 容器代理调用 `UpdateTaskProtection`。