根据 Amazon SQS 进行扩展 - Amazon EC2 Auto Scaling
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

根据 Amazon SQS 进行扩展

重要

以下信息和步骤向您展示了在将队列属性作为自定义指标发布到之前,如何使用队列属性计算每个实例的 Amazon SQS ApproximateNumberOfMessages 队列待办事项。 CloudWatch但是,您现在可以使用指标数学来节省发布自己的指标所花费的成本和精力。有关更多信息,请参见 使用指标数学为 Amazon EC2 Auto Scaling 创建目标跟踪扩展策略

本节介绍如何扩展 Auto Scaling 组以响应 Amazon Simple Queue Service (Amazon SQS) 队列中系统负载的变化。要了解有关如何使用 Amazon SQS 的更多信息,请参阅 Amazon 简单队列服务开发人员指南

在一些情况下,您可能会考虑根据 Amazon SQS 队列中的活动扩展。例如,假设您有 Web 应用程序,让用户上传图像并联机使用。在此场景中,每个图像需要先调整大小并编码,然后才能发布。该应用程序在 Auto Scaling 组中的 EC2 实例上运行,配置为处理您的典型上传速率。不正常的实例将终止并进行替换,以始终保持当前的实例等级。该应用程序将图像的原始位图数据放在 SQS 队列中以进行处理。它处理这些图像,然后将处理的图像发布到某个位置以供用户查看。如果上传的图像数不随时间波动,则适用于此场景的架构可以良好运作。但是,如果上传数量随着时间波动,您可以考虑使用动态扩展来缩放 Auto Scaling 组的容量。

将目标跟踪与合适的指标结合使用

如果您使用基于自定义 Amazon SQS 队列指标的目标跟踪扩展策略,则动态扩展可以更有效地适应应用程序的需求曲线。有关为目标跟踪选择指标的更多信息,请参阅 选择指标

使用诸如目标跟踪之类的 A CloudWatch mazon SQS 指标的问题在ApproximateNumberOfMessagesVisible于,队列中的消息数量可能不会与处理队列消息的 Auto Scaling 组的大小成比例变化。这是因为 SQS 队列中的消息数不仅仅定义所需的实例数。Auto Scaling 组中的实例数可能由多种因素决定,包括处理消息所需的时间以及可接受的延迟长度(队列延迟)。

该解决方案使用要维护的每个实例的积压 指标以及每个实例的可接受积压 的目标值。您可以按以下所示计算这些数字:

  • 每个实例的积压:要计算您每个实例的积压,首先通过 ApproximateNumberOfMessages 度列属性确定 SQS 队列的长度(可从队列中检索的消息数)。将该数字除以队列的运行容量(对于 Auto Scaling 组,这是处于 InService 状态的实例数量),以获得每个实例的积压。

  • 每个实例的可接受积压:要计算您的目标值,请先确定您的应用程序可以接受的延迟。然后,将可接受的延迟值除以 EC2 实例处理一条消息所用的平均时间。

例如,假设您当前有一个包含 10 个实例的自动扩缩组,并且队列中的可见消息数量(ApproximateNumberOfMessages)是 1500。如果每条消息的平均处理时间为 0.1 秒,最长可接受延迟为 10 秒,则每个实例的可接受积压为 10/0.1,即 100 条消息。这意味着您的目标跟踪策略的目标值为 100。当每个实例的积压达到目标值时,将发生横向扩展事件。由于每个实例已经积压了 150 条消息(10 个实例 1500 条消息),该组会横向扩展并增加了 5 个实例以维持与目标值的比例。

以下过程演示如何发布自定义指标和创建目标跟踪扩展策略,以根据这些计算值来配置您的 Auto Scaling 组进行扩展。

重要

请记住,为了降低成本,请改用指标数学。有关更多信息,请参见 使用指标数学为 Amazon EC2 Auto Scaling 创建目标跟踪扩展策略

此配置有三个主要部分:

  • 一个 Auto Scaling 组,用于管理处理来自 SQS 队列的消息的 EC2 实例。

  • 发送 CloudWatch 到 Amazon 的自定义指标,用于衡量 Auto Scaling 组中每个 EC2 实例在队列中的消息数量。

  • 一种目标跟踪策略,用于将 Auto Scaling 组配置为根据自定义指标和设定的目标值进行扩展。 CloudWatch 警报会调用扩展策略。

下图演示了此配置的架构。


                        Amazon EC2 Auto Scaling 使用队列架构图

限制和先决条件

要使用此配置,您需要注意以下限制:

  • 您必须使用Amazon CLI或 SDK 将您的自定义指标发布到 CloudWatch。然后,您可以使用 Amazon Web Services Management Console 监控指标。

  • Amazon EC2 Auto Scaling 控制台不支持使用自定义指标的目标跟踪扩缩策略。您必须使用 Amazon CLI 或者使用开发工具包为您的扩展策略指定自定义指标。

以下各节指示您为需要执行的任务使用 Amazon CLI。例如,要获取反映队列当前使用情况的指标数据,可以使用 SQS get-queue-attributes命令。确保您已经安装并配置 CLI。

开始之前,您必须有一个要使用的 Amazon SQS 队列。以下部分假设您已经有一个队列(标准队列或 FIFO 队列)、一个 Auto Scaling 组以及 EC2 实例(运行使用队列的应用程序)。有关 Amazon SQS 权限的更多信息,请参阅 Amazon 简单队列服务开发人员指南

配置基于 Amazon SQS 的缩放

步骤 1:创建 CloudWatch 自定义指标

