感知中断事件与响应

抢占式实例可能会因为价格因素或者市场供需变化而被强制回收,如果您的业务对实例中断敏感,则需要注意及时感知抢占式实例的中断事件并做出响应处理。为了帮助您更好地开发中断事件处理程序,本文将指导您如何通过不同的方式感知中断事件。

感知中断事件

通过ECSSDK查询

通过云服务器ECSDescribeInstances接口查询实例信息,并根据返回的OperationLocks判断实例是否进入待回收状态。

  • 若返回空值:实例可持续使用。

  • 若返回LockReason值为Recycling:抢占式实例被中断,处于待回收状态。

SDK调用示例

准备工作

  1. 创建AccessKey

    由于阿里云账号(主账号)拥有资源的所有权限,其AccessKey一旦泄露风险巨大,所以建议您使用满足最小化权限需求的RAM用户的AccessKey。获取方法请参见创建AccessKey

  2. RAM用户授予CMS相关权限

    RAM用户授予操作云服务器ECS相关资源的权限。本文提供的示例代码需要创建查询实例信息,建议授予以下权限:

    云产品

    授予权限

    云服务器ECS

    本示例选择系统策略:AliyunECSFullAccess

  3. 配置访问凭证

    本文示例代码会在系统环境变量中读取AccessKey作为访问云服务的凭证,具体操作步骤请参见Linux、macOSWindows系统配置环境变量

  4. 安装ECS SDK

    获取ECS SDK,本文通过添加Maven依赖的方式来安装。更多安装方式,请参见安装ECS Java SDK

    添加Maven依赖的示例如下:

    <dependencies>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>ecs20140526</artifactId>
            <version>5.3.0</version>
        </dependency>
    </dependencies>

初始化客户端

阿里云SDK支持多种访问凭据用于初始化客户端,例如AccessKeySTS Token等,更多方式请参见管理访问凭据。本示例以通过AccessKey初始化客户端为例。

import com.aliyun.ecs20140526.Client;
import com.aliyun.teaopenapi.models.Config;

public class Sample {
    private static Client createClient() throws Exception {
        Config config = new Config()
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
                // Endpoint 请参考 https://api.aliyun.com/product/Ecs
                .setEndpoint("ecs.cn-hangzhou.aliyuncs.com");
        return new Client(config);
    }
}

构建接口的请求对象

在构建请求对象之前,请查看该接口的API文档获取参数信息。

// 构造请求对象
DescribeInstancesRequest request = new DescribeInstancesRequest().setRegionId("cn-hangzhou");

发起调用

通过客户端调用OpenAPI时,支持设置运行时参数,例如超时配置、代理配置等,更多信息请查看进阶配置

// 设置运行时参数
RuntimeOptions runtime = new RuntimeOptions();
// 调用 DescribeInstances 接口
DescribeInstancesResponse response = client.describeInstancesWithOptions(request, runtime);
System.out.println(response.body.toMap());

异常处理

Java SDK将异常进行了细致的分类,主要划分为TeaUnretryableExceptionTeaException。

  • TeaUnretryableException:主要是因为网络问题造成,一般是网络问题达到最大重试次数后抛出。

  • TeaException:主要以业务报错为主的异常。

建议采取合理的措施来处理异常,比如合理地传播异常、记录日志、尝试恢复等,以确保系统的健壮性和稳定性。

完整示例

import com.aliyun.ecs20140526.Client;
import com.aliyun.ecs20140526.models.DescribeInstancesRequest;
import com.aliyun.ecs20140526.models.DescribeInstancesResponse;
import com.aliyun.ecs20140526.models.DescribeInstancesResponseBody;
import com.aliyun.tea.TeaException;
import com.aliyun.tea.TeaUnretryableException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.alibaba.fastjson.JSONArray;

import java.util.Arrays;

public class Sample {
    private static Client createClient() throws Exception {
        Config config = new Config()
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
                // Endpoint 请参考 https://api.aliyun.com/product/Ecs
                .setEndpoint("ecs.cn-hangzhou.aliyuncs.com");
        return new Client(config);
    }

