在 Amazon EC2 Auto Scaling 上设计您的应用程序,以便正常地处理实例终止问题 - Amazon EC2 Auto Scaling
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

在 Amazon EC2 Auto Scaling 上设计您的应用程序,以便正常地处理实例终止问题

本主题涵盖了当 Amazon EC2 Auto Scaling 响应横向缩减事件时,正在运行实例的应用程序在理想状态下不应意外终止的情况下您可以采用的不同方法。

例如,假设您有一个 Amazon SQS 队列,用于收集长时间运行的任务的传入消息。当新消息到达时,自动扩缩组中的一个实例会检索该消息并开始对其进行处理。处理每个消息需要 3 小时。随着消息数量的增加,新的实例会自动添加到自动扩缩组中。随着消息数量的减少,现有实例会自动终止。在此情况下,Amazon EC2 Auto Scaling 必须决定终止哪个实例。默认情况下,Amazon EC2 Auto Scaling 可能会终止那个对长达 3 小时的任务已经处理了 2.9 小时的实例,而不是终止当前处于空闲状态的实例。为了避免在使用 Amazon EC2 Auto Scaling 时出现意外终止问题,您的应用程序设计必须能应对这种情况。

您可以使用以下功能来防止自动扩缩组终止那些尚未准备好终止的实例,或者防止过快地终止实例以至于它们无法完成分配的任务。这三个功能可以组合使用,也可以单独使用。

重要

在 Amazon EC2 Auto Scaling 上设计应用程序以正常地处理实例终止时,请务必牢记这些要点。

  • 如果一个实例运行状况不佳,无论您使用哪个功能,Amazon EC2 Auto Scaling 都将替换该实例(除非您暂停 ReplaceUnhealthy 流程)。您可以使用生命周期挂钩来允许应用程序正常关闭,或者在实例终止之前复制需要恢复的任何数据。

  • 无法保证终止生命周期挂钩是否会在实例终止之前运行或完成。如果出现故障,Amazon EC2 Auto Scaling 仍会终止该实例。

横向缩减保护实例

在许多情况下,您可以使用实例横向缩减保护,此时的终止实例是一项关键操作,默认应拒绝该操作,并且仅明确允许供指定实例使用。例如,在运行容器化工作负载时,通常希望保护所有实例,仅对没有当前任务或计划任务的实例取消保护。诸如 Amazon ECS 之类的服务已在其产品中内置集成了实例横向缩减保护。

您可以在自动扩缩组上启用横向缩减保护,以便在创建实例时对其应用横向缩减保护,并对现有实例启用横向缩减保护。当实例没有更多作业要做时,它可以关闭保护。该实例可以继续轮询新作业,并在分配了新作业时重新启用保护。

应用程序可以从用于管理实例是否可终止的集中控制面板设置保护,也可以从实例本身设置保护。但是,如果大量实例不断切换横向缩减保护,那么大的实例集可能会遇到节流问题。

有关更多信息,请参阅 实例横向缩减保护

自定义终止策略

与实例横向缩减保护一样,自定义终止策略可帮助您防止自动扩缩组终止指定的实例。

默认情况下,自动扩缩组使用默认终止策略来确定首先终止哪个实例。如果您想更好地控制首先终止哪些实例,则可以使用 Lambda 函数实现您自己的自定义终止策略。每当 Amazon EC2 Auto Scaling 必须决定要终止哪个实例时,它都会调用该函数。它只会终止该函数返回的实例。如果函数出错、超时或生成空列表,则 Amazon EC2 Auto Scaling 不会终止实例。

如果知道某个实例何时足够冗余或利用率不足,因此可以终止该实例,那么自定义终止策略会非常有用。为了支持这一观点,您需要使用控制面板来实现应用程序,由该平面监控整个组的工作负载。这样,如果一个实例仍在处理作业,那么 Lambda 函数就会知道不将它包含在内。

有关更多信息,请参阅 了解使用 Lambda 创建自定义终止策略。

终止生命周期挂钩

终止生命周期挂钩可延长已选择终止的实例的使用寿命。它提供了额外的时间来完成当前分配给实例的所有消息或请求,或者保存进度并将工作转移给另一个实例。

对于许多工作负载,生命周期挂钩可能足以正常地关闭运行着已选择终止的实例的应用程序。这是一种尽最大努力的方法,不能用于在出现故障时防止终止。

要使用生命周期挂钩,您需要知道何时选择终止实例。有两种方法可以知道这一点:

选项 描述 最适合用于 指向文档的链接
在实例之内 实例元数据服务 (IMDS) 是一个安全端点,您可以通过它来直接从实例中轮询实例的状态。如果元数据随之返回 Terminated,则您的实例将按计划终止。 在实例终止之前必须对实例执行操作的应用程序。 检索目标生命周期状态
在实例之外 当实例终止时,会生成事件通知。您可以使用亚马逊 EventBridge、亚马逊 SQS 或 Amazon SNS 创建规则来捕获这些事件,并调用响应,例如使用 Lambda 函数。 需要在实例之外进行操作的应用程序。 创建通知目标

要使用生命周期挂钩,您还需要知道您的实例何时准备好完全被终止。Amazon EC2 Auto Scaling 不会告诉 Amazon EC2 在收到CompleteLifecycle操作调用或超时过后(以先发生者为准)之前终止该实例。

默认情况下,由于终止生命周期挂钩的存在,实例可以继续运行一小时(检测信号超时)。如果一小时的时间不足以完成生命周期操作,则可以配置默认超时。当生命周期操作实际正在进行时,您可以通过 RecordLifecycleActionHeartbeatAPI 调用延长超时时间。

有关更多信息,请参阅 Amazon EC2 Auto Scaling 生命周期钩子