进阶玩法:针对ECS新购选型场景查询可用资源


  • 接口名称(查询某一可用区的资源列表)

DescribeAvailableResource

  • 背景:

选购云服务ECS时,在指定条件下有哪些资源是可用的?如何更好的选择所需的资源?针对用户的ECS购买选型,介绍如何利用DescribeAvailableResource接口查询可用资源

  • 针对选型场景做相应的查询

场景1. 用户在杭州地域下,包年包月(包含按周)ecs实例可以售卖实例规格列表
场景2. 用户在杭州地域下,按量ecs实例可以售卖实例规格列表
场景3. 用户在杭州地域下,Spot实例可以售卖实例规格列表
场景4. 用户选购包年包月ecs.gn4.8xlarge规格的实例,在杭州地域下那个可用区可售卖
场景5. 用户在杭州可用区E下,带vpc网络包年包月实例可以售卖实例规格列表

除了您现在看到的这文章,您还可以前往:

DescribeAvailableResource接口文档
查询ECS可用的资源接口实践

aliyun-java-sdk-ecs版本在4.6.3及以上。


接口要点概述

您可以通过DescribeAvailableResource指定不同目标资源( DestinationResource )查询不同类型的资源列表,再指定其他条件细化资源条件。目标资源( DestinationResource) 的各个可选取值有不同的逻辑与(&&)要求。在下列顺序列表中,排在越后面的参数其逻辑与(&&)苛刻程度越高。
顺序:(Zone)> IoOptimized > InstanceType > SystemDisk > DataDisk
取值示例:
若参数 DestinationResource 取值为 SystemDisk,则必须传入参数 IoOptimized 和 InstanceType。
若参数 DestinationResource 取值为 InstanceType,则必须传入参数 IoOptimized。
若参数 DestinationResource 取值为 DataDisk,则必须传入参数 IoOptimized、InstanceType 和 SystemDiskCategory。

使用场景事例

事例使用的公共方法在后面给出。

场景1. 用户在杭州地域下,包年包月(包含按周)ecs实例可以售卖实例规格列表

    /**
     *  场景1. 用户在杭州地域下,包年包月(包含按周)ecs实例可以售卖实例规格列表
     *  目标地域 : cn-hangzhou
     *  任意可用区中: zoneId不传
     *  包年包月(包含按周):InstanceChargeType PrePaid
     *       SpotStrategy 不传或者NoSpot
     *
     *  说明 : 若参数 DestinationResource 取值为 InstanceType,则必须传入参数 IoOptimized
     *  步骤
     *  1.查询可用io优化资源
     *  2.查询可用实例规格资源
     *  返回结果:
     *     按ZoneId返回实例规格资源列表
     *     没有可用实例规格资源,返回null或者空Map
     */
    public Map<String,Set<String>> doDescribeScene1() {
        DescribeAvailableResourceRequest describe = new DescribeAvailableResourceRequest();
        describe.setRegionId("cn-hangzhou");
        describe.setInstanceChargeType("PrePaid");
        // 1.查询可用io优化资源
        describe.setDestinationResource(IOOPTIMIED);
        Map<String, Set<String>> ioOptimizeds = doActionAndProcessResponse(describe);
        if (null == ioOptimizeds) {
            // 没有io优化资源,查询不到对应的规格资源
            return null;
        }
        //实例规格资源列表 allTypes
        // key: zoneId,  values:实例规格列表
        Map<String,Set<String>> allTypes = new HashMap<String, Set<String>>();
        for (String zoneId : ioOptimizeds.keySet()) {
            describe.setZoneId(zoneId);
            describe.setDestinationResource(INSTANCETYPE);
            for(String iopts : ioOptimizeds.get(zoneId)){
                describe.setIoOptimized(iopts);
            }

            Set<String> allTypesInZoneId = allTypes.get(zoneId);
            Map<String, Set<String>> types = doActionAndProcessResponse(describe);
            Set<String> typesInZoneId = types.get(zoneId);
            if(null != allTypesInZoneId){
                allTypesInZoneId.addAll(typesInZoneId);
            }else{
                allTypes.put(zoneId, typesInZoneId);
            }
        }

        return allTypes;
    }

