三层容量模型
基线容量
覆盖日常最低负载,用 Savings Plans 或预留实例锁定 1-3 年价格,单价最低。
弹性容量
按目标追踪策略随流量伸缩,优先使用 Spot 实例池,跨 3 个以上实例类型分散中断风险。
应急容量
预置容量储备(Capacity Reservation)或 On-Demand 兜底,只在大促、故障切换时启用。
容量规划四步法
-
01
采集与建模
拉取 90 天的 RPS、CPU、内存与响应时间数据,识别日内峰谷、周周期和活动尖峰。
交付物:负载曲线图、峰谷比与增长率、单实例承载能力基线
3-5 天
-
02
压测定标
在预生产环境阶梯加压,找到单实例的拐点(p99 开始劣化的并发数),而不是拿 CPU 70% 当上限。
交付物:单实例容量卡、拐点前的安全水位、扩容阈值建议
5-8 天
-
03
策略落地
配置目标追踪 + 预测性伸缩双策略,设置合理的预热时间与冷却窗口,避免抖动。
交付物:ASG 启动模板、伸缩策略 IaC 代码、混合实例分配策略
3-5 天
-
04
演练与调优
做一次 Spot 中断演练和一次流量翻倍演练,验证扩容速度与服务降级链路。
交付物:演练报告、调优后的阈值、容量应急手册
2-3 天
混合实例策略示例(Terraform)
resource "aws_autoscaling_group" "web" {
name = "web-asg"
vpc_zone_identifier = var.private_subnet_ids
min_size = 4 # 基线容量,由 Savings Plans 覆盖
max_size = 40
desired_capacity = 6
health_check_type = "ELB"
health_check_grace_period = 90
default_instance_warmup = 60
mixed_instances_policy {
instances_distribution {
# 基线 4 台走按需,超出部分 75% 用 Spot
on_demand_base_capacity = 4
on_demand_percentage_above_base_capacity = 25
spot_allocation_strategy = "price-capacity-optimized"
spot_max_price = " # 留空表示不超过按需价
}
launch_template {
launch_template_specification {
launch_template_id = aws_launch_template.web.id
version = "$Latest"
}
# 多类型分散中断风险,注意保持相近的 vCPU/内存比
override { instance_type = "m7i.large" }
override { instance_type = "m7a.large" }
override { instance_type = "m6i.large" }
override { instance_type = "m6a.large" }
override { instance_type = "m5.large" }
}
}
# 优雅退出:Spot 中断通知触发连接排空
capacity_rebalance = true
tag {
key = "CostCenter"
value = "web-frontend"
propagate_at_launch = true
}
}
resource "aws_autoscaling_policy" "target_tracking" {
name = "web-req-per-target"
autoscaling_group_name = aws_autoscaling_group.web.name
policy_type = "TargetTrackingScaling"
target_tracking_configuration {
predefined_metric_specification {
predefined_metric_type = "ALBRequestCountPerTarget"
resource_label = "${var.alb_arn_suffix}/${var.tg_arn_suffix}"
}
target_value = 800 # 由压测拐点反推,而非拍脑袋
}
}
capacity_rebalance 打开后,AWS 会在 Spot 中断前主动补容量,配合 90 秒预热基本无感。
常见踩坑对照
容易出问题的做法
- 用 CPU 60% 作为唯一扩容指标,忽略了 IO 或下游数据库瓶颈
- 冷却时间设成默认 300 秒,尖峰流量还没扩完就已经超时
- Spot 只挑一种实例类型,容量池枯竭时集体中断
- 健康检查用 EC2 类型,应用挂了但实例还在,流量继续打进来
- 缩容不做连接排空,用户请求被硬切断
推荐做法
- 以 ALBRequestCountPerTarget 或队列深度为主指标,CPU 作为辅助
- 启动模板内置预热镜像,配合 default_instance_warmup 缩短生效时间
- 至少 4-5 种同规格实例类型,跨 3 个可用区分散
- 健康检查用 ELB 类型 + 应用级 /healthz 探针
- 配置 deregistration_delay 与优雅停机钩子,先摘流量再关机