云服务器自动伸缩配置指南:弹性应对流量波动
做电商的都知道这种痛:平时 2 台服务器绰绰有余,一到 618 或双十一流量涨 10 倍,凌晨爬起来手动加机器,加到一半网站已经超时;活动结束又忘了减,白白多烧一个月钱。自动伸缩(Auto Scaling)就是为了解决这个问题——让实例数量跟着真实负载自动增减,而不是靠人熬夜盯监控。它是云计算相对于传统服务器的核心优势之一。
先看它的工作闭环:
流量增长 → 触发扩容 → 增加实例 → 负载回落
流量下降 → 触发缩容 → 减少实例 → 成本下降
核心概念
| 组件 | 说明 |
|---|---|
| 启动模板 | 实例的"图纸":AMI/镜像、规格、安全组、User Data |
| 伸缩组 | 一组实例的逻辑集合,限定 min/max/desired |
| 伸缩策略 | 定义"何时扩、扩多少"的规则 |
| 冷却时间 | 一次扩缩容后等待多久再评估 |
| 健康检查 | 实例异常时自动替换,保证容量不掉 |
AWS Auto Scaling 配置
第 1 步:创建启动模板。 把新实例的配置固化下来,包括开机要执行的 User Data(比如让 nginx 自启):
# 启动模板配置
AMI: ubuntu-22.04-lts
Instance Type: t3.medium
Security Group: web-sg
Key Pair: my-key
User Data:
#!/bin/bash
systemctl start nginx
systemctl enable nginx
第 2 步:创建伸缩组。 指定最小、最大和期望实例数,并挂到多个可用区:
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name web-asg \
--launch-template LaunchTemplateName=web-template \
--min-size 2 --max-size 10 --desired-capacity 2 \
--vpc-zone-identifier subnet-aaa,subnet-bbb
第 3 步:配置策略和告警。 最省心的是目标跟踪策略(Target Tracking)——你只告诉它"CPU 保持在 50%",扩缩容由系统自动算;也可以用手动调整 + CloudWatch 告警:
# 基于 CloudWatch 告警的扩容策略
aws autoscaling put-scaling-policy \
--auto-scaling-group-name web-asg \
--policy-name cpu-scale-up \
--scaling-adjustment 1 --adjustment-type ChangeInCapacity --cooldown 300
# 对应的 CloudWatch 告警
aws cloudwatch put-metric-alarm --alarm-name cpu-high \
--metric-name CPUUtilization --namespace AWS/EC2 \
--threshold 70 --period 120 --statistic Average
参考:AWS Auto Scaling 文档 https://docs.aws.amazon.com/autoscaling/ec2/userguide/what-is-amazon-ec2-auto-scaling.html
阿里云弹性伸缩
阿里云的配置路径是:创建伸缩组 → 配置伸缩配置(镜像+规格)→ 添加伸缩规则 → 绑定定时或告警任务。典型规则如下:
规则名称: cpu-scale-out
触发条件: CPU 使用率 > 75% 持续 5 分钟
动作: 增加 1 台实例
冷却时间: 300 秒
规则名称: cpu-scale-in
触发条件: CPU 使用率 < 30% 持续 10 分钟
动作: 移除 1 台实例
冷却时间: 600 秒
注意缩容的阈值比扩容低、持续时间比扩容长(示例里是 10 分钟 vs 5 分钟)。原因很简单:流量上来要反应快,流量下去要观察久,避免"一抖就缩、一缩又弹"的抖动。
参考:阿里云弹性伸缩文档 https://help.aliyun.com/zh/ess/
缩容不等于直接删机器
扩容易、缩容难。缩容时系统会从伸缩组里挑实例移除,不做保护的话,正在处理请求的实例可能被直接销毁:
- 开启缩容保护(Scale-in Protection),让正在跑任务的关键实例不被自动移除;
- 让应用支持优雅下线:收到 SIGTERM 后停止接收新请求、排空存量连接,再退出;
- 把伸缩组挂到负载均衡后,新实例注册有健康检查窗口,"上线前预热"不能省。
一个真实案例:大促前的定时扩容
某个日活 50 万的内容站,把两种策略搭配着用:大促当天上午 10 点前用定时扩容把实例从 4 台提前拉到 20 台(流量是凌晨开始涨的,动态策略根本来不及反应);日常则用目标跟踪策略把 CPU 维持在 50%。活动结束后再定时缩回 4 台。结果:活动期间 99.99% 的请求在 200ms 内返回,账单也只比平时多出活动那几小时的费用。
这个案例的关键在于把"可预期的流量"和"不可预期的负载"分开治理——定时任务对付前者,动态策略兜住后者,而不是指望一套策略通吃。
最佳实践
| 实践 | 说明 |
|---|---|
| 设好 min/max | 防止无限扩容烧钱、无限缩容崩服务 |
| 多可用区部署 | 单个可用区故障时仍有容量 |
| 容量缓冲 | 目标 CPU 别设到 90%,留 20-30% 余量 |
| 预热新实例 | 新实例就绪后再接流量 |
| 定期压测演练 | 模拟流量高峰,验证策略真的会触发 |
常见问题
为什么 CPU 都 100% 了还不扩容? 先看冷却时间是否过长、告警的持续评估期设置是否合理,再看伸缩组 max 是不是到了上限。
突然的尖峰流量,动态策略来得及吗? 来不及——CPU 是滞后指标。对付可预期的活动(大促、秒杀),加定时扩容;对付突发流量,考虑预留容量或更高的起始实例数。
缩容后会话丢失怎么办? 把会话/缓存外置(Redis、数据库),应用保持无状态,实例才能随时增减。
自动伸缩不是"配好就不管",它需要和监控告警、压测演练放在一起维护。配置对了,它是省钱又扛压的利器;配置错了,它就是半夜把你叫醒的告警来源。