云服务器自动伸缩配置指南:弹性应对流量波动

做电商的都知道这种痛:平时 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、数据库),应用保持无状态,实例才能随时增减。

自动伸缩不是"配好就不管",它需要和监控告警、压测演练放在一起维护。配置对了,它是省钱又扛压的利器;配置错了,它就是半夜把你叫醒的告警来源。