阿里云抢占实例OpenApi入门实践

本文涉及的产品
云服务器 ECS,每月免费额度280元 3个月
云服务器ECS,u1 2核4GB 1个月
简介: 本文目标是介绍开发者如何通过阿里云ECS SDK,合理快速的创建需要的SPOT竞价实例

阿里云竞价实例OpenApi入门实践

目的

本文目标是介绍开发者如何通过阿里云ECS SDK,合理快速的创建需要的抢占实例

准备工作:

  • 首先要熟悉了解阿里云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>



## 哪些地域与规格可以购买竞价实例:

> 典型一个场景,我需要创建一批价格便宜量又足的计算资源,做业务数据处理。
但我不知道去哪个地域去创建需要的计算资源。
我们需要规划下对计算资源的大致需求:
1. 地域,创建的竞价实例哪个地域创建。
2. 规格  根据你的业务需求确定什么样规格实例

> 但是由于目前aliyun 每个地域因为售卖比率不同,每个地域可用对外开放售卖的规格存在很大差异。
所以建议通过DesribeZones接口来获取您的账户可创建的地域与规格信息,帮助您选择地域和规格。
* API名称: DesribeZones
* API说明:https://help.aliyun.com/document_detail/25610.html
* 代码示例:

>  OpenApiCaller.java

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天内的价格变化数据。
* API名称:DescribeSpotPriceHistory
* API文档:https://help.aliyun.com/document_detail/60400.html
* 代码实例:DescribeSpotPriceHistorySample.java

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种方式来感知
1.  vpc 实例可以通过metadata 来获取

* metadata访问示例:

curl 'http://100.100.100.200/latest/meta-data/instance/spot/termination-time'
返回格式示例:2015-01-05T18:02:00Z,时间为UTC时间,如果返回为空,说明可持续使用


2.  通过查询 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文档即可。

相关实践学习
一小时快速掌握 SQL 语法
本实验带您学习SQL的基础语法,快速入门SQL。
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情:&nbsp;https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
存储 分布式计算 网络协议
阿里云服务器内存型r7、r8a、r8y实例区别参考
在阿里云目前的活动中,属于内存型实例规格的云服务器有内存型r7、内存型r8a、内存型r8y这几个实例规格,相比于活动内的经济型e、通用算力型u1实例来说,这些实例规格等性能更强,与计算型和通用型相比,它的内存更大,因此这些内存型实例规格主要适用于数据库、中间件和数据分析与挖掘,Hadoop、Spark集群等场景,本文为大家介绍内存型r7、r8a、r8y实例区别及最新活动价格,以供参考。
阿里云服务器内存型r7、r8a、r8y实例区别参考
|
27天前
|
缓存 编解码 弹性计算
阿里云服务器e/u1/c7/c7a/c8a/c8y/g7/g7a/g8a/g8ae实例适用场景汇总
目前阿里云活动购买云服务器时,除了轻量应用服务器之外,活动内的云服务器实例规格主要以e/u1/c7/c7a/c8a/c8y/g7/g7a/g8a/g8ae这几种为主,本文主要为大家介绍了阿里云服务器的实例规格是什么,有什么用?并汇总了阿里云轻量应用服务器和阿里云服务器e/u1/c7/c7a/c8a/c8y/g7/g7a/g8a/g8ae实例规格适用场景,以供大家了解和选择适合自己的需求的实例规格。
阿里云服务器e/u1/c7/c7a/c8a/c8y/g7/g7a/g8a/g8ae实例适用场景汇总
|
26天前
|
SQL 存储 API
阿里云实时计算Flink的产品化思考与实践【下】
本文整理自阿里云高级产品专家黄鹏程和阿里云技术专家陈婧敏在 FFA 2023 平台建设专场中的分享。
110573 56
阿里云实时计算Flink的产品化思考与实践【下】
|
1天前
|
存储 开发工具 对象存储
Javaweb之SpringBootWeb案例之阿里云OSS服务入门的详细解析
Javaweb之SpringBootWeb案例之阿里云OSS服务入门的详细解析
6 0
|
存储 弹性计算 网络协议
阿里云服务器经济型e、通用算力型u1与c7/g7/r7/c8y/g8y/r8y实例区别及选择参考
在阿里云目前的各个活动中,除了轻量应用服务器之外,活动内的云服务器实例规格主要以经济型e、通用算力型u1、计算型c7/c8y、通用型g7/g8y、内存型r7/r8y这几个实例规格为主,c7/c8y属于计算型实例,g7/g8y属于通用型实例,c7/r8y属于内存型实例,c7/g7/r7属于最新第七代云服务器实例,c8y/g8y/r8y属于倚天云服务器实例,不同的云服务器实例规格在性能、特点及适用场景上有所不同,本文大家介绍一下阿里云服务器经济型e、通用算力型u1与c7/g7/r7/c8y/g8y/r8y的区别,以供参考。
阿里云服务器经济型e、通用算力型u1与c7/g7/r7/c8y/g8y/r8y实例区别及选择参考
|
13天前
|
弹性计算 安全
电子好书发您分享《阿里云第八代企业级ECS实例,为企业提供更安全的云上防护》
阿里云第八代ECS实例,搭载第五代英特尔至强处理器与飞天+CIPU架构,提升企业云服务安全与算力。[阅读详情](https://developer.aliyun.com/ebook/8303/116162?spm=a2c6h.26392459.ebook-detail.5.76bf7e5al1Zn4U) ![image](https://ucc.alicdn.com/pic/developer-ecology/cok6a6su42rzm_f422f7cb775444bbbfc3e61ad86800c2.png)
35 14
|
15天前
|
存储 缓存 Java
阿里云OSS实战从入门到大神
说起阿里云OSS,那作用和功能都是非常强大的,它可以存放图片,音频,视频等资源文件,这些资源文件,你不必存放到服务器的硬盘里,这样既可以节省服务器硬盘空间,又可以降低服务器的读写压力,非常适合大并发的架构。
54 0
|
23天前
|
存储 缓存 PHP
阿里云服务器实例、CPU内存、带宽、操作系统选择参考
对于使用阿里云服务器的用户来说,云服务器的选择和使用非常重要,如果实例、内存、CPU、带宽等配置选择错误,可能会影响到自己业务在云服务器上的计算性能及后期运营状况,本文为大家介绍一下阿里云服务器实例、CPU内存、带宽、操作系统的选择注意事项,以供参考。
阿里云服务器实例、CPU内存、带宽、操作系统选择参考
|
27天前
|
存储 对象存储 容器
阿里云OSS对象存储基础入门
阿里云OSS对象存储基础入门
88 0
|
29天前
|
缓存 编解码 前端开发
2024年阿里云服务器经济型e、通用算力型u1及计算型、通用型实例适用场景参考
目前阿里云的活动中提供了多种云服务器实例规格,包括经济型e、通用算力型u1、计算型c7/a系列和通用型g7/a系列等,适用于不同场景。实例规格定义了CPU、内存等配置,影响计算和存储能力。本文主要为大家介绍了阿里云服务器的实例规格是什么,并汇总了阿里云轻量应用服务器和阿里云服务器e/u1/c7/c7a/c8a/c8y/g7/g7a/g8a/g8ae实例规格适用场景,以供参考。
2024年阿里云服务器经济型e、通用算力型u1及计算型、通用型实例适用场景参考

热门文章

最新文章