如何使用Boto3在EC2实例间迁移工作负载平衡CPU利用率
基于Boto3实现EC2集群负载迁移的落地方案
明确核心前提:EC2没有内置的跨实例运行中工作负载热迁移能力,你需要实现的“把工作负载从高CPU实例迁到低CPU实例”,本质是通过流量切转+冗余实例回收的方式实现等效迁移,不需要直接搬运实例上的运行进程。
前置环境校验
在写代码前先确认现有环境满足基础条件,避免逻辑和现有规则冲突:
- 你的弹性伸缩组(ASG)已经关联了应用负载均衡器(ALB/NLB),作为流量调度的核心载体
- 给执行Boto3脚本的IAM角色配置对应权限:CloudWatch指标读取、AutoScaling组操作、ELBv2目标组修改、EC2实例查询
- 梳理清楚你现有扩缩容规则的触发阈值和冷却时间,自定义迁移逻辑要避开规则触发窗口期
核心实现流程
1. 拉取集群内所有实例的CPU指标
通过Boto3调用CloudWatch接口,采集ASG内所有处于服务状态的实例最近5分钟的平均CPU利用率,筛选符合迁移触发条件的场景:
迁移触发判定:集群内运行中实例数≥2,存在至少1台实例CPU≥70%,存在至少1台实例CPU≤30%
参考代码片段:
import boto3 from datetime import datetime, timedelta cloudwatch = boto3.client("cloudwatch") autoscaling = boto3.client("autoscaling") def get_asg_instance_cpu(asg_name: str) -> dict: # 查询ASG内所有处于InService状态的运行中实例 all_asg_instances = autoscaling.describe_auto_scaling_instances()["AutoScalingInstances"] running_instance_ids = [ inst["InstanceId"] for inst in all_asg_instances if inst["AutoScalingGroupName"] == asg_name and inst["LifecycleState"] == "InService" ] cpu_metrics = {} for instance_id in running_instance_ids: # 拉取实例最近5分钟的平均CPU利用率 metric_resp = cloudwatch.get_metric_statistics( Namespace="AWS/EC2", MetricName="CPUUtilization", Dimensions=[{"Name": "InstanceId", "Value": instance_id}], StartTime=datetime.utcnow() - timedelta(minutes=5), EndTime=datetime.utcnow(), Period=300, Statistics=["Average"] ) if metric_resp["Datapoints"]: cpu_metrics[instance_id] = metric_resp["Datapoints"][0]["Average"] return cpu_metrics
2. 高低负载实例分组
拿到CPU指标字典后,按负载区间做拆分:
- 高负载集合:所有CPU≥70%的实例
- 低负载集合:所有CPU≤30%、且在负载均衡目标组内有正常流量权重的实例
优先选择和高负载实例处于同一可用区的低负载实例承接切转流量,减少跨可用区的网络延迟开销
3. 执行等效负载迁移动作
不需要直接操作实例上的业务进程,通过两步完成负载转移:
第一步:调用ELBv2接口,将高负载实例在目标组的流量权重调整为0,所有新的业务请求会全部路由到低负载实例上。
参考代码片段:
elbv2 = boto3.client("elbv2") def cut_traffic_from_high_load(high_load_instance_id: str, target_group_arn: str, port: int = 80): # 将高负载实例的流量权重清零,不承接新请求 elbv2.register_targets( TargetGroupArn=target_group_arn, Targets=[{"Id": high_load_instance_id, "Port": port, "Weight": 0}] )
第二步:通过CloudWatch监控高负载实例的活跃连接数指标,等存量请求全部处理完成、连接数降到0之后,调用AutoScaling接口将该高负载实例从伸缩组中分离并终止,等效完成工作负载从高实例到低实例的迁移。
4. 避免和现有扩缩容规则冲突
迁移逻辑执行时要加两层校验,防止和原有自动扩缩容规则互相干扰:
- 切流前先检查ASG的当前期望容量,如果高负载已经触发了扩容动作(比如期望容量比实际运行容量高),先临时调整期望容量,避免流量切完之后原有缩容规则误下线刚刚承接流量的低负载实例
- 单次迁移动作执行完成后,设置10分钟的逻辑冷却期,冷却期内不再触发新的迁移判定,避免CPU指标短时间抖动导致频繁切流
生产环境注意事项
- 指标判定不要用1分钟以内的瞬时CPU值,至少用3-5分钟的平均指标,避免临时CPU尖峰触发无意义的迁移动作
- 不要在高负载实例还承接大量存量请求的时候强制终止实例,会导致用户请求报错
- 如果业务是有状态场景(比如本地存储用户会话、本地缓存),切流前需要先把高负载实例上的状态数据同步到低负载实例,避免出现用户会话丢失的问题
内容的提问来源于stack exchange,提问作者Augusto Accorsi
相关产品推荐
相关产品推荐