场景2. 用户在杭州地域下,按量ecs实例可以售卖实例规格列表

   /**
     *  场景2. 用户在杭州地域下,按量ecs实例可以售卖实例规格列表
     *  目标地域 : cn-hangzhou
     *  任意可用区中: zoneId不传
     *  包年包月(包含按周):InstanceChargeType 不传或者PostPaid
     *       SpotStrategy 不传或者NoSpot
     *
     *  说明 : 若参数 DestinationResource 取值为 InstanceType,则必须传入参数 IoOptimized
     *  步骤
     *  1.查询可用io优化资源
     *  2.查询可用实例规格资源
     *  返回结果:
     *     按ZoneId返回实例规格资源列表
     *     没有可用实例规格资源,返回null或者空Map
     */
    public Map<String,Set<String>> doDescribeScene2() {
        DescribeAvailableResourceRequest describe = new DescribeAvailableResourceRequest();
        describe.setRegionId("cn-hangzhou");
        describe.setInstanceChargeType("PostPaid");
        // 1.查询可用io优化资源
        describe.setDestinationResource(IOOPTIMIED);
        Map<String, Set<String>> ioOptimizeds = doActionAndProcessResponse(describe);
        if (null == ioOptimizeds) {
            // 没有io优化资源,查询不到对应的规格资源
            return null;
        }
        //实例规格资源列表 allTypes
        // key: zoneId,  values:实例规格列表
        Map<String,Set<String>> allTypes = new HashMap<String, Set<String>>();
        for (String zoneId : ioOptimizeds.keySet()) {
            describe.setZoneId(zoneId);
            describe.setDestinationResource(INSTANCETYPE);
            for(String iopts : ioOptimizeds.get(zoneId)){
                describe.setIoOptimized(iopts);
            }

            Set<String> allTypesInZoneId = allTypes.get(zoneId);
            Map<String, Set<String>> types = doActionAndProcessResponse(describe);
            Set<String> typesInZoneId = types.get(zoneId);
            if(null != allTypesInZoneId){
                allTypesInZoneId.addAll(typesInZoneId);
            }else{
                allTypes.put(zoneId, typesInZoneId);
            }
        }

        return allTypes;
    }

场景3. 用户在杭州地域下,Spot实例可以售卖实例规格列表

    /**
     *  场景3. 用户在杭州地域下,Spot实例可以售卖实例规格列表
     *  目标地域 : cn-hangzhou
     *  任意可用区中: zoneId不传
     *  包年包月(包含按周):InstanceChargeType 不传或者PostPaid
     *       SpotStrategy 传SpotWithPriceLimit 或者 SpotAsPriceGo
     *
     *  说明 : 若参数 DestinationResource 取值为 InstanceType,则必须传入参数 IoOptimized
     *  步骤
     *  1.查询可用io优化资源
     *  2.查询可用实例规格资源
     *  返回结果:
     *     按ZoneId返回实例规格资源列表
     *     没有可用实例规格资源,返回null或者空Map
     */
    public Map<String,Set<String>> doDescribeScene3() {
        DescribeAvailableResourceRequest describe = new DescribeAvailableResourceRequest();
        describe.setRegionId("cn-hangzhou");
        describe.setInstanceChargeType("PostPaid");
        describe.setSpotStrategy("SpotWithPriceLimit");   //describe.setSpotStrategy("SpotAsPriceGo");
        // 1.查询可用io优化资源
        describe.setDestinationResource(IOOPTIMIED);
        Map<String, Set<String>> ioOptimizeds = doActionAndProcessResponse(describe);
        if (null == ioOptimizeds) {
            // 没有io优化资源,查询不到对应的规格资源
            return null;
        }
        //实例规格资源列表 allTypes
        // key: zoneId,  values:实例规格列表
        Map<String,Set<String>> allTypes = new HashMap<String, Set<String>>();
        for (String zoneId : ioOptimizeds.keySet()) {
            describe.setZoneId(zoneId);
            describe.setDestinationResource(INSTANCETYPE);
            for(String iopts : ioOptimizeds.get(zoneId)){
                describe.setIoOptimized(iopts);
            }

            Set<String> allTypesInZoneId = allTypes.get(zoneId);
            Map<String, Set<String>> types = doActionAndProcessResponse(describe);
            Set<String> typesInZoneId = types.get(zoneId);
            if(null != allTypesInZoneId){
                allTypesInZoneId.addAll(typesInZoneId);
            }else{
                allTypes.put(zoneId, typesInZoneId);
            }
        }

        return allTypes;
    }

