閱讀898 返回首頁    go 阿裏雲 go 技術社區[雲棲]


阿裏雲競價實例OpenApi入門實踐

阿裏雲競價實例OpenApi入門實踐

目的

本文目標是介紹開發者如何通過阿裏雲ECS SDK,合理快速的創建需要的SPOT競價實例

準備工作:

  • 首先要熟悉了解阿裏雲SDK的基礎知識和調用方法,可以參考SDK 使用說明
  • Spot競價實例代碼需要依賴的ECS SDK版本4.2.0 以上,
  • 以JAVA POM依賴舉例,修改引入pom依賴:
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>3.2.8</version>
</dependency>
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-ecs</artifactId>
    <version>4.2.0</version>
</dependency>

  • 目前競價實例灰度開放部分用戶白名單開放,您可以用您的賬號登陸購買頁麵,確認你的賬號是否具備spot購買權限
  • 建議您提前通過自定義鏡像來保證SOPT實例可以快速開始自己的業務功能。

哪些地域與規格可以購買競價實例:

典型一個場景,我需要創建一批價格便宜量又足的計算資源,做業務數據處理。
但我不知道去哪個地域去創建需要的計算資源。
我們需要規劃下對計算資源的大致需求:
1. 地域,創建的競價實例哪個地域創建。
2. 規格 根據你的業務需求確定什麼樣規格實例

但是由於目前aliyun 每個地域因為售賣比率不同,每個地域可用對外開放售賣的規格存在很大差異。
所以建議通過DesribeZones接口來獲取您的賬戶可創建的地域與規格信息,幫助您選擇地域和規格。


public class OpenApiCaller {
    IClientProfile profile;
    IAcsClient client;

    public OpenApiCaller() {
        profile = DefaultProfile.getProfile("cn-hangzhou", AKSUtil.accessKeyId, AKSUtil.accessKeySecret);
        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;
        }
    }

 }

DescribeZonesSample.java


public class DescribeZonesSample {

    public static void main(String[] args) {

        OpenApiCaller caller = new OpenApiCaller();
        DescribeZonesRequest request = new DescribeZonesRequest();
        request.setRegionId("cn-zhangjiakou");//可以通過DescribeRegionsRequest獲取每個地域的regionId
        request.setSpotStrategy("SpotWithPriceLimit");//對於查詢是否可購買競價實例此項必填
        request.setInstanceChargeType("PostPaid");//後付費模式,競價實例必須是後付費模式
        DescribeZonesResponse response = caller.doAction(request);
        System.out.println(JSON.toJSONString(response));

    }
}

輸出結果:

