You need to enable JavaScript to run this app. 如何使用Boto3在EC2实例间迁移工作负载平衡CPU利用率
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 15:06:05