    public static void main(String[] args) {
        try {
            Client client = Sample.createClient();
            // 构造请求对象
            // 设置待查询的一个或多个ECS实例ID。
            JSONArray instanceIds = new JSONArray();
            instanceIds.addAll(Arrays.asList("i-bp145cvd0exyqj****","i-bp1gehfgfrrk4lah****"));
            DescribeInstancesRequest request = new DescribeInstancesRequest()
                    .setRegionId("cn-hangzhou")
                    .setInstanceIds(instanceIds.toJSONString());
            // 设置运行时参数
            RuntimeOptions runtime = new RuntimeOptions();
            while (!instanceIds.isEmpty()) {
              // 调用 DescribeInstances 接口
              DescribeInstancesResponse response = client.describeInstancesWithOptions(request, runtime);
              // 获取实例相关的返回结果。
              DescribeInstancesResponseBody responseBody = response.getBody();
              DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstances instanceList = responseBody.getInstances();
              //获取实例信息,并根据lockReason返回值进行判断
              if (instanceList != null && instanceList.getInstance()!= null && !instanceList.getInstance().isEmpty()) {
                  for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance instance : instanceList.getInstance()) {
                      // 输出被查询的实例ID与可用区信息。
                      System.out.println("result:instance:" + instance.getInstanceId() + ",az:" + instance.getZoneId());
                      if (instance.getOperationLocks() != null ) {
                          DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstanceOperationLocks operationLocks  = instance.getOperationLocks();
                          if(operationLocks.getLockReason()!=null && !operationLocks.getLockReason().isEmpty()){
                              for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstanceOperationLocksLockReason lockReason : operationLocks.getLockReason()) {
                                  // 如果实例被锁定,输出指定实例ID以及对应的锁定类型。
                                  System.out.println("instance:" + instance.getInstanceId() + "-->lockReason:" + lockReason.getLockReason() + ",vmStatus:" + instance.getStatus());
                                  if ("Recycling".equals(lockReason.getLockReason())) {
                                      // 输出即将被回收的实例ID信息。
                                      System.out.println("spot instance will be recycled immediately, instance id:" + instance.getInstanceId());
                                      instanceIds.remove(instance.getInstanceId());
                                  }
                              }
                          }

                      }
                  }
                  // 如果抢占式实例还未被锁定,将每隔两分钟查询一次。
                  System.out.print("try describeInstances again later ...");
                  Thread.sleep(2 * 60 * 1000);
              } else {
                  break;
              }
            }
        } catch (TeaUnretryableException ue) {
            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            ue.printStackTrace();
            // 打印错误信息
            System.out.println(ue.getMessage());
            // 打印请求记录,查询错误发生时的请求信息
            System.out.println(ue.getLastRequest());
        } catch (TeaException e) {
            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            e.printStackTrace();
            // 打印错误码
            System.out.println(e.getCode());
            // 打印错误信息,错误信息中包含 RequestId
            System.out.println(e.getMessage());
            // 打印服务端返回的具体错误内容
            System.out.println(e.getData());
        } catch (Exception e) {
            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            e.printStackTrace();
        }
    }
}

返回结果

触发回收时输出结果如下:

result:instance:i-bp1i9c3qiv1qs6nc****,az:cn-hangzhou-i
instance:i-bp1i9c3qiv1qs6nc****-->lockReason:Recycling,vmStatus:Stopped
spot instance will be recycled immediately, instance id:i-bp1i9c3qiv1qs6nc****

通过元数据在实例内部查询

您可以在ECS实例内部访问元数据服务(Metadata Service)获知抢占式实例的终止时间。更多关于实例元数据的信息,请参见实例元数据

获取抢占式实例停机释放时间元数据:instance/spot/termination-time

返回结果:

  • 如果返回404:实例可持续使用。

  • 如果返回类似2015-01-05T18:02:00Z格式的信息(UTC时间):实例将于这个时间被回收。

调用示例:

Linux实例

# 获取元数据服务器的访问凭证用于鉴权
TOKEN=`curl -X PUT "http://100.100.100.200/latest/api/token" -H "X-aliyun-ecs-metadata-token-ttl-seconds:<元数据服务器访问凭证有效期>"`
# 查询抢占式实例是否被中断回收
curl -H "X-aliyun-ecs-metadata-token: $TOKEN" http://100.100.100.200/latest/meta-data/instance/spot/termination-time

Windows实例