{
    "requestId": "388D6321-E587-470C-8CFA-8985E2963DAE",
    "zones": [
        {

            "localName": "華北 3 可用區 A",
            "zoneId": "cn-zhangjiakou-a",
            "availableDiskCategories": [
                "cloud_ssd",
                "cloud_efficiency"
            ],
            "availableInstanceTypes": [
                "ecs.e4.large",
                "ecs.n4.4xlarge",
                "ecs.sn2.medium",
                "ecs.i1.2xlarge",
                "ecs.se1.2xlarge",
                "ecs.n4.xlarge",
                "ecs.se1ne.2xlarge",
                "ecs.se1.large",
                "ecs.sn2.xlarge",
                "ecs.se1ne.xlarge",
                "ecs.xn4.small",
                "ecs.sn2ne.4xlarge",
                "ecs.se1ne.4xlarge",
                "ecs.sn1.medium",
                "ecs.n4.8xlarge",
                "ecs.mn4.large",
                "ecs.e4.2xlarge",
                "ecs.mn4.2xlarge",
                "ecs.mn4.8xlarge",
                "ecs.n4.2xlarge",
                "ecs.e4.xlarge",
                "ecs.sn2ne.large",
                "ecs.sn2ne.xlarge",
                "ecs.sn1ne.large",
                "ecs.n4.large",
                "ecs.sn1.3xlarge",
                "ecs.e4.4xlarge",
                "ecs.sn1ne.2xlarge",
                "ecs.e4.small",
                "ecs.i1.4xlarge",
                "ecs.se1.4xlarge",
                "ecs.sn2ne.2xlarge",
                "ecs.sn2.3xlarge",
                "ecs.i1.xlarge",
                "ecs.n4.small",
                "ecs.sn1ne.4xlarge",
                "ecs.mn4.4xlarge",
                "ecs.sn1ne.xlarge",
                "ecs.se1ne.large",
                "ecs.sn2.large",
                "ecs.i1-c5d1.4xlarge",
                "ecs.sn1.xlarge",
                "ecs.sn1.large",
                "ecs.mn4.small",
                "ecs.mn4.xlarge",
                "ecs.se1.xlarge"
            ],
            "availableResourceCreation": [
                "VSwitch",
                "IoOptimized",
                "Instance",
                "Disk"
            ],
            "availableResources": [
                {
                    "dataDiskCategories": [
                        "cloud_ssd",
                        "cloud_efficiency"
                    ],
                    "instanceGenerations": [
                        "ecs-3",
                        "ecs-2"
                    ],
                    "instanceTypeFamilies": [
                        "ecs.mn4",
                        "ecs.sn1",
                        "ecs.sn2",
                        "ecs.sn1ne",
                        "ecs.xn4",
                        "ecs.i1",
                        "ecs.se1",
                        "ecs.e4",
                        "ecs.n4",
                        "ecs.se1ne",
                        "ecs.sn2ne"
                    ],
                    "instanceTypes": [
                        "ecs.n4.4xlarge",
                        "ecs.sn2.medium",
                        "ecs.i1.2xlarge",
                        "ecs.se1.2xlarge",
                        "ecs.n4.xlarge",
                        "ecs.se1ne.2xlarge",
                        "ecs.se1.large",
                        "ecs.sn2.xlarge",
                        "ecs.se1ne.xlarge",
                        "ecs.xn4.small",
                        "ecs.sn2ne.4xlarge",
                        "ecs.se1ne.4xlarge",
                        "ecs.sn1.medium",
                        "ecs.n4.8xlarge",
                        "ecs.mn4.large",
                        "ecs.mn4.2xlarge",
                        "ecs.mn4.8xlarge",
                        "ecs.n4.2xlarge",
                        "ecs.sn2ne.large",
                        "ecs.sn2ne.xlarge",
                        "ecs.sn1ne.large",
                        "ecs.n4.large",
                        "ecs.sn1.3xlarge",
                        "ecs.sn1ne.2xlarge",
                        "ecs.e4.small",
                        "ecs.i1.4xlarge",
                        "ecs.se1.4xlarge",
                        "ecs.sn2ne.2xlarge",
                        "ecs.sn2.3xlarge",
                        "ecs.i1.xlarge",
                        "ecs.n4.small",
                        "ecs.sn1ne.4xlarge",
                        "ecs.mn4.4xlarge",
                        "ecs.sn1ne.xlarge",
                        "ecs.se1ne.large",
                        "ecs.sn2.large",
                        "ecs.i1-c5d1.4xlarge",
                        "ecs.sn1.xlarge",
                        "ecs.sn1.large",
                        "ecs.mn4.small",
                        "ecs.mn4.xlarge",
                        "ecs.se1.xlarge"
                    ],
                    "ioOptimized": true,
                    "networkTypes": [
                        "vpc"
                    ],
                    "systemDiskCategories": [
                        "cloud_ssd",
                        "cloud_efficiency"
                    ]
                }
            ],
            "availableVolumeCategories": [
                "san_ssd",
                "san_efficiency"
            ]
        }
    ]
}

通過查詢spot曆史價格接口來獲得最佳性價比的地域,規格信息

通過上一步我們可以基本確定哪個可用區可以生產的哪些具體規格,有了這些信息就可以通過
DescribeSpotPriceHistory接口查詢獲取價格曆史變化,最多允許獲取30天內的價格變化數據。


public class DescribeSpotPriceHistorySample {

