模拟抢占式实例中断事件

抢占式实例的中断事件为被动触发事件,当您在开发抢占式实例中断事件处理程序过程中,无法有效地进行代码调试。因此阿里云提供了模拟抢占式实例中断事件的方式,便于您调试运维程序。

背景信息

模拟抢占式实例中断事件需要依赖阿里云云监控,您可以通过云监控控制台或者云监控API模拟中断事件。中断事件的触发机制如下图所示:

image

操作步骤

通过云监控控制台模拟中断事件

本方式中,以云监控设置中断事件报警规则,并将事件投递到轻量消息队列(原MNS)为例,介绍如何通过云监控控制台模拟中断事件。

  1. 登录云监控控制台

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

  3. 事件监控页签,单击另存为报警

  4. 创建/修改事件报警面板,完成以下配置,然后单击确定

    • 报警规则名称:自定义名称。例如:抢占式实例中断事件报警。

    • 产品类型:选择云服务器ECS

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

    • 事件等级:选择警告

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

    • 资源范围:保持默认配置。

    • 报警方式:您需要根据实际情况,选择适用于您业务的报警方式。本示例中,选择轻量消息队列(原MNS)

    成功创建后,您可以在报警规则页签,查看已创建的规则。

  5. 在抢占式实例中断事件的报警规则的操作列,选择image.png > 调试

  6. 创建事件调试面板,修改JSON文件,然后单击确定

    您需要将JSON文件中资源相关的信息替换为待模拟中断事件的抢占式实例的信息。JSON文件内容如下所示。其中:

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

    • <resource-id>以及i-2zeg014dfo4y892z***两个变量需要替换为抢占式实例的实例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***",
            "action": "delete"
        },
        "status": "Normal"
    }

    成功发起调试后,系统将根据您设置的报警方式推送报警信息。

通过云监控OpenAPI模拟中断事件

