You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AWS CDK/CloudFormation中实现ECS基于表达式的指标自动扩缩容?

实现ECS服务基于指标表达式的目标扩缩容

不用依赖自定义Lambda就能搞定,AWS CDK和CloudFormation都原生支持这个配置——只是官方文档的示例大多聚焦单指标场景,容易忽略Metric Expression的配置方式。

AWS CDK 实现示例(TypeScript)

在CDK中,你可以通过ApplicationAutoScaling.TargetTrackingScalingPolicy的customizedMetricSpecification属性直接配置指标表达式。比如下面的例子是计算「SQS队列待处理消息数/ECS当前运行任务数」作为扩缩容依据:

import * as cdk from 'aws-cdk-lib';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as appscaling from 'aws-cdk-lib/aws-applicationautoscaling';
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';

const stack = new cdk.Stack(app, 'EcsScalingStack');

// 导入已有的ECS集群与服务
const ecsCluster = ecs.Cluster.fromClusterArn(stack, 'ExistingCluster', 'arn:aws:ecs:region:account-id:cluster/your-cluster');
const ecsService = ecs.EcsService.fromEcsServiceArn(stack, 'ExistingService', 'arn:aws:ecs:region:account-id:service/your-cluster/your-service');

// 创建扩缩容目标
const scalingTarget = ecsService.autoScaleTaskCount({
  minCapacity: 2,
  maxCapacity: 10,
});

// 基于指标表达式的目标追踪策略
scalingTarget.scaleToTrackCustomMetric('QueuePerTaskScaling', {
  targetValue: 5, // 目标值:每个任务对应5条待处理消息
  customizedMetricSpecification: {
    metricName: 'QueueMessagesPerTask',
    namespace: 'CustomMetrics',
    dimensionsMap: {},
    statistic: 'Average',
    unit: cloudwatch.Unit.NONE,
    // 核心配置:指标表达式
    metricExpression: {
      expression: 'm1/m2',
      label: 'QueueMessagesPerTask',
      returnData: true,
      metrics: [
        {
          id: 'm1',
          metricStat: {
            metric: cloudwatch.Metric.fromMetricName({
              namespace: 'AWS/SQS',
              metricName: 'ApproximateNumberOfMessagesVisible',
              dimensionsMap: { QueueName: 'your-queue' },
            }),
            period: cdk.Duration.minutes(1),
            stat: 'Average',
          },
          returnData: false,
        },
        {
          id: 'm2',
          metricStat: {
            metric: cloudwatch.Metric.fromMetricName({
              namespace: 'AWS/ECS',
              metricName: 'RunningTasksCount',
              dimensionsMap: {
                ClusterName: ecsCluster.clusterName,
                ServiceName: ecsService.serviceName,
              },
            }),
            period: cdk.Duration.minutes(1),
            stat: 'Average',
          },
          returnData: false,
        },
      ],
    },
  },
});

CloudFormation 模板实现示例(YAML)

直接在AWS::ApplicationAutoScaling::ScalingPolicy的TargetTrackingScalingPolicyConfiguration中定义CustomizedMetricSpecification,并包含MetricExpression字段即可:

Resources:
  ECSScalingTarget:
    Type: AWS::ApplicationAutoScaling::ScalingTarget
    Properties:
      MaxCapacity: 10
      MinCapacity: 2
      ResourceId: !Join ['/', [service, !Ref ECSClusterName, !Ref ECSServiceName]]
      ScalableDimension: ecs:service:DesiredCount
      ServiceNamespace: ecs
      RoleARN: !GetAtt ECSScalingRole.Arn

  ECSScalingPolicy:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    Properties:
      PolicyName: QueuePerTaskScalingPolicy
      PolicyType: TargetTrackingScaling
      ScalingTargetId: !Ref ECSScalingTarget
      TargetTrackingScalingPolicyConfiguration:
        TargetValue: 5
        CustomizedMetricSpecification:
          MetricName: QueueMessagesPerTask
          Namespace: CustomMetrics
          Statistic: Average
          Unit: None
          MetricExpression:
            Expression: m1/m2
            Label: QueueMessagesPerTask
            ReturnData: true
            Metrics:
              - Id: m1
                MetricStat:
                  Metric:
                    Dimensions:
                      - Name: QueueName
                        Value: your-queue
                    MetricName: ApproximateNumberOfMessagesVisible
                    Namespace: AWS/SQS
                  Period: 60
                  Stat: Average
                ReturnData: false
              - Id: m2
                MetricStat:
                  Metric:
                    Dimensions:
                      - Name: ClusterName
                        Value: !Ref ECSClusterName
                      - Name: ServiceName
                        Value: !Ref ECSServiceName
                    MetricName: RunningTasksCount
                    Namespace: AWS/ECS
                  Period: 60
                  Stat: Average
                ReturnData: false

  ECSScalingRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: application-autoscaling.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: ECSAutoScalingPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - cloudwatch:GetMetricStatistics
                  - cloudwatch:ListMetrics
                  - ecs:DescribeServices
                  - ecs:UpdateService
                Resource: '*'

注意事项

  • 指标表达式需符合CloudWatch语法规则,确保表达式中的指标ID与引用对应
  • 需为AutoScaling角色配置读取CloudWatch指标、更新ECS服务的权限
  • 根据业务场景调整Period(统计周期)和Statistic(统计方式)参数
  • 目标值的设置要贴合实际业务负载,避免过度扩缩容

内容的提问来源于stack exchange,提问作者sachi1325

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 08:46:32