场景4. 用户选购包年包月ecs.gn4.8xlarge规格的实例,在杭州地域下那个可用区可售卖

   /**
     *  场景4. 用户选购包年包月ecs.gn4.8xlarge规格的实例,在杭州地域下那个可用区可售卖
     *  目标地域 : cn-hangzhou
     *  任意可用区中: zoneId不传
     *  目标规格: ecs.gn4.8xlarge
     *  包年包月(包含按周):InstanceChargeType 传PrePaid
     *       SpotStrategy 不传或者NoSpot
     *
     *  说明 : 若参数 DestinationResource 取值为 InstanceType,则必须传入参数 IoOptimized
     *  步骤
     *  1.查询可用io优化资源
     *  2.查询可用实例规格资源
     *  返回结果:
     *     支持售卖的可用区列表
     *     没有支持售卖的可用区,返回null或者空
     */
    public List<String> doDescribeScene4() {
        DescribeAvailableResourceRequest describe = new DescribeAvailableResourceRequest();
        describe.setRegionId("cn-hangzhou");
        describe.setInstanceChargeType("PrePaid");
        describe.setInstanceType("ecs.gn4.8xlarge");
        // 1.查询可用io优化资源
        describe.setDestinationResource(IOOPTIMIED);
        Map<String, Set<String>> ioOptimizeds = doActionAndProcessResponse(describe);
        if (null == ioOptimizeds) {
            // 没有io优化资源,查询不到对应的规格资源
            return null;
        }
        //支持该规格的zones
        List<String> zones = new ArrayList<String>(ioOptimizeds.size());
        for (String zoneId : ioOptimizeds.keySet()) {
            describe.setZoneId(zoneId);
            describe.setDestinationResource(INSTANCETYPE);
            for(String iopts : ioOptimizeds.get(zoneId)){
                describe.setIoOptimized(iopts);
            }
            Map<String, Set<String>> typesMap = doActionAndProcessResponse(describe);
            Set<String> types = typesMap.get(zoneId);
            if(CollectionUtils.isNotEmpty(types)){
                if(types.contains("ecs.gn4.8xlarge")){
                    zones.add(zoneId);
                }
            }
        }
        if(CollectionUtils.isNotEmpty(zones)){
            return zones;
        }
        return null;
    }

场景5. 用户在杭州可用区E下,带vpc网络包年包月实例可以售卖实例规格列表

    /**
     *  场景5. 用户在杭州可用区E下,带vpc网络包年包月实例可以售卖实例规格列表
     *  目标地域 : cn-hangzhou
     *  任意可用区中: cn-hangzhou-e
     *  目标网络:vpc
     *  包年包月(包含按周):InstanceChargeType 传PrePaid
     *       SpotStrategy 不传或者NoSpot
     *
     *  说明 : 若参数 DestinationResource 取值为 InstanceType,则必须传入参数 IoOptimized
     *  步骤
     *  1.查询可用io优化资源
     *  2.查询可用实例规格资源
     *  返回结果:
     *     支持售卖的实例规格列表
     *     没有可以售卖的实例规格,返回null或者空
     */
    public List<String> doDescribeScene5() {
        DescribeAvailableResourceRequest describe = new DescribeAvailableResourceRequest();
        describe.setRegionId("cn-hangzhou");
        describe.setZoneId("cn-hangzhou-e");
        describe.setInstanceChargeType("PrePaid");
        describe.setNetworkCategory("Vpc");
        // 1.查询可用io优化资源
        describe.setDestinationResource(IOOPTIMIED);
        Map<String, Set<String>> ioOptimizedMap = doActionAndProcessResponse(describe);
        if (null == ioOptimizedMap) {
            // 没有io优化资源,查询不到对应的规格资源
            return null;
        }
        Set<String> ioOptimizeds = ioOptimizedMap.get("cn-hangzhou-e");
        // 没有io优化资源,查询不到对应的规格资源
        if(CollectionUtils.isEmpty(ioOptimizeds)) {
            return null;
        }
        //支持该规格的规格
        Set<String> types = new HashSet<String>();
        describe.setDestinationResource(INSTANCETYPE);

        for(String iopts : ioOptimizeds){
            describe.setIoOptimized(iopts);
            Map<String, Set<String>> typesMap = doActionAndProcessResponse(describe);
            Set<String> typesInMap = typesMap.get("cn-hangzhou-e");
            if(CollectionUtils.isNotEmpty(typesInMap)){
                types.addAll(typesInMap);
            }
        }
        if(CollectionUtils.isNotEmpty(types)){
            return new ArrayList<String>(types);
        }
        return null;
    }