# 获取元数据服务器的访问凭证用于鉴权
$token = Invoke-RestMethod -Headers @{"X-aliyun-ecs-metadata-token-ttl-seconds" = "<元数据服务器访问凭证有效期>"} -Method PUT -Uri http://100.100.100.200/latest/api/token
# 查询抢占式实例是否被中断回收
Invoke-RestMethod -Headers @{"X-aliyun-ecs-metadata-token" = $token} -Method GET -Uri http://100.100.100.200/latest/meta-data/instance/spot/termination-time

通过云监控SDK查询

ECS实例相关的事件都会同步至云监控,您也可直接通过云监控的DescribeSystemEventAttribute接口查询抢占式实例中断事件Instance:PreemptibleInstanceInterruption,根据返回结果中的content字段返回值是否为delete判断抢占式实例是否触发中断回收。

SDK调用示例

准备工作

  1. 创建AccessKey

    由于阿里云账号(主账号)拥有资源的所有权限,其AccessKey一旦泄露风险巨大,所以建议您使用满足最小化权限需求的RAM用户的AccessKey。获取方法请参见创建AccessKey

  2. RAM用户授予CMS相关权限

    RAM用户授予操作云监控CMS的权限。本文提供的示例代码需要查询系统事件,建议授予以下权限:

    云产品

    授予权限

    云监控CMS

    AliyunCloudMonitorFullAccess

  3. 配置访问凭证

    本文示例代码会在系统环境变量中读取AccessKey作为访问云服务的凭证,具体操作步骤请参见Linux、macOSWindows系统配置环境变量

  4. 安装CMS SDK

    获取CMS SDK,本文通过添加Maven依赖的方式来安装。更多安装方式,请参见安装CMS Java SDK

    添加Maven依赖的示例如下:

    <dependencies>
        <dependency>
          <groupId>com.aliyun</groupId>
          <artifactId>cms20190101</artifactId>
          <version>8.1.3</version>
        </dependency>
    </dependencies>

初始化客户端

阿里云SDK支持多种访问凭据用于初始化客户端,例如AccessKeySTS Token等,更多方式请参见管理访问凭据。本示例以通过AccessKey初始化客户端为例。

import com.aliyun.cms20190101.Client;
import com.aliyun.teaopenapi.models.Config;

public class Sample {
    private static Client createClient() throws Exception {
        Config config = new Config()
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
                // Endpoint 请参考 https://api.aliyun.com/product/Ecs
                .setEndpoint("metrics.cn-hangzhou.aliyuncs.com");
        return new Client(config);
    }
}

构建接口的请求对象

配置抢占式实例中断事件的查询参数,更多参数请参见DescribeSystemEventAttribute

API

参数

示例取值

DescribeSystemEventAttribute

Product

产品名称缩写:ECS

EventType

事件类型:StatusNotification

Name

事件名称:Instance:PreemptibleInstanceInterruption

// 构造请求对象
DescribeSystemEventAttributeRequest request = new DescribeSystemEventAttributeRequest()
    .setProduct("ECS");
    .setEventType("StatusNotification");
     .setName("Instance:PreemptibleInstanceInterruption");

发起调用

通过客户端调用OpenAPI时,支持设置运行时参数,例如超时配置、代理配置等,更多信息请查看进阶配置

// 设置运行时参数
RuntimeOptions runtime = new RuntimeOptions();
// 调用 DescribeInstances 接口
DescribeSystemEventAttributeResponse response = client.describeSystemEventAttributeWithOptions(request, runtime);
System.out.println(response.body.toMap());

异常处理

Java SDK将异常进行了细致的分类,主要划分为TeaUnretryableExceptionTeaException。

  • TeaUnretryableException:主要是因为网络问题造成,一般是网络问题达到最大重试次数后抛出。

  • TeaException:主要以业务报错为主的异常。

建议采取合理的措施来处理异常,比如合理地传播异常、记录日志、尝试恢复等,以确保系统的健壮性和稳定性。

完整示例

import com.aliyun.cms20190101.Client;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.cms20190101.models.DescribeSystemEventAttributeRequest;
import com.aliyun.cms20190101.models.DescribeSystemEventAttributeResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.tea.TeaUnretryableException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;

public class Sample {
    private static Client createClient() throws Exception {
        Config config = new Config()
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
                .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
                .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
                // Endpoint 请参考 https://api.aliyun.com/product/Ecs
                .setEndpoint("metrics.cn-hangzhou.aliyuncs.com");
        return new Client(config);
    }

