全部产品
存储与CDN 数据库 安全 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 开发者工具 解决方案 物联网 钉钉智能硬件
云服务器 ECS

使用 OpenAPI 管理竞价实例

更新时间:2017-12-07 23:04:28

本文介绍了如何使用阿里云 ECS SDK 合理快速地创建并管理竞价实例。

准备工作

在执行操作之前,您需要:

  • 了解能满足您业务要求的实例规格和地域。
  • 熟悉了解阿里云 ECS SDK 的基础知识和调用方法。详细信息,请参考 SDK 使用说明

    注意
    竞价实例代码需要依赖的 ECS SDK 版本 4.2.0 以上。以 Java POM 依赖为例,修改引入 pom 依赖:

    1. <dependency>
    2. <groupId>com.aliyun</groupId>
    3. <artifactId>aliyun-java-sdk-core</artifactId>
    4. <version>3.2.8</version>
    5. </dependency>
    6. <dependency>
    7. <groupId>com.aliyun</groupId>
    8. <artifactId>aliyun-java-sdk-ecs</artifactId>
    9. <version>4.2.0</version>
    10. </dependency>

查询地域及可用的实例规格

使用 OpenAPI DescribeZones 查询可以创建竞价实例的地域以及可用的实例规格。示例代码如下所示。

  • OpenApiCaller.java

    1. public class OpenApiCaller {
    2. IClientProfile profile;
    3. IAcsClient client;
    4. public OpenApiCaller() {
    5. profile = DefaultProfile.getProfile("cn-hangzhou", AKSUtil.accessKeyId, AKSUtil.accessKeySecret);
    6. client = new DefaultAcsClient(profile);
    7. }
    8. public <T extends AcsResponse> T doAction(AcsRequest<T> var1) {
    9. try {
    10. return client.getAcsResponse(var1);
    11. } catch (Throwable e) {
    12. e.printStackTrace();
    13. return null;
    14. }
    15. }
  • DescribeZonesSample.java

    1. public class DescribeZonesSample {
    2. public static void main(String[] args) {
    3. OpenApiCaller caller = new OpenApiCaller();
    4. DescribeZonesRequest request = new DescribeZonesRequest();
    5. request.setRegionId("cn-zhangjiakou");//可以通过 DescribeRegionsRequest 获取每个地域的 RegionId
    6. request.setSpotStrategy("SpotWithPriceLimit");//对于查询是否可购买竞价实例此项必填
    7. request.setInstanceChargeType("PostPaid");//后付费模式,竞价实例必须是后付费模式
    8. DescribeZonesResponse response = caller.doAction(request);
    9. System.out.println(JSON.toJSONString(response));
    10. }
    11. }

    以下为输出结果,可以查看每个地域各个地域可供选择的实例规格、磁盘类型、网络类型等信息。

    1. {
    2. "requestId": "388D6321-E587-470C-8CFA-8985E2963DAE",
    3. "zones": [
    4. {
    5. "localName": "华北 3 可用区 A",
    6. "zoneId": "cn-zhangjiakou-a",
    7. "availableDiskCategories": [
    8. "cloud_ssd",
    9. "cloud_efficiency"
    10. ],
    11. "availableInstanceTypes": [
    12. "ecs.e4.large",
    13. "ecs.n4.4xlarge",
    14. "ecs.sn2.medium",
    15. "ecs.i1.2xlarge",
    16. "ecs.se1.2xlarge",
    17. "ecs.n4.xlarge",
    18. "ecs.se1ne.2xlarge",
    19. "ecs.se1.large",
    20. "ecs.sn2.xlarge",
    21. "ecs.se1ne.xlarge",
    22. "ecs.xn4.small",
    23. "ecs.sn2ne.4xlarge",
    24. "ecs.se1ne.4xlarge",
    25. "ecs.sn1.medium",
    26. "ecs.n4.8xlarge",
    27. "ecs.mn4.large",
    28. "ecs.e4.2xlarge",
    29. "ecs.mn4.2xlarge",
    30. "ecs.mn4.8xlarge",
    31. "ecs.n4.2xlarge",
    32. "ecs.e4.xlarge",
    33. "ecs.sn2ne.large",
    34. "ecs.sn2ne.xlarge",
    35. "ecs.sn1ne.large",
    36. "ecs.n4.large",
    37. "ecs.sn1.3xlarge",
    38. "ecs.e4.4xlarge",
    39. "ecs.sn1ne.2xlarge",
    40. "ecs.e4.small",
    41. "ecs.i1.4xlarge",
    42. "ecs.se1.4xlarge",
    43. "ecs.sn2ne.2xlarge",
    44. "ecs.sn2.3xlarge",
    45. "ecs.i1.xlarge",
    46. "ecs.n4.small",
    47. "ecs.sn1ne.4xlarge",
    48. "ecs.mn4.4xlarge",
    49. "ecs.sn1ne.xlarge",
    50. "ecs.se1ne.large",
    51. "ecs.sn2.large",
    52. "ecs.i1-c5d1.4xlarge",
    53. "ecs.sn1.xlarge",
    54. "ecs.sn1.large",
    55. "ecs.mn4.small",
    56. "ecs.mn4.xlarge",
    57. "ecs.se1.xlarge"
    58. ],
    59. "availableResourceCreation": [
    60. "VSwitch",
    61. "IoOptimized",
    62. "Instance",
    63. "Disk"
    64. ],
    65. "availableResources": [
    66. {
    67. "dataDiskCategories": [
    68. "cloud_ssd",
    69. "cloud_efficiency"
    70. ],
    71. "instanceGenerations": [
    72. "ecs-3",
    73. "ecs-2"
    74. ],
    75. "instanceTypeFamilies": [
    76. "ecs.mn4",
    77. "ecs.sn1",
    78. "ecs.sn2",
    79. "ecs.sn1ne",
    80. "ecs.xn4",
    81. "ecs.i1",
    82. "ecs.se1",
    83. "ecs.e4",
    84. "ecs.n4",
    85. "ecs.se1ne",
    86. "ecs.sn2ne"
    87. ],
    88. "instanceTypes": [
    89. "ecs.n4.4xlarge",
    90. "ecs.sn2.medium",
    91. "ecs.i1.2xlarge",
    92. "ecs.se1.2xlarge",
    93. "ecs.n4.xlarge",
    94. "ecs.se1ne.2xlarge",
    95. "ecs.se1.large",
    96. "ecs.sn2.xlarge",
    97. "ecs.se1ne.xlarge",
    98. "ecs.xn4.small",
    99. "ecs.sn2ne.4xlarge",
    100. "ecs.se1ne.4xlarge",
    101. "ecs.sn1.medium",
    102. "ecs.n4.8xlarge",
    103. "ecs.mn4.large",
    104. "ecs.mn4.2xlarge",
    105. "ecs.mn4.8xlarge",
    106. "ecs.n4.2xlarge",
    107. "ecs.sn2ne.large",
    108. "ecs.sn2ne.xlarge",
    109. "ecs.sn1ne.large",
    110. "ecs.n4.large",
    111. "ecs.sn1.3xlarge",
    112. "ecs.sn1ne.2xlarge",
    113. "ecs.e4.small",
    114. "ecs.i1.4xlarge",
    115. "ecs.se1.4xlarge",
    116. "ecs.sn2ne.2xlarge",
    117. "ecs.sn2.3xlarge",
    118. "ecs.i1.xlarge",
    119. "ecs.n4.small",
    120. "ecs.sn1ne.4xlarge",
    121. "ecs.mn4.4xlarge",
    122. "ecs.sn1ne.xlarge",
    123. "ecs.se1ne.large",
    124. "ecs.sn2.large",
    125. "ecs.i1-c5d1.4xlarge",
    126. "ecs.sn1.xlarge",
    127. "ecs.sn1.large",
    128. "ecs.mn4.small",
    129. "ecs.mn4.xlarge",
    130. "ecs.se1.xlarge"
    131. ],
    132. "ioOptimized": true,
    133. "networkTypes": [
    134. "vpc"
    135. ],
    136. "systemDiskCategories": [
    137. "cloud_ssd",
    138. "cloud_efficiency"
    139. ]
    140. }
    141. ],
    142. "availableVolumeCategories": [
    143. "san_ssd",
    144. "san_efficiency"
    145. ]
    146. }
    147. ]
    148. }

查询竞价实例的历史价格

使用 OpenAPI DescribeSpotPriceHistory 查询竞价实例最近 30 天的价格变化数据,获得最佳性价比的地域和规格信息,示例代码(DescribeSpotPriceHistorySample.java)如下。

  1. public class DescribeSpotPriceHistorySample {
  2. public static void main(String[] args) {
  3. OpenApiCaller caller = new OpenApiCaller();
  4. List<DescribeSpotPriceHistoryResponse.SpotPriceType> result = new ArrayList<DescribeSpotPriceHistoryResponse.SpotPriceType>();
  5. int offset = 0;
  6. while (true) {
  7. DescribeSpotPriceHistoryRequest request = new DescribeSpotPriceHistoryRequest();
  8. request.setRegionId("cn-hangzhou");//可以通过 DescribeRegionsRequest 获取可购买的每个地域的 RegionId
  9. request.setZoneId("cn-hangzhou-b");//可用区必填
  10. request.setInstanceType("ecs.sn2.medium");//参考 DescribeZones 返回的实例类型,必填
  11. request.setNetworkType("vpc");//参考 DescribeZones 返回的网络类型,必填
  12. // request.setIoOptimized("optimized");//是否 I/O 优化类型,DescribeZones 返回的 IoOptimized,选填
  13. // request.setStartTime("2017-09-20T08:45:08Z");//价格开始时间,选填,默认 3 天内数据
  14. // request.setEndTime("2017-09-28T08:45:08Z");//价格结束时间,选填
  15. request.setOffset(offset);
  16. DescribeSpotPriceHistoryResponse response = caller.doAction(request);
  17. if (response != null && response.getSpotPrices() != null) {
  18. result.addAll(response.getSpotPrices());
  19. }
  20. if (response.getNextOffset() == null || response.getNextOffset() == 0) {
  21. break;
  22. } else {
  23. offset = response.getNextOffset();
  24. }
  25. }
  26. if (!result.isEmpty()) {
  27. for (DescribeSpotPriceHistoryResponse.SpotPriceType spotPriceType : result) {
  28. System.out.println(spotPriceType.getTimestamp() + "--->spotPrice:" + spotPriceType.getSpotPrice() + "---->originPrice:" + spotPriceType.getOriginPrice());
  29. }
  30. System.out.println(result.size());
  31. } else {
  32. }
  33. }
  34. }

以下为返回结果示例。

  1. 2017-09-26T06:28:55Z--->spotPrice:0.24---->originPrice:1.2
  2. 2017-09-26T14:00:00Z--->spotPrice:0.36---->originPrice:1.2
  3. 2017-09-26T15:00:00Z--->spotPrice:0.24---->originPrice:1.2
  4. 2017-09-27T14:00:00Z--->spotPrice:0.36---->originPrice:1.2
  5. 2017-09-27T15:00:00Z--->spotPrice:0.24---->originPrice:1.2
  6. 2017-09-28T14:00:00Z--->spotPrice:0.36---->originPrice:1.2
  7. 2017-09-28T15:00:00Z--->spotPrice:0.24---->originPrice:1.2
  8. 2017-09-29T06:28:55Z--->spotPrice:0.24---->originPrice:1.2

重复以上步骤,您可以判断出该规格资源在可用区的价格变化趋势和最近价格。

说明
您可以通过平均价格和最高价格来决定是否可以接受购买该竞价实例,也可以通过更加合理的数据模型来分析历史价格数据,随时调整创建资源的规格和可用区,到达最佳性价比。

创建竞价实例

在创建竞价实例之前,您需要完成以下工作:

使用 OpenAPI CreateInstance 创建竞价实例。示例代码(CreateInstaneSample.java)如下。

  1. public class CreateInstaneSample {
  2. public static void main(String[] args) {
  3. OpenApiCaller caller = new OpenApiCaller();
  4. CreateInstanceRequest request = new CreateInstanceRequest();
  5. request.setRegionId("cn-hangzhou");//地域 ID
  6. request.setZoneId("cn-hangzhou-b"); //可用区ID
  7. request.setSecurityGroupId("sg-bp11nhf94ivkdxwb2gd4");//提前创建的安全组 ID
  8. request.setImageId("centos_7_03_64_20G_alibase_20170818.vhd");//建议选择您自己在该地域准备的自定义镜像
  9. request.setVSwitchId("vsw-bp164cyonthfudn9kj5br");//VPC 类型需要交换机 ID
  10. request.setInstanceType("ecs.sn2.medium"); //填入您询价后需要购买的规格
  11. request.setIoOptimized("optimized");//参考 DescirbeZones 返回参数
  12. request.setSystemDiskCategory("cloud_ssd");//参考 DescirbeZones 返回参数,多选一 cloud_ssd, cloud_efficiency, cloud
  13. request.setSystemDiskSize(40);
  14. request.setInstanceChargeType("PostPaid");//竞价实例必须后付费
  15. request.setSpotStrategy("SpotWithPriceLimit");//SpotWithPriceLimit 出价模式,SpotAsPriceGo 不用出价,最高按量付费价格
  16. request.setSpotPriceLimit(0.25F);//SpotWithPriceLimit 出价模式生效,您能接受的最高价格,单位为元每小时,必须高于当前的市场成交价才能成功
  17. CreateInstanceResponse response = caller.doAction(request);
  18. System.out.println(response.getInstanceId());
  19. }
  20. }

回收竞价实例

当竞价实例可能会因为价格因素或者市场供需变化而被强制回收。此时会触发竞价实例的中断。释放前,竞价实例会进入锁定状态,提示实例将会被自动回收。您可以针对实例回收状态自动化处理实例的退出逻辑。

目前,您可以通过以下任一种方式来获取竞价实例的中断锁定状态:

  • 通过 实例元数据 获取。运行以下命令:

    1. curl 'http://100.100.100.200/latest/meta-data/instance/spot/termination-time'

    如果返回为空,说明实例可持续使用。如果返回类似 2015-01-05T18:02:00Z 格式的信息(UTC 时间),说明实例将于这个时间释放。

  • 使用 OpenAPI DescribeInstances,根据返回的 OperationLocks 判断实例是否进入 待回收 状态。代码示例如下(DescribeInstancesSample.java)。

    1. public class DescribeInstancesSample {
    2. public static void main(String[] args) throws InterruptedException {
    3. OpenApiCaller caller = new OpenApiCaller();
    4. JSONArray allInstances = new JSONArray();
    5. allInstances.addAll(Arrays.asList("i-bp18hgfai8ekoqwo0y2n", "i-bp1ecbyds24ij63w146c"));
    6. while (!allInstances.isEmpty()) {
    7. DescribeInstancesRequest request = new DescribeInstancesRequest();
    8. request.setRegionId("cn-hangzhou");
    9. request.setInstanceIds(allInstances.toJSONString());//指定实例 ID,效率最高
    10. DescribeInstancesResponse response = caller.doAction(request);
    11. List<DescribeInstancesResponse.Instance> instanceList = response.getInstances();
    12. if (instanceList != null && !instanceList.isEmpty()) {
    13. for (DescribeInstancesResponse.Instance instance : instanceList) {
    14. System.out.println("result:instance:" + instance.getInstanceId() + ",az:" + instance.getZoneId());
    15. if (instance.getOperationLocks() != null) {
    16. for (DescribeInstancesResponse.Instance.LockReason lockReason : instance.getOperationLocks()) {
    17. System.out.println("instance:" + instance.getInstanceId() + "-->lockReason:" + lockReason.getLockReason() + ",vmStatus:" + instance.getStatus());
    18. if ("Recycling".equals(lockReason.getLockReason())) {
    19. //do your action
    20. System.out.println("spot instance will be recycled immediately, instance id:" + instance.getInstanceId());
    21. allInstances.remove(instance.getInstanceId());
    22. }
    23. }
    24. }
    25. }
    26. System.out.print("try describeInstances again later ...");
    27. Thread.sleep(2 * 60 * 1000);
    28. } else {
    29. break;
    30. }
    31. }
    32. }
    33. }

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

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

其他操作

您还可以启动、停止、释放竞价实例。具体的操作与一般按量付费实例没有区别。可以参考 OpenAPI 文档:

本文导读目录