    public static void main(String[] args) {

        OpenApiCaller caller = new OpenApiCaller();
        List<DescribeSpotPriceHistoryResponse.SpotPriceType> result = new ArrayList<DescribeSpotPriceHistoryResponse.SpotPriceType>();
        int offset = 0;
        while (true) {
            DescribeSpotPriceHistoryRequest request = new DescribeSpotPriceHistoryRequest();
            request.setRegionId("cn-hangzhou");//可以通過DescribeRegionsRequest獲取可購買的每個地域的regionId
            request.setZoneId("cn-hangzhou-b");//可用區必填
            request.setInstanceType("ecs.sn2.medium");//參考DescribeZones 返回的實例類型,必填
            request.setNetworkType("vpc");//參考DescribeZones 返回的網絡類型,必填
//            request.setIoOptimized("optimized");//是否Io優化類型,DescribeZones 返回的IoOptimized,選填
//            request.setStartTime("2017-09-20T08:45:08Z");//價格開始時間,選填,默認3天內數據
//            request.setEndTime("2017-09-28T08:45:08Z");//價格結束時間,選填
            request.setOffset(offset);
            DescribeSpotPriceHistoryResponse response = caller.doAction(request);
            if (response != null && response.getSpotPrices() != null) {
                result.addAll(response.getSpotPrices());
            }
            if (response.getNextOffset() == null || response.getNextOffset() == 0) {
                break;
            } else {
                offset = response.getNextOffset();
            }
        }
        if (!result.isEmpty()) {
            for (DescribeSpotPriceHistoryResponse.SpotPriceType spotPriceType : result) {
                System.out.println(spotPriceType.getTimestamp() + "--->spotPrice:" + spotPriceType.getSpotPrice() + "---->originPrice:" + spotPriceType.getOriginPrice());
            }
            System.out.println(result.size());
        } else {
        }

    }

}


  • 返回結果
2017-09-26T06:28:55Z--->spotPrice:0.24---->originPrice:1.2
2017-09-26T14:00:00Z--->spotPrice:0.36---->originPrice:1.2
2017-09-26T15:00:00Z--->spotPrice:0.24---->originPrice:1.2
2017-09-27T14:00:00Z--->spotPrice:0.36---->originPrice:1.2
2017-09-27T15:00:00Z--->spotPrice:0.24---->originPrice:1.2
2017-09-28T14:00:00Z--->spotPrice:0.36---->originPrice:1.2
2017-09-28T15:00:00Z--->spotPrice:0.24---->originPrice:1.2
2017-09-29T06:28:55Z--->spotPrice:0.24---->originPrice:1.2

  • 重複以上步驟,您可以判斷出該規格資源在可用區的價格變化趨勢和最近價格。
  • 簡單的策略通過平均價格和最高價格來決定是否可以接受購買該spot實例。
  • 當然從最小成本出發,可以通過更加合理的數據模型來分析價曆史價格數據,隨時調整創建資源的規格和可用區,到達最佳性價比。

創建Spot實例

通過以上過程,我們最終得到可以創建的資源的地域信息,規格屬性,磁盤,網絡等信息。
現在就可以開始真正創建競價實例了。

  • API名稱:CreateInstance
  • 建議您提前在控製台或者openapi方式 在需要創建vm資源的地區創建好vpc專有網絡,獲取創建參數vswitchId
  • 建議您提前在控製台或者openapi方式 在需要創建vm資源的地區創建安全組,獲取創建參數:SecurityGroupId

  • 接口文檔:https://help.aliyun.com/document_detail/25499.html

  • 示例代碼:CreateInstaneSample.java

public class CreateInstaneSample {