    public static void main(String[] args) {
        try {
            Client client = Sample.createClient();
            // 构造请求对象
            DescribeSystemEventAttributeRequest request = new DescribeSystemEventAttributeRequest()
                .setProduct("ECS");
                .setEventType("StatusNotification");
                .setName("Instance:PreemptibleInstanceInterruption");
            // 设置运行时参数
            RuntimeOptions runtime = new RuntimeOptions();
            // 调用 DescribeSystemEventAttribute 接口
            DescribeSystemEventAttributeResponse response = client.describeSystemEventAttributeWithOptions(request, runtime);
            System.out.println(response.body.toMap());
        } catch (TeaUnretryableException ue) {
            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            ue.printStackTrace();
            // 打印错误信息
            System.out.println(ue.getMessage());
            // 打印请求记录,查询错误发生时的请求信息
            System.out.println(ue.getLastRequest());
        } catch (TeaException e) {
            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            e.printStackTrace();
            // 打印错误码
            System.out.println(e.getCode());
            // 打印错误信息,错误信息中包含 RequestId
            System.out.println(e.getMessage());
            // 打印服务端返回的具体错误内容
            System.out.println(e.getData());
        } catch (Exception e) {
            // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
            e.printStackTrace();
        }
    }
}

返回结果

根据返回结果判断抢占式实例中断事件。

事件通知的JSON格式如下所示:

{
  "ver": "1.0",
  "id": "2256A988-0B26-4E2B-820A-8A********E5",
  "product": "ECS",
  "resourceId": "acs:ecs:cn-hangzhou:169070********30:instance/i-bp1ecr********5go2go",
  "level": "INFO",
  "name": "Instance:PreemptibleInstanceInterruption",
  "userId": "169070********30",
  "eventTime": "20190409T121826.922+0800",
  "regionId": "cn-hangzhou",
  "content": {
    "instanceId": "i-bp1ecr********5go2go",  
    "action": "delete"                       
  }
}

content字段解释如下表所示。更多参数说明,请参见DescribeSystemEventAttribute

字段

说明

示例值

instanceId

抢占式实例的ID。

i-bp1ecr********5go2go

action

抢占式实例的操作事件。取值delete时表示抢占式实例中断,将被强制回收。

delete

订阅云监控系统事件

通过订阅云监控系统事件实时监控抢占式实例的中断事件,再通过短信、邮件、函数计算、消息队列、Webhook等不同的渠道推送。

工作流程

image

