云上计算资源(EC2/ECS)Auto Scaling弹性伸缩策略配置实战

本文从运维实际痛点出发,系统梳理AWS EC2 Auto Scaling与ECS Auto Scaling的策略配置方法、常见陷阱与验证手段。涵盖启动模板、目标追踪策略、复合指标配置、冷却时间调优及回滚方案,帮助团队避免因扩容不及时或缩容过度导致的线上问题。

云上计算资源(EC2/ECS)Auto Scaling弹性伸缩策略配置实战
封面图:ZuCDN · ZuCDN 原创

在云上架构中,Auto Scaling是应对流量波动最直接的防御手段。但许多团队在配置后仍出现“扩容慢、缩容猛”的尴尬局面——明明触发了告警,实例却迟迟未加入服务;流量回落时,又因缩容策略过于激进导致剩余实例过载。这些问题的根源往往不在工具本身,而在策略参数的设计与验证环节。本文聚焦EC2 Auto Scaling与ECS Auto Scaling的实际配置细节,不讨论基础概念,直接切入可执行的规则与验证点。

EC2 Auto Scaling与ECS Auto Scaling的核心差异

两种服务虽然名字相近,但调度基础完全不同。EC2 Auto Scaling管理的是底层虚拟机实例,而ECS Auto Scaling管理的是任务(Task)或者服务级别的副本数。理解这一点是策略设计的前提。

EC2 Auto Scaling:面向实例级扩缩

当配置EC2 Auto Scaling时,你需要定义启动模板(Launch Template)、伸缩组(Auto Scaling Group)以及伸缩策略。实例创建后,通常由负载均衡器接管流量。常见问题是:刚创建的实例尚未完成初始化(如安装软件、挂载数据卷),就已经被后端服务发现,导致请求超时。解决方案是结合生命周期挂钩(Lifecycle Hook)与自定义脚本,等待实例就绪后再加入目标组。

ECS Auto Scaling:面向容器级扩缩

ECS Auto Scaling基于服务自动缩放(Service Auto Scaling),直接控制任务数量。你不需要关注底层实例是否启动(除非使用Fargate),但必须直面CPU、内存等容器级指标。一个容易被忽略的陷阱:ECS服务使用了容量提供者(Capacity Provider)时,自动缩放策略若未与底层EC2 Auto Scaling联动,可能出现“容器想扩但主机无资源”的情况。此时需要配置集群自动缩放(Cluster Auto Scaling)来补充实例。

启动模板/任务定义中的容易踩的坑

不少人把启动模板或任务定义当作一次性的配置,但它们的细节直接决定了扩容后的行为是否正常。

EC2启动模板:用户数据与实例元数据

启动模板中的用户数据(User Data)是按需扩展实例的初始化脚本。常见错误是依赖网络下载外部包,但未考虑脚本执行时间。例如,一个需要下载2GB数据集的初始化过程可能耗时5分钟,而默认的健康检查超时只有2分钟。正确的做法是在用户数据中增加信号通知,配合生命周期挂钩,让伸缩组等到实例健康检查通过后再注册到负载均衡。

  • 风险点:未设置shutdown behavior导致缩容时实例终止不干净
  • 验证方法:手动从伸缩组创建实例,检查/var/log/cloud-init-output.log

ECS任务定义:资源预留与端口冲突

每个任务定义中声明的CPU和内存数值会影响调度。如果数值过小,容器会被打满;如果过大,调度器可能找不到合适的主机。另外,使用动态端口映射时,若服务使用了awsvpc网络模式,需确保安全组允许从负载均衡到临时端口的流量。否则扩容后容器启动但无法被访问。

  • 经验值:CPU预留值建议设置为任务实际使用的90%,保留一定余量但不浪费
  • 验证方法:在ECS集群中运行一个偏离实例,检查服务是否健康

伸缩策略类型与真实适用场景

AWS提供了三种原生策略:简单缩放、步进缩放、目标追踪。但很多人直接套用模板导致配置偏离。

目标追踪策略:最适合稳定的Web服务

目标追踪(Target Tracking)自动根据聚合指标调节容量,类似于自托管HPA。它简单有效,但有两个限制:
– 只能使用预定义指标(如CPU、内存、请求数)或自定义指标,不能直接定义多个指标复合
– 默认的冷却时间较短,在指标快速抖动时可能造成频繁缩放

