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

如何在ECS集群内存不足时通过AWS CloudFormation实现实例自动扩缩容

具备内存驱动自动扩缩容的ECS服务&任务CloudFormation模板

我最近写了个CloudFormation模板,能一站式创建ECS任务定义、服务,还自带基于*内存使用率(MemoryUtilization)*的自动扩缩容功能——简单说就是当任务的内存使用率触发设定阈值时自动加1个任务,使用率降下来就减1个,省得手动调整资源。

先给大家看看核心的任务定义部分:

EcsTd:
  Type: AWS::ECS::TaskDefinition
  DependsOn: LogGroup
  Properties:
    Family: !Sub ${EnvironmentName}-${PlatformName}-${Type}
    ContainerDefinitions:
      - Name: !Sub ${EnvironmentName}-${PlatformName}-${Type}
        Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/your-repo:your-tag
        # 可根据业务需求补充容器配置:资源限制、端口映射、环境变量等
        MemoryReservation: 512 # 示例内存预留值,按需调整
        LogConfiguration:
          LogDriver: awslogs
          Options:
            awslogs-group: !Ref LogGroup
            awslogs-region: !Ref AWS::Region
            awslogs-stream-prefix: ecs

任务定义关键细节说明

  • 命名规范:任务家族(Family)和容器名称都用EnvironmentName、PlatformName、Type三个参数拼接,不管是测试还是生产环境,都能轻松区分不同ECS任务,排查问题更高效
  • 依赖控制:通过DependsOn确保日志组(LogGroup)先创建完成,避免容器启动时因找不到日志组报错
  • 日志关联:绑定到指定CloudWatch Log Group,方便后续查看容器日志、配置监控告警

自动扩缩容核心配置

要实现内存驱动的扩缩容,还得配上ECS服务的自动扩缩容目标和策略,这是模板里的核心逻辑:

# ECS服务自动扩缩容目标
EcsServiceScalingTarget:
  Type: AWS::ApplicationAutoScaling::ScalableTarget
  DependsOn: EcsService
  Properties:
    MaxCapacity: 10 # 最大任务数,按需调整
    MinCapacity: 1 # 最小任务数
    ResourceId: !Sub service/${EcsCluster}/${EcsService.Name}
    ScalableDimension: ecs:service:DesiredCount
    ServiceNamespace: ecs

# 内存使用率过高时的扩容策略
EcsServiceScaleOutPolicy:
  Type: AWS::ApplicationAutoScaling::ScalingPolicy
  Properties:
    PolicyName: !Sub ${EnvironmentName}-${PlatformName}-scale-out
    PolicyType: StepScaling
    ScalingTargetId: !Ref EcsServiceScalingTarget
    StepScalingPolicyConfiguration:
      AdjustmentType: ChangeInCapacity
      Cooldown: 60 # 冷却时间,避免频繁扩缩容
      MetricAggregationType: Average
      StepAdjustments:
        - MetricIntervalLowerBound: 0
          ScalingAdjustment: 1 # 内存使用率达标时,增加1个任务

# 内存使用率过低时的缩容策略
EcsServiceScaleInPolicy:
  Type: AWS::ApplicationAutoScaling::ScalingPolicy
  Properties:
    PolicyName: !Sub ${EnvironmentName}-${PlatformName}-scale-in
    PolicyType: StepScaling
    ScalingTargetId: !Ref EcsServiceScalingTarget
    StepScalingPolicyConfiguration:
      AdjustmentType: ChangeInCapacity
      Cooldown: 60
      MetricAggregationType: Average
      StepAdjustments:
        - MetricIntervalUpperBound: 0
          ScalingAdjustment: -1 # 内存使用率低于阈值时,减少1个任务

# 内存使用率告警规则(触发扩容)
MemoryHighAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    AlarmName: !Sub ${EnvironmentName}-${PlatformName}-memory-high
    AlarmDescription: Trigger scale out when MemoryUtilization exceeds threshold
    Namespace: AWS/ECS
    MetricName: MemoryUtilization
    Dimensions:
      - Name: ClusterName
        Value: !Ref EcsCluster
      - Name: ServiceName
        Value: !Ref EcsService.Name
    Statistic: Average
    Period: 60
    EvaluationPeriods: 2
    Threshold: 70 # 内存使用率阈值,示例为超过70%触发扩容
    ComparisonOperator: GreaterThanThreshold
    AlarmActions:
      - !Ref EcsServiceScaleOutPolicy

# 内存使用率告警规则(触发缩容)
MemoryLowAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    AlarmName: !Sub ${EnvironmentName}-${PlatformName}-memory-low
    AlarmDescription: Trigger scale in when MemoryUtilization is below threshold
    Namespace: AWS/ECS
    MetricName: MemoryUtilization
    Dimensions:
      - Name: ClusterName
        Value: !Ref EcsCluster
      - Name: ServiceName
        Value: !Ref EcsService.Name
    Statistic: Average
    Period: 60
    EvaluationPeriods: 2
    Threshold: 30 # 内存使用率阈值,示例为低于30%触发缩容
    ComparisonOperator: LessThanThreshold
    AlarmActions:
      - !Ref EcsServiceScaleInPolicy

扩缩容逻辑说明

  • 当ECS任务的平均内存使用率连续2分钟超过70%时,CloudWatch告警会触发扩容策略,自动增加1个任务
  • 当平均内存使用率连续2分钟低于30%时,触发缩容策略,减少1个任务
  • 冷却时间设为60秒,防止短时间内频繁调整任务数量,避免资源不必要的波动

内容的提问来源于stack exchange,提问作者Kārlis Janisels

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:04:30