4. 伸缩策略(上):基于CPU/内存利用率的动态伸缩策略配置
动态伸缩这事儿,说白了就是让云平台自己判断“该加机器了”或者“该减机器了”。
我个人习惯把这种策略叫做“自动挡”。你设定好规则,剩下的交给云平台。但很多同学上来就踩坑——规则设得太敏感,结果半夜三点给你弹出来20台机器,第二天一看账单直接傻眼。
4.1 核心指标:CPU和内存,到底看哪个?
CPU利用率和内存利用率,是最常用的两个指标。但你不能无脑选。
| 指标 | 适用场景 | 典型阈值 | 注意事项 |
|---|---|---|---|
| CPU利用率 | 计算密集型应用(如视频转码、科学计算) | 扩容:70%~80% 缩容:20%~30% |
注意CPU Burst场景,短时尖峰可能误触发 |
| 内存利用率 | 内存密集型应用(如缓存、大数据处理) | 扩容:75%~85% 缩容:30%~40% |
内存泄漏会导致持续扩容,需配合健康检查 |
| 两者组合 | 通用型应用(如Web服务、API网关) | 任一指标超过阈值即扩容 | 避免“与”逻辑,否则扩容响应太慢 |
我的经验: 对于大多数Web应用,我建议优先看CPU。内存利用率往往有滞后性——等你看到内存飙高时,其实GC已经频繁触发,应用性能早就下降了。
4.2 冷却时间:别让系统“抽风”
冷却时间(Cooldown Period)是动态伸缩里最容易忽略的参数。
举个例子:你的扩容阈值设的是CPU > 75%。某次流量突增,CPU冲到80%,触发扩容。新机器启动需要2分钟。在这2分钟里,CPU可能因为负载分摊降到了60%。但如果没有冷却时间,系统会立刻判定“CPU低于75%了,缩容吧”——结果刚缩完,流量又来了,CPU再次飙升,又扩容……
这就叫“震荡”。
我曾经踩过的坑: 给一个电商平台配伸缩策略,冷却时间设了30秒。结果双十一大促时,系统在10分钟内反复扩缩了15次,产生了大量“僵尸实例”的启动和销毁费用。后来我把冷却时间改到120秒,问题才解决。
一般建议:
- 扩容冷却时间: 60~180秒(取决于实例启动速度)
- 缩容冷却时间: 120~300秒(缩容要更保守)
4.3 阈值设置:别太死板
阈值不是拍脑袋定的。我见过有人直接设“CPU > 50%就扩容”,结果集群规模翻了一倍,利用率反而更低——因为每台机器都在空转。
正确的做法是:
- 先压测: 用工具(如wrk、ab、JMeter)模拟真实流量,找到应用的性能拐点。
- 留余量: 阈值不要设到极限。比如压测发现CPU到85%时响应时间开始恶化,那扩容阈值就设在70%。
- 分时段: 白天和晚上的阈值可以不同。白天流量大,阈值可以设低一点;晚上流量小,阈值可以设高一点。
核心原则: 扩容要快,缩容要慢。宁可多跑几台机器,也别让用户感受到延迟。
4.4 配置示例:AWS Auto Scaling + 阿里云ESS
不同云厂商的配置大同小异。我拿两个主流平台举例。
4.4.1 AWS Auto Scaling(CPU策略)
# 创建伸缩策略(AWS CLI)
aws autoscaling put-scaling-policy \
--auto-scaling-group-name my-asg \
--policy-name cpu-scale-out \
--scaling-adjustment 2 \
--adjustment-type ChangeInCapacity \
--cooldown 120
# 创建CloudWatch告警
aws cloudwatch put-metric-alarm \
--alarm-name cpu-high-alarm \
--metric-name CPUUtilization \
--namespace AWS/EC2 \
--statistic Average \
--period 60 \
--evaluation-periods 2 \
--threshold 75 \
--comparison-operator GreaterThanThreshold \
--alarm-actions arn:aws:autoscaling:...:policy/cpu-scale-out
这里有个细节:evaluation-periods 2 表示连续2个周期(共120秒)都超过阈值才触发。这能过滤掉短时尖峰。
4.4.2 阿里云ESS(内存策略)
# 创建伸缩规则(阿里云CLI)
aliyun ess CreateScalingRule \
--ScalingGroupId asg-xxxx \
--ScalingRuleName mem-scale-out \
--ScalingRuleType SimpleScalingRule \
--AdjustmentType QuantityChangeInCapacity \
--AdjustmentValue 1 \
--Cooldown 180
# 创建云监控报警
aliyun cms PutMetricRule \
--RuleName mem-high-rule \
--Namespace acs_ecs_dashboard \
--MetricName memory_usedutilization \
--Period 60 \
--Statistics Average \
--Threshold 80 \
--ComparisonOperator GreaterThanThreshold \
--EvaluationCount 3 \
--ContactGroups my-group
你想想看,为什么阿里云这里我用了EvaluationCount 3?因为内存变化比CPU慢,多等一个周期更稳妥。
4.5 核心逻辑:一张图看懂
下面这张图,是我自己总结的动态伸缩决策流程。你照着这个思路配策略,基本不会出大问题。
4.6 避坑指南:我踩过的几个雷
- 不要用单一数据点: 我曾经只采1分钟的数据,结果某次GC暂停导致CPU瞬间降到0,触发了缩容。后来改成取5分钟平均值,稳多了。
- 注意“冷启动”问题: 新启动的实例需要预热。如果一启动就加入负载均衡,CPU会瞬间飙高,触发新一轮扩容。我一般给新实例加一个“预热期”,前2分钟不参与伸缩判断。
- 缩容策略要保守: 缩容比扩容危险得多。扩容最多多花点钱,缩容可能导致服务过载。我习惯把缩容阈值设得比扩容阈值低很多(比如扩容75%,缩容25%),留足缓冲。
- 别忘了“最大实例数”: 我见过有人没设上限,结果一次流量高峰弹出了200台机器,账单直接爆表。一定要设一个硬上限,比如最多20台。
一个小技巧: 如果你用的是Kubernetes,可以考虑HPA(Horizontal Pod Autoscaler)配合VPA(Vertical Pod Autoscaler)。HPA管数量,VPA管规格,两者配合能省更多钱。不过这是后面章节的内容了,这里先提一嘴。