全部產品
Search
文件中心

Elastic Compute Service:查詢搶佔式執行個體中斷事件

更新時間:Feb 28, 2024

搶佔式執行個體可能會因為價格因素或者市場供需變化而被強制回收,此時會觸發搶佔式執行個體的中斷。搶佔式執行個體被回收前會進入鎖定狀態,系統會提示您執行個體將會被自動回收。本文介紹如何查詢搶佔式執行個體是否被中斷。

方式一:通過CloudMonitorSDK查詢

以CloudMonitorJava SDK為例,介紹如何查詢搶佔式執行個體中斷事件。

  1. 接入CloudMonitorSDK。

    具體操作,請參見SDK參考

  2. 通過SDK查詢系統事件。

    範例程式碼如下所示:

    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.IAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.exceptions.ServerException;
    import com.aliyuncs.profile.DefaultProfile;
    import com.google.gson.Gson;
    import java.util.*;
    import com.aliyuncs.cms.model.v20190101.*;
    
    public class DescribeSystemEventAttribute {
        public static void main(String[] args) {
            // 初始化DefaultAcsClient執行個體。
            // 請確保代碼運行環境設定了環境變數ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
            // 工程代碼泄露可能會導致AccessKey泄露,並威脅帳號下所有資源的安全性。以下程式碼範例使用環境變數擷取AccessKey的方式進行調用,建議使用更安全的STS方式。
            DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
            IAcsClient client = new DefaultAcsClient(profile);
    
            // 查詢搶佔式執行個體中斷事件。
            DescribeSystemEventAttributeRequest request = new DescribeSystemEventAttributeRequest();
            request.setRegionId("cn-hangzhou");
            request.setProduct("ECS");
            request.setEventType("StatusNotification");
            request.setName("Instance:PreemptibleInstanceInterruption");
            try {
                // 接收響應結果。
                DescribeSystemEventAttributeResponse response = client.getAcsResponse(request);
                System.out.println(new Gson().toJson(response));
            } catch (ServerException e) {
                e.printStackTrace();
            } catch (ClientException e) {
                System.out.println("ErrCode:" + e.getErrCode());
                System.out.println("ErrMsg:" + e.getErrMsg());
                System.out.println("RequestId:" + e.getRequestId());
            }
        }
    }
  3. 根據返回結果判斷搶佔式執行個體中斷事件。

    事件通知的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

方式二:通過中繼資料在執行個體內部查詢

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
  • 如果返回404:執行個體可持續使用。

  • 如果返回類似2015-01-05T18:02:00Z格式的資訊(UTC時間):執行個體將於這個時間被回收。

方式三:通過API查詢

調用DescribeInstances,並根據返回的OperationLocks判斷執行個體是否進入待回收狀態。

  • 若返回空值:執行個體可持續使用。

  • 若返回LockReason值為Recycling:搶佔式執行個體被中斷,處於待回收狀態。

程式碼範例(DescribeInstancesSample.java)如下所示:

import com.alibaba.fastjson.JSONArray;
import com.aliyuncs.AcsRequest;
import com.aliyuncs.AcsResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.ecs.model.v20140526.DescribeInstancesRequest;
import com.aliyuncs.ecs.model.v20140526.DescribeInstancesResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import java.util.*;

public class DescribeInstancesSample {
    public static void main(String[] args) throws InterruptedException {
        // 初始化DefaultAcsClient執行個體。
        OpenApiCaller caller = new OpenApiCaller();
        // 設定待查詢的一個或多個ECS執行個體ID。
        JSONArray allInstances = new JSONArray();
        allInstances.addAll(Arrays.asList("i-bp1i9c3qiv1qs6nc****"));
        while (!allInstances.isEmpty()) {
            DescribeInstancesRequest request = new DescribeInstancesRequest();
            // 指定執行個體所在的地區。
            request.setRegionId("cn-hangzhou");
            // 指定執行個體ID,查詢效率高。
            request.setInstanceIds(allInstances.toJSONString());
            // 接收響應結果。
            DescribeInstancesResponse response = caller.doAction(request);
            // 擷取執行個體相關的返回結果。
            List<DescribeInstancesResponse.Instance> instanceList = response.getInstances();
            if (instanceList != null && !instanceList.isEmpty()) {
                for (DescribeInstancesResponse.Instance instance : instanceList) {
                    // 輸出被查詢的執行個體ID與可用性區域資訊。
                    System.out.println("result:instance:" + instance.getInstanceId() + ",az:" + instance.getZoneId());
                    if (instance.getOperationLocks() != null) {
                        for (DescribeInstancesResponse.Instance.LockReason lockReason : instance.getOperationLocks()) {
                            // 如果執行個體被鎖定,輸出指定執行個體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());
                                allInstances.remove(instance.getInstanceId());
                            }
                        }
                    }
                }
                // 如果搶佔式執行個體還未被鎖定,將每隔兩分鐘查詢一次。
                System.out.print("try describeInstances again later ...");
                Thread.sleep(2 * 60 * 1000);
            } else {
                break;
            }
        }
    }
}

// 初始化DefaultAcsClient執行個體的類。
class OpenApiCaller{
    IClientProfile profile;
    IAcsClient client;
    public OpenApiCaller() {
        // 請確保代碼運行環境設定了環境變數ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
        // 工程代碼泄露可能會導致AccessKey泄露,並威脅帳號下所有資源的安全性。以下程式碼範例使用環境變數擷取AccessKey的方式進行調用,建議使用更安全的STS方式。
        profile = DefaultProfile.getProfile("cn-hangzhou", System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        client = new DefaultAcsClient(profile);
    }

    public  <T extends AcsResponse> T doAction(AcsRequest<T> var1) {
        try {
            return  client.getAcsResponse(var1);
        } catch (Throwable e) {
            e.printStackTrace();
            return null;
        }
    }
}

觸發回收時輸出結果如下:

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****