本方式中,使用Alibaba Cloud SDK for Java,以云监控设置中断事件报警规则,并将事件投递到轻量消息队列(原MNS)为例,介绍如何通过云监控OpenAPI模拟中断事件。

  1. 完成准备工作。

    1. 获取阿里云账号对应的AccessKey。

      具体操作,请参见创建AccessKey

    2. 在开发环境中安装Java SDK。

      您需要在Maven项目中添加以下依赖。具体操作,请参见SDK参考

      <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>tea-openapi</artifactId>
        <version>0.0.13</version>
      </dependency>
      
      <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>cms20190101</artifactId>
        <version>1.0.1</version>
      </dependency>
  2. 调用云监控的PutEventRule接口,创建抢占式实例中断事件报警规则。

    Java代码样例如下所示:

    com.aliyun.cms20190101.Client client = Sample.createClient(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));import com.aliyun.cms20190101.models.*;
    import com.aliyun.teaopenapi.models.*;
    
    /**
     * 调用PutEventRule创建或修改事件的报警规则。
     */
    public class Sample {
    
        // 初始化请求参数。
        public static com.aliyun.cms20190101.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
            // 您的阿里云账号的AccessKey ID以及AccessKey Secret。
            Config config = new Config().setAccessKeyId(accessKeyId).setAccessKeySecret(accessKeySecret);
            // OpenAPI的接入点(Endpoint)。
            config.endpoint = "metrics.cn-hangzhou.aliyuncs.com";
            return new com.aliyun.cms20190101.Client(config);
        }
    
        public static void main(String[] args_) throws Exception {
            java.util.List<String> args = java.util.Arrays.asList(args_);
            // 请确保代码运行环境设置了环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
            // 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取AccessKey的方式进行调用,建议使用更安全的STS方式。
            com.aliyun.cms20190101.Client client = Sample.createClient(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
            PutEventRuleRequest.PutEventRuleRequestEventPattern eventPattern0 = new PutEventRuleRequest.PutEventRuleRequestEventPattern()
                    // 设置事件报警规则的类型。
                    .setEventTypeList(java.util.Arrays.asList("*"))
                    // 事件报警规则的等级。
                    .setLevelList(java.util.Arrays.asList("*"))
                    // 事件报警规则的名称
                    .setNameList(java.util.Arrays.asList("Instance:PreemptibleInstanceInterruption"))
                    // 云服务类型
                    .setProduct("ECS");
            PutEventRuleRequest putEventRuleRequest = new PutEventRuleRequest()
                    // 自定义规则名称。
                    .setRuleName("spot_release_event_test")
                    .setEventPattern(java.util.Arrays.asList(eventPattern0))
                    // 事件报警规则的类型。
                    .setEventType("SYSTEM")
                    // 事件报警规则的状态。
                    .setState("ENABLED");
            //未打印返回结果,如有需要您可以自行打印。
            client.putEventRule(putEventRuleRequest);
        }
    }
  3. 通过阿里云轻量消息队列(原MNS),创建消息队列。

    创建消息队列的代码样例,请参见步骤二:创建队列

  4. 调用云监控的PutEventRuleTargets接口,为已创建的报警规则设置报警方式,将消息投递至已创建的消息队列中。

    Java代码样例如下所示:

    import com.aliyun.cms20190101.models.*;
    import com.aliyun.teaopenapi.models.*;
    
    /**
     * 调用PutEventRuleTargets添加或修改报警规则的发送目标。
     */
    public class Sample {
    
        // 初始化请求参数。
        public static com.aliyun.cms20190101.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
            // 您的阿里云账号的AccessKey ID以及AccessKey Secret。
            Config config = new Config().setAccessKeyId(accessKeyId).setAccessKeySecret(accessKeySecret);
            // OpenAPI的接入点(Endpoint)。
            config.endpoint = "metrics.cn-hangzhou.aliyuncs.com";
            return new com.aliyun.cms20190101.Client(config);
        }
    
        public static void main(String[] args_) throws Exception {
            // 请确保代码运行环境设置了环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
            // 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取AccessKey的方式进行调用,建议使用更安全的STS方式。
            com.aliyun.cms20190101.Client client = Sample.createClient(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
            PutEventRuleTargetsRequest.PutEventRuleTargetsRequestMnsParameters mnsParameters0 = new PutEventRuleTargetsRequest.PutEventRuleTargetsRequestMnsParameters()
                    // 消息队列所属的地域。
                    .setRegion("cn-hangzhou")
                    // 规则发送目标的唯一标识。
                    .setId("1")
                    // 队列名称。
                    .setQueue("mq-test");
            PutEventRuleTargetsRequest putEventRuleTargetsRequest = new PutEventRuleTargetsRequest()
                    // 指定报警规则的名称。
                    .setRuleName("spot_release_event_test")
                    .setMnsParameters(java.util.Arrays.asList(
                            mnsParameters0
                    ));
            // 未打印返回结果,如有需要您可以自行打印。
            client.putEventRuleTargets(putEventRuleTargetsRequest);
        }
    }
  5. 调用云监控的SendDryRunSystemEvent接口,发送模拟中断事件。

    Java代码样例如下所示:

    import com.aliyun.cms20190101.models.*;
    import com.aliyun.teaopenapi.models.*;
    
    /**
     *调用SendDryRunSystemEvent调试云资源的系统事件。
     */
    public class Sample {
    
        // 初始化请求参数。
        public static com.aliyun.cms20190101.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
            // 您的阿里云账号的AccessKey ID以及AccessKey Secret。
            Config config = new Config().setAccessKeyId(accessKeyId).setAccessKeySecret(accessKeySecret);
            // OpenAPI的接入点(Endpoint)。
            config.endpoint = "metrics.cn-hangzhou.aliyuncs.com";
            return new com.aliyun.cms20190101.Client(config);
        }
    
        public static void main(String[] args_) throws Exception {
            // 请确保代码运行环境设置了环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
            // 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取AccessKey的方式进行调用,建议使用更安全的STS方式。
            com.aliyun.cms20190101.Client client = Sample.createClient(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
            SendDryRunSystemEventRequest sendDryRunSystemEventRequest = new SendDryRunSystemEventRequest()
                    // 云服务名称。
                    .setProduct("ecs")
                    // 报警事件名称。
                    .setEventName("Instance:PreemptibleInstanceInterruption")
                    // 设置模拟事件的内容。
                    .setEventContent("{\"product\":\"ECS\",\"resourceId\":\"acs:ecs:cn-shanghai:133160284996****:instance/i-abcdef\",\"level\":\"WARN\",\"instanceName\":\"instanceName\",\"regionId\":\"cn-beijing\",\"name\":\"Instance:PreemptibleInstanceInterruption\",\"content\": {\"instanceId\":\"i-abcdef****\",\"action\":\"delete\"},\"status\":\"Normal\"}");
            // 未打印返回结果,如有需要您可以自行打印。
            client.sendDryRunSystemEvent(sendDryRunSystemEventRequest);
        }
    }
  6. 在队列中接收模拟事件的消息。

    接收消息的代码样例,请参见步骤四:接收和删除消息