在实际配置中,建议将目标值设为预留了缓冲的数值。例如,CPU目标值设为60%,而不是75%。这样当突发流量到来时,实例可以提前启动,而不是等到CPU冲到80%才动作。

步进缩放策略:应对未知模式

当负载特征不规则(如每日固定时间突发、偶尔尖刺),步进缩放(Step Scaling)更可控。你需要定义多个告警阈值和对应的调整幅度。例如:CPU > 70% 增加2台,CPU > 85% 增加5台。步进策略配合冷却时间(Cooldown)参数至关重要——冷却时间内策略不会重复触发,防止扩容后又马上扩容。但冷却时间过长会导致扩容延迟,建议设置为60-120秒。

简单缩放策略:已被步进取代

简单缩放(Simple Scaling)只能做一次固定调整,且没有冷却控制,容易造成震荡。除非是极简单的场景(如测试环境),否则不建议使用。

多指标复合与冷却时间的协同

许多服务需要同时监控CPU、请求数和队列深度。单个目标追踪策略无法满足,你需要多个独立策略同时运行。但多个策略可能互相干扰:一个策略扩容,另一个策略认为当前容量已足够而缩容。解决思路是设置不同的降温时间,扩容策略的冷却时间短,缩容策略的冷却时间长——通常缩容冷却时间设为扩容的3倍。此外,可以借助AWS无服务器应用模型中的自定义CFN宏来实现加权决策,但更常见的做法是使用CloudWatch复合告警。

CloudWatch复合告警示例

定义一个复合告警:当CPU > 70% 请求数 > 5000时触发扩容。这可以避免CPU因非业务原因偏高(如后台批处理)造成无效扩容。复合告警的缺点是延迟增加(需要等子告警状态稳定),通常延迟在1-2分钟之内,对于大多数Web应用是可接受的。

验证方法与常见问题排查

策略配置完成后,必须进行非生产验证,否则上线后出问题很难定位。

手动触发扩容验证

最简单的方法是手动调用AWS CLI修改伸缩组所需容量:aws autoscaling set-desired-capacity --auto-scaling-group-name my-asg --desired-capacity 3 --honor-cooldown。观察实例是否按预期注册到目标组,并查看CloudWatch指标中的GroupInServiceInstances。如果实例长时间处于Pending,检查生命周期挂钩或用户数据脚本。

压力测试缩容

使用工具如ab、wrk或locust制造流量尖刺,观察扩容触发时间。记录GroupTotalCapacityALBRequestCountPerTarget的变化曲线。特别注意流量下降后的缩容行为:如果实例被迅速终止,但已有请求尚未处理完毕,可能导致500错误。此时应考虑启用缩容保护(Instance Protection)或延长冷却时间。

ECS特定问题:服务无法再平衡

ECS服务在缩容时默认会先终止较老的任务,但若任务中有未完成的事务,则需配置任务终止策略(drain)。在服务定义中设置deploymentCircuitBreaker回滚配置,避免连续失败导致服务离线。

回滚方案与安全建议

没有完美的策略,必须有回滚的退路。以下是在生产环境实施Auto Scaling时推荐的安全机制。

缩回手动模式

在CloudFormation或Terraform部署的伸缩组中,保留一个手动调整容量的运维脚本。当自动策略误触发导致实例异常增加时,管理员可以快速将伸缩组的最小值和最大值恢复到保守值。这个操作比禁用伸缩策略更可靠,因为禁用策略后,现有实例不会被删除,但自动更换实例的能力也消失了。

使用AZ感知与平衡

配置伸缩组时应启用跨可用区分布。如果某个AZ出现故障,自动缩放会尝试在其他AZ补充。但在多AZ环境下,缩容策略可能倾向于清除故障AZ的实例,但健康实例尚未准备好接手全部流量,此时可能触发连锁反应。建议缩容冷却时间至少是扩容冷却时间的2倍,且缩容时保持每个AZ至少有一台健康实例。

监控关键指标并设置告警

除了CPU和内存,还应监控GroupPendingInstancesGroupStandbyInstances。如果Pending数量持续超过阈值,说明扩容链路存在问题。设置一个告警当Pending实例数超过5且持续时间>2分钟时,通知值班人员介入检查启动模板或负载均衡器状态。

弹性伸缩不是“一配了事”的开关,而是需要持续根据业务周期调整参数。每两到三个月审视一次策略的目标值、冷却时间和告警阈值,配合压测验证,才能让自动缩放真正成为业务稳定的护盾,而非事故的放大器。

延伸阅读