    public static void main(String[] args) {
        OpenApiCaller caller = new OpenApiCaller();
        CreateInstanceRequest request = new CreateInstanceRequest();
        request.setRegionId("cn-hangzhou");//地域Id
        request.setZoneId("cn-hangzhou-b"); //可用區Id
        request.setSecurityGroupId("sg-bp11nhf94ivkdxwb2gd4");//提前創建的安全組Id
        request.setImageId("centos_7_03_64_20G_alibase_20170818.vhd");//建議選擇您自己在該地域準備的自定義鏡像
        request.setVSwitchId("vsw-bp164cyonthfudn9kj5br");//vpc 類型需要虛擬路由Id

        request.setInstanceType("ecs.sn2.medium"); //填入您詢價後需要購買的規格
        request.setIoOptimized("optimized");//參考 DescirbeZones返回參數
        request.setSystemDiskCategory("cloud_ssd");//參考 DescirbeZones返回參數,多選一 cloud_ssd,cloud_efficiency,cloud
        request.setSystemDiskSize(40);

        request.setInstanceChargeType("PostPaid");//競價實例必須後付費
        request.setSpotStrategy("SpotWithPriceLimit");//SpotWithPriceLimit出價模式,SpotAsPriceGo不用出價,最高按量付費價格
        request.setSpotPriceLimit(0.25F);//SpotWithPriceLimit出價模式生效,用戶您能接受的最高價格,單元元每小時,必須高於當前的公共價格才能成功

        CreateInstanceResponse response = caller.doAction(request);
        System.out.println(response.getInstanceId());

    }
}

spot實例中斷

  • 競價實例可能會因為價格因素或者其他ecs內部庫存因素會強製回收競價資源,此時會觸發spot的中斷
  • 在真正開始釋放vm前 vm 會進入鎖定狀態, 提示vm 將會被自動回收,您可以針對vm 回收狀態來自動化處理實例的退出邏輯
  • 目前spot的中斷鎖定狀態可以通過2種方式來感知
  • vpc 實例可以通過metadata 來獲取

  • metadata訪問示例:

curl 'https://100.100.100.200/latest/meta-data/instance/spot/termination-time'
返回格式示例:2015-01-05T18:02:00Z,時間為UTC時間,如果返回為空,說明可持續使用

  1. 通過查詢 describeInstances 返回的OperationLocks 感知是否vm進入準備回收狀態
  • openapi獲取鎖定狀態代碼示例:DescribeInstancesSample.java
public class DescribeInstancesSample {

    public static void main(String[] args) throws InterruptedException {
        OpenApiCaller caller = new OpenApiCaller();
        JSONArray allInstances = new JSONArray();
        allInstances.addAll(Arrays.asList("i-bp18hgfai8ekoqwo0y2n", "i-bp1ecbyds24ij63w146c"));
        while (!allInstances.isEmpty()) {
            DescribeInstancesRequest request = new DescribeInstancesRequest();
            request.setRegionId("cn-hangzhou");
            request.setInstanceIds(allInstances.toJSONString());//指定實例Id,效率最高
            DescribeInstancesResponse response = caller.doAction(request);
            List<DescribeInstancesResponse.Instance> instanceList = response.getInstances();
            if (instanceList != null && !instanceList.isEmpty()) {
                for (DescribeInstancesResponse.Instance instance : instanceList) {
                    System.out.println("result:instance:" + instance.getInstanceId() + ",az:" + instance.getZoneId());
                    if (instance.getOperationLocks() != null) {
                        for (DescribeInstancesResponse.Instance.LockReason lockReason : instance.getOperationLocks()) {
                            System.out.println("instance:" + instance.getInstanceId() + "-->lockReason:" + lockReason.getLockReason() + ",vmStatus:" + instance.getStatus());
                            if ("Recycling".equals(lockReason.getLockReason())) {
                                //do your action
                                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;
            }
        }

    }
}

觸發回收時輸出結果:

instance:i-bp1ecbyds24ij63w146c-->lockReason:Recycling,vmStatus:Stopped
spot instance will be recycled immediately, instance id:i-bp1ecbyds24ij63w146c

啟動,關機,釋放 SPOT競價實例

啟動,停止,釋放實例Spot 實例和其他實例沒有任何區別,本文不再介紹,請參看相關api文檔即可。

最後更新:2017-10-19 15:33:23

  上一篇:go  Nature重磅:人工智能從0到1, 無師自通完爆阿法狗100-0 | 深度解析
  下一篇:go  【沉澱】實例遷移、Insert和寫入性能——數倍,甚至數十倍提升,HybridDB for MySQL負責人王騫談自己經曆和收獲