sdk使用

    public DescribeAvailableResourceResponse doAction(DescribeAvailableResourceRequest describe) {
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", product_accessKey, product_accessSecret);
        IAcsClient client = new DefaultAcsClient(profile);
        try {
            DescribeAvailableResourceResponse response = client.getAcsResponse(describe);
            System.out.println(JSON.toJSONString(response));
            return response;

        } catch (ClientException e) {
            e.printStackTrace();
        }
        return null;
    }

公共请求及结果处理


    private final static String IOOPTIMIED = "IoOptimized";
    private final static String INSTANCETYPE = "InstanceType";
    private final static String SYSTEMDISK = "SystemDisk";
    private final static String DATADISK = "DataDisk";
    private final static String ZONE = "Zone";
    private final static String NETWORK = "Network";

    // 发起请求并处理结果
    private Map<String,Set<String>> doActionAndProcessResponse(DescribeAvailableResourceRequest describe) {
        DescribeAvailableResourceResponse response = doAction(describe);
        Map<String,Set<String>> result = new HashMap<String, Set<String>>();
        if (null != response && CollectionUtils.isNotEmpty(response.getAvailableZones())) {
            for (AvailableZone availableZone : response.getAvailableZones()) {
                String zoneId = availableZone.getZoneId();
                Set<String> values = result.get(zoneId);
                if(CollectionUtils.isEmpty(values)){
                    values = new HashSet<String>();
                }
                if (CollectionUtils.isNotEmpty(availableZone.getAvailableResources())) {
                    for (AvailableResource resource : availableZone.getAvailableResources()) {
                        if (CollectionUtils.isNotEmpty(resource.getSupportedResources())) {
                            for (SupportedResource supportResource : resource.getSupportedResources()) {
                                //只取可用资源
                                if (supportResource.getStatus().equals("Available")) {
                                    values.add(supportResource.getValue());
                                }
                            }
                        }
                    }
                }else{
                    if (availableZone.getStatus().equals("Available")) {
                        values.add(availableZone.getZoneId());
                    }
                }
            }

            if (result.size() != 0) {
                return result;
            }
        }
        return null;
    }

过滤条件导致资源空

进阶玩法:针对ECS新购选型场景查询可用资源
过滤条件导致没有可用资源时返回
进阶玩法:针对ECS新购选型场景查询可用资源
再次强调:
若参数 DestinationResource 取值为 SystemDisk,则必须传入参数 IoOptimized 和 InstanceType。
若参数 DestinationResource 取值为 InstanceType,则必须传入参数 IoOptimized。
若参数 DestinationResource 取值为 DataDisk,则必须传入参数 IoOptimized、InstanceType 和 SystemDiskCategory
IoOptimized等必传参数没有传入时,则报错:
Code: Invalid.Param
Message: The input parameter DestinationResource that is mandatory for processing this request is not supplied.

上一篇:云速搭部署OSS及资源包最佳实践


下一篇:C++调用GDAL库读取并输出tif文件,并计算斑块面积输出景观指数:CSD