You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决单实例ASG更新时先终止旧实例引发的停机问题?

问题场景

我有一个运行在单个EC2实例上的遗留应用,使用以下Auto Scaling Group(ASG)配置:

const asg = new autoscaling.AutoScalingGroup(this, `${stage}ASG`, {
  vpc,
  minCapacity: 1,
  maxCapacity: 1,
  launchTemplate,
  updatePolicy: autoscaling.UpdatePolicy.rollingUpdate({}),
  autoScalingGroupName: `${stage}ASG`,
  terminationPolicies: [autoscaling.TerminationPolicy.OLDEST_INSTANCE],
  healthCheck: autoscaling.HealthCheck.elb({
    grace: cdk.Duration.minutes(30),
  }),
});

更新启动模板时,ASG会先移除旧实例再启动新实例,导致新实例用户脚本完成前出现大量停机。希望实现ASG等待新实例用户脚本完成且负载均衡器健康检查通过后,再终止旧实例。

根据AWS官方文档说明:

实例先终止后启动:当Auto Scaling组中只有一个实例时,启动实例刷新可能会导致中断。这是因为Amazon EC2 Auto Scaling会先终止一个实例,然后再启动一个新实例。

但文档未给出该场景的缓解方案。

解决方案

要实现“先启动健康新实例,再终止旧实例”的无停机更新,需调整ASG的容量配置和更新策略,具体步骤如下:

  • 调整ASG容量上限
    将ASG的maxCapacity设置为2,minCapacity保持1。这样ASG在更新时会优先启动新实例,而非直接终止旧实例。推荐长期保持max=2,避免后续更新重复调整。

    修改后的CDK配置示例:

    const asg = new autoscaling.AutoScalingGroup(this, `${stage}ASG`, {
      vpc,
      minCapacity: 1,
      maxCapacity: 2, // 调整为2
      launchTemplate,
      updatePolicy: autoscaling.UpdatePolicy.rollingUpdate({
        minInstancesInService: 1, // 确保更新期间至少1个实例在线
        maxBatchSize: 1, // 每次仅更新1个实例
        pauseTime: cdk.Duration.minutes(30), // 匹配健康检查宽限期
        waitOnResourceSignals: true, // 等待实例初始化完成信号
      }),
      autoScalingGroupName: `${stage}ASG`,
      terminationPolicies: [autoscaling.TerminationPolicy.OLDEST_INSTANCE],
      healthCheck: autoscaling.HealthCheck.elb({
        grace: cdk.Duration.minutes(30),
      }),
    });
    
  • 配置滚动更新关键参数

    • minInstancesInService: 1:强制ASG在更新过程中始终保持至少1个健康实例在线,彻底避免停机。
    • waitOnResourceSignals: true:让ASG等待实例的用户脚本完成后发送的成功信号,确保应用初始化完成后才继续更新流程。
    • maxBatchSize: 1:每次只启动一个新实例,避免负载突增影响应用可用性。
  • 在用户脚本中添加健康信号
    确保EC2实例的用户数据脚本在完成所有初始化操作后,向CloudFormation发送成功信号,示例Bash脚本如下:

    #!/bin/bash
    # 执行应用初始化逻辑
    ./your-app-init-script.sh
    
    # 发送初始化完成信号
    /opt/aws/bin/cfn-signal -e 0 --stack ${AWS::StackName} --resource ${ASGLogicalID} --region ${AWS::Region}
    
  • 保留现有终止策略
    当前配置的OLDEST_INSTANCE终止策略会优先终止旧实例,完全符合“先启新再删旧”的需求,无需修改。


内容的提问来源于stack exchange,提问作者benito_h

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 12:53:25