自定义指标是使用您选择的指标名称和命名空间定义的。自定义指标的命名空间不能以 AWS/ 开头。有关发布自定义指标的更多信息,请参阅 Amazon CloudWatch 用户指南中的发布自定义指标主题。

按照此过程,通过首先从您的 Amazon 账户读取信息来创建自定义指标。然后,计算前面的章节中建议的每个实例的积压指标。最后,以 1 分钟为间 CloudWatch 隔发布此数字。只要可能,我们强烈建议您按 1 分钟粒度的指标进行扩展,以确保更快地响应系统负载变化。

创建 CloudWatch 自定义指标 (Amazon CLI)
  1. 使用 SQS get-queue-attributes 命令获取在队列中等待的消息数 (ApproximateNumberOfMessages):

    aws sqs get-queue-attributes --queue-url https://sqs.region.amazonaws.com/123456789/MyQueue \ --attribute-names ApproximateNumberOfMessages
  2. 使用 describe-auto-scaling-groups 命令获取组的运行容量,这是处于 InService 生命周期状态的实例数。此命令返回 Auto Scaling 组的实例及其生命周期状态。

    aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names my-asg
  3. 将该队列中可供检索的大致消息数量除以该组的运行容量,计算得出每个实例的积压。

  4. 创建每分钟运行一次的脚本,以检索每个实例的待办事项值并将其发布到 CloudWatch 自定义指标。发布自定义指标时,需要指定该指标的名称、命名空间、单位、值以及零个或多个维度。维度由维度名称和维度值组成。

    要发布自定义指标,请将斜体占位符值替换为首选指标名称、指标值、命名空间(只要不是以 AWS “” 开头)和维度(可选),然后运行以下put-metric-data命令。

    aws cloudwatch put-metric-data --metric-name MyBacklogPerInstance --namespace MyNamespace \ --unit None --value 20 --dimensions MyOptionalMetricDimensionName=MyOptionalMetricDimensionValue

应用程序发出所需的指标之后,数据发送到 CloudWatch。该指标在 CloudWatch 控制台中可见。您可以通过登录Amazon Web Services Management Console并导航到该 CloudWatch 页面来访问它。然后,通过导航到指标页面或者使用搜索框搜索指标来查看指标。有关查看指标的信息,请参阅 Amazon CloudWatch 用户指南中的查看可用指标

步骤 2:创建目标跟踪扩展策略

现在,您可以将创建的指标添加到目标跟踪扩缩策略中。

创建目标跟踪扩缩策略(Amazon CLI)
  1. 使用以下cat命令可以在您的主目录的名为config.json的 JSON 文件中存储扩缩策略的目标值和自定义指标规范。将每个用户输入占位符替换为您自己的信息。对于 TargetValue,计算每个实例的可接受积压指标并在此处输入。要计算此数值,请考虑正常延迟值并将其除以处理一条消息所需的平均时间(如前面的章节所述)。

    如果您没有为步骤 1 中创建的指标指定任何维度,请不要在自定义指标规范中包含任何维度。

    $ cat ~/config.json { "TargetValue":100, "CustomizedMetricSpecification":{ "MetricName":"MyBacklogPerInstance", "Namespace":"MyNamespace", "Dimensions":[ { "Name":"MyOptionalMetricDimensionName", "Value":"MyOptionalMetricDimensionValue" } ], "Statistic":"Average", "Unit":"None" } }
  2. 使用 put-scaling-policy 命令以及在前面的步骤中创建的 config.json 文件创建扩展策略。

    aws autoscaling put-scaling-policy --policy-name sqs100-target-tracking-scaling-policy \ --auto-scaling-group-name my-asg --policy-type TargetTrackingScaling \ --target-tracking-configuration file://~/config.json

    这会创建两个警报:一个用于增加实例数量,另一个用于减少实例数量。它还会返回向其注册的策略的 Amazon 资源名称 (ARN) CloudWatch,该名称 CloudWatch 用于在指标阈值被违反时调用缩放。

步骤 3:测试扩展策略

在您完成设置后,验证您的扩展策略是否正常工作。您可以通过以下方式测试:增加 SQS 队列中的消息数,然后验证 Auto Scaling 组是否已启动更多 EC2 实例。您还可以通过以下方式测试:减少 SQS 队列中的消息数,然后验证 Auto Scaling 组是否终止了一个 EC2 实例。

测试扩展函数
  1. 按照将消息发送到一个队列(控制台)中的步骤,将消息添加到队列。请确保您增加了队列中的消息数量,使得每个实例的积压指标超过目标值。

    您的更改调用警报可能需要几分钟时间。

  2. 使用 describe-auto-scaling-groups 命令确认该组已启动一个实例。

    aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name my-asg
测试缩减函数
  1. 按照接收和删除消息(控制台)中的步骤从队列中删除消息。请确保您减少了队列中的消息数量,使得每个实例的积压指标低于目标值。

    您的更改调用警报可能需要几分钟时间。

  2. 使用 describe-auto-scaling-groups 命令确认该组已终止一个实例。

    aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name my-asg

Amazon SQS 和实例缩减保护

实例被终止时还未处理的消息将返回 SQS 队列中,可由仍在运行的实例进行处理。对于执行长时间运行任务的应用程序,您可以选择使用实例扩展保护来控制 Auto Scaling 组扩展时终止哪些队列工作程序。

以下伪代码显示了保护长时间运行、队列驱动的工件进程免受缩放终止的一种方法。

while (true) { SetInstanceProtection(False); Work = GetNextWorkUnit(); SetInstanceProtection(True); ProcessWorkUnit(Work); SetInstanceProtection(False); }

有关更多信息,请参见 在 Amazon EC2 Auto Scaling 上设计您的应用程序,以便正常地处理实例终止问题