操作步骤

  1. 接收渠道准备

    函数计算

    1. 登录函数计算控制台,在左侧导航栏,单击服务及函数
    2. 在顶部菜单栏,选择地域,然后在服务列表页面,单击目标服务。
    3. 函数管理页面,单击创建函数
    4. 创建函数页面,按需选择创建函数的方式,配置以下配置项,然后单击创建

      说明

      本文以使用内置运行时创建使用自定义运行时创建方式为例进行说明。如果函数计算提供的环境无法满足您的业务需求,您可以使用容器镜像创建方式部署函数。具体操作,请参见创建Custom Container函数

      • 基本设置:配置函数的基本信息,包括函数名称请求处理程序类型请求处理程序类型包括以下两种。

        • 处理事件请求:通过定时器、调用API/SDK或其他阿里云服务的触发器来触发函数执行。

        • 处理 HTTP 请求:用于处理HTTP请求或WebSocket请求的函数。如果您的使用场景是Web场景,建议您使用自定义运行时创建

      • 函数代码:配置函数的运行环境和代码相关信息。

        配置项

        说明

        示例

        运行环境

        选择您熟悉的语言,例如Python、Java、PHPNode.js等。函数计算支持的运行环境,请参见函数计算支持的函数运行环境列表

        Node.js14

        代码上传方式

        选择上传函数代码到函数计算的方式。

        • 使用示例代码:默认方式,您可以根据业务需要选择函数计算为您提供的创建函数的示例代码。

        • 通过 ZIP 包上传代码:选择函数代码ZIP包并上传。

        • 通过 JAR 包上传代码:选择函数代码JAR包并上传。

        • 通过文件夹上传代码:选择包含函数代码的文件夹并上传。

        • 通过 OSS 上传代码:选择上传函数代码的Bucket 名称文件名称

        说明
        • 代码上传方式选择使用示例代码时,不需要修改请求处理程序。当选择其他代码上传方式时,则需要根据实际情况修改请求处理程序,否则函数执行时会报错。

        • 运行环境选择为Java 8Java 11时,只支持使用示例代码通过 JAR 包上传代码通过 OSS 上传代码。其余运行环境支持使用示例代码通过 ZIP 包上传代码通过文件夹上传代码通过 OSS 上传代码

        使用示例代码

        启动命令

        说明

        仅当您选择使用自定义运行时创建函数时,需设置此配置项。

        程序的启动命令。如果不配置启动命令,您需要在代码的根目录手动创建一个名称为bootstrap的启动脚本,您的程序通过此脚本来启动。

        npm run start

        监听端口

        说明

        仅当您选择使用自定义运行时创建函数时,需设置此配置项。

        您的代码中的HTTP Server所监听的端口。

        9000

      • 高级配置:配置函数的实例相关信息和函数执行超时时间等。

        配置项

        说明

        示例

        规格方案

        根据您的业务情况,选择或手动输入合理的vCPU规格内存规格组合。关于各资源使用的计费详情,请参见计费概述

        说明

        vCPU大小(单位为核)与内存大小(单位为GB)的比例必须设置在1∶11∶4之间。

        0.35核,512 MB

        临时硬盘大小

        根据您的业务情况,选择临时存储文件的硬盘大小。

        取值说明如下。

        • 512 MB:默认值。不计费,函数计算为您提供512 MB以内的硬盘免费使用额度。

        • 10 GB:按9.5 GB进行计费。

        说明

        临时硬盘中所有目录可写,共享临时硬盘的空间。

        临时硬盘大小与底层执行函数的实例生命周期一致,实例被系统回收后,硬盘上的数据也会消失。如您需要对文件进行持久化保存,可以选择挂载NASOSS。具体操作,请参见配置NAS文件系统配置OSS文件系统

        512 MB

        实例并发度

        设置函数实例的并发度。具体信息,请参见设置实例并发度

        10

        执行超时时间

        设置超时时间。执行超时时间默认为60秒,最长为86400秒。

        60

        请求处理程序

        设置请求处理程序,函数计算的运行时会加载并调用您的请求处理程序处理请求。选择使用自定义运行时创建使用容器镜像创建函数时,无需设置此配置项。

        说明

        代码上传方式选择使用示例代码时,不需要修改请求处理程序。当选择其他代码上传方式时,则需要根据实际情况修改请求处理程序,否则函数执行时会报错。

        index.handler

        时区

        选择函数的时区。此处设置函数的时区后,将自动为函数添加一条环境变量TZ,其值为您设置的目标时区。

        UTC

      • 环境变量:设置函数运行环境中的环境变量。更多信息,请参见环境变量

      • 触发器配置:设置函数的触发器,您可以使用触发器触发函数执行。更多信息,请参见触发器管理

    轻量消息队列

    1. 登录轻量消息队列(原 MNS)控制台

    2. 在左侧导航栏,选择队列模型 > 队列列表

    3. 在顶部菜单栏,选择地域。

    4. 队列列表页面,单击创建队列

    5. 创建队列面板配置以下参数,然后单击确定

      • 名称:队列名称。

      • 消息最大长度:发送到队列的消息体的最大长度。

      • 长轮询时间:当队列中没有消息时,该队列的ReceiveMessage请求的最大等待时长。

      • 消息可见性超时时间:消息从队列中取出后从Active状态变成Inactive状态后的持续时间。

      • 消息保存时长:消息在队列中的最长存活时间。从发送到队列开始经过此参数指定的时间后,不论消息是否被取出都将被删除。

      • 消息延时时间:发送到队列的所有消息将延后此参数指定的时间后被消费。

      • 启用日志功能:是否开启日志管理功能。

      队列列表页面目标队列已创建。

    Webhook

    重要

    Webhook服务需要部署在开通公网的服务器上,注意服务器需要开启响应端口的访问权限。

    Java示例代码如下:

    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class WebhookController {
        @PostMapping("/callback")
        public ResponseEntity<String> receiveWebhook(@RequestBody String payload) {
            // 处理payload,例如记录日志或进行业务逻辑处理
            System.out.println("Received webhook payload: " + payload);
            // 返回成功响应
            return ResponseEntity.ok("Webhook received");
        }
    }

  2. 创建订阅策略

    1. 登录云监控控制台

    2. 在左侧导航栏,选择事件中心 > 事件订阅

    3. 订阅策略页签,单击创建订阅策略

    4. 创建订阅策略页面,设置订阅策略的相关参数。

      本示例仅说明订阅抢占式实例中断事件所涉及的参数,更多参数说明,请参见管理事件订阅(推荐)

      • 基本信息:输入订阅策略名称描述

      • 报警订阅

        • 订阅类型:选择系统事件

        • 订阅范围

        • 产品:选择云服务器ECS

        • 事件类型:选择状态通知

        • 事件名称:选择抢占式实例中断通知

        • 事件等级:选择告警(Warning)

        • 应用分组事件内容事件资源:均不设置,表示订阅本账号内所有应用分组中的所有ECS实例的系统事件抢占式实例中断通知

      • 合并降噪:使用默认值。

      • 通知自定义通知方式使用默认通知方式。

      • 推送与集成:点击添加渠道,弹出窗口中点击增加渠道目标类型选择第1步准备的渠道,其他参数根据提示完成填写即可。更多推送渠道说明,请参见管理推送渠道

  3. 模拟中断事件

    抢占式实例的中断事件为被动触发事件,当您在开发抢占式实例中断事件处理程序过程中,无法有效地进行代码调试。您可以借助调试事件订阅模拟抢占式实例中断事件。

    1. 订阅策略页签,单击调试事件订阅

    2. 创建事件调试面板,产品选择云服务器ECS名称选择抢占式实例中断通知

      系统自动生成JSON格式的调试内容,您需要将JSON文件中资源相关的信息替换为待模拟中断事件的抢占式实例的信息。

      • 阿里云账号UID变量需要替换为当前登录的阿里云账号UID。

      • <resource-id>以及<instanceId>需要替换为抢占式实例的实例ID。

      • <地域ID>需要替换为抢占式实例所属的地域ID。

        {
            "product": "ECS",
            "resourceId": "acs:ecs:cn-shanghai:阿里云账号UID:instance/<resource-id>",
            "level": "WARN",
            "instanceName": "instanceName",
            "regionId": "<地域ID>",
            "groupId": "0",
            "name": "Instance:PreemptibleInstanceInterruption",
            "content": {
                "instanceId": "i-2zeg014dfo4y892z***",
                "instanceName": "wor***b73",
                "action": "delete"
            },
            "status": "Normal"
        }
    3. 单击确定

      系统提示操作成功,云监控自动根据订阅策略中的通知方式发送一条报警测试通知。

  4. 接收和查看

    函数计算

    1. 登录函数计算控制台,在左侧导航栏,单击服务及函数

    2. 在顶部菜单栏,选择地域,然后在服务列表页面,单击目标服务操作列的函数管理

    3. 函数管理页面,单击目标函数名称,然后在函数详情页面,单击调用日志页签

    轻量消息队列

    1. 登录轻量消息队列(原 MNS)控制台

    2. 队列列表页面,找到目标队列,在其右侧操作列选择更多 > 收发消息

    3. 可选:队列收发消息快速体验页面,单击编辑接收消息参数,在编辑接收消息参数面板配置单次获取最大条数轮询时间,然后单击确定

    4. 队列收发消息快速体验页面的接收消息区域,单击接收消息

    5. 接收消息区域显示队列的消息列表。

    6. 可选:在消息列表中找到目标消息,在其右侧操作列单击详情,在消息详情对话框中查看消息内容等信息。

    Webhook

    在部署了Webhook的程序中查看调用情况和通知内容。

响应中断事件

如何响应中断,取决于您的实际业务场景和需求,强烈建议您对应用程序进行测试,确保它可以很好地应对抢占式实例的中断回收,下面给出一些思路和建议供您参考:

  • 优雅处理中断

    及时响应中断信号,保存任务处理进度并进行资源清理,终止任务执行。

  • 数据持久化和检查点

    定期将任务处理进度和中间结果保存到持久化存储(如本地文件或数据库),确保业务重要数据和配置得到了保存。关于数据保留和恢复的配置,请参见抢占式实例数据保留和恢复

  • 测试集成是否成功

    在云监控中触发测试事件,检查程序是否正确响应。更多信息,请参见通过轻量消息队列感知并响应抢占式实例中断事件