LoadCenter/src/main/java/com/lyh/common/aliyun/service/AliYunEcsService.java

318 lines
14 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.lyh.common.aliyun.service;
import com.alibaba.fastjson2.JSON;
import com.aliyun.ecs20140526.Client;
import com.aliyun.ecs20140526.models.*;
import com.aliyun.tea.TeaException;
import com.aliyun.teautil.Common;
import com.aliyun.teautil.models.RuntimeOptions;
import com.lyh.common.aliyun.config.AliConfig;
import com.lyh.common.aliyun.model.InstanceSpecification;
import com.lyh.common.utils.user.UserUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 阿里云ecs服务器openAPI调用
*
* @ProjectName: LoadCenter
* @Author: LiuYunHu
* @CreateTime: 2024/4/16
*/
@Component
@Slf4j
public class AliYunEcsService {
/**
* 应用阿里云客户端配置
*/
private final AliConfig aliConfig;
private final Client client;
/**
* 实例规格,用于创建实例
*/
@Autowired
private InstanceSpecification instanceSpecification;
public AliYunEcsService(AliConfig aliConfig, Client client) {
this.aliConfig = aliConfig;
this.client = client;
}
/**
* 查询要删除的实例
*
* @Author: LiuYunHu
* @Date: 2024/4/16 20:31
* @Param: [client, regionId, instanceIds, instanceName]
* @Return: DescribeInstancesResponse
**/
public static DescribeInstancesResponse DescribeInstances(Client client, String regionId, String instanceIds, String instanceName) throws Exception {
DescribeInstancesRequest req = new DescribeInstancesRequest()
.setRegionId(regionId)
.setInstanceName(instanceName);
if (!Common.empty(instanceIds)) {
req.instanceIds = Common.toJSONString(com.aliyun.darabonbastring.Client.split(instanceIds, ",", 50));
}
DescribeInstancesResponse resp = client.describeInstances(req);
com.aliyun.teaconsole.Client.log("--------------------查询需要删除的实例--------------------");
return resp;
}
/**
* 修改实例的属性 取消 ‘释放保护’
*
* @Author: LiuYunHu
* @Date: 2024/4/16 20:33
* @Param: [client, instatnceId]
* @Return: void
**/
public static void ModifyInstanceAttribute(Client client, String instatnceId) throws Exception {
ModifyInstanceAttributeRequest req = new ModifyInstanceAttributeRequest()
.setInstanceId(instatnceId)
.setDeletionProtection(false);//设置删除保护为false
client.modifyInstanceAttribute(req);
com.aliyun.teaconsole.Client.log("--------------------" + instatnceId + "释放保护取消成功--------------------");
}
/**
* 执行释放实例
*
* @Author: LiuYunHu
* @Date: 2024/4/16 20:35
* @Param: [client, regionId, instanceIds, force]
* @Return: void
**/
public static void DeleteInstances(com.aliyun.ecs20140526.Client client, String regionId, String instanceIds, String force) throws Exception {
DeleteInstancesRequest req = new DeleteInstancesRequest()
.setRegionId(regionId)
.setInstanceId(com.aliyun.darabonbastring.Client.split(instanceIds, ",", 50))
.setForce(Common.equalString(force, "true"));
DeleteInstancesResponse resp = client.deleteInstances(req);
com.aliyun.teaconsole.Client.log("--------------------实例释放成功--------------------");
com.aliyun.teaconsole.Client.log(Common.toJSONString(Common.toMap(resp)));
}
/**
* RunInstances 通过备选实例规格创建ECS实例最佳实践
* 该场景中在调用RunInstances创建ECS实例时判断是否发生库存不足等错误如果发生错误将调用DescribeRecommendInstanceType查询备选实例然后通过备选实例规格重新创建ECS实例。
*/
public static String RunInstances(Client client, String regionId, String imageId, String instanceType, String securityGroupId, String vSwitchId, Integer internetMaxBandwidthOut, String internetChargeType, String size, String category, String instanceChargeType) throws Exception {
RunInstancesRequest request = new RunInstancesRequest()
.setRegionId(regionId)
.setImageId(imageId)
.setInstanceType(instanceType)
.setSecurityGroupId(securityGroupId)
.setVSwitchId(vSwitchId)
.setInstanceName("自动创建的实例节点")
.setDescription(new Date().toLocaleString() + " 创建的实例节点")
.setInternetMaxBandwidthOut(internetMaxBandwidthOut)
.setInternetChargeType(internetChargeType)
.setInstanceChargeType(instanceChargeType)
// 批量创建五台ECS实例如果不设置该参数默认创建一台ECS实例。
// amount = 5,
// 如果缺少库存可以接受的最低创建数量。
// minAmount = 2,
// 打开预检参数功能不会实际创建ECS实例只检查参数正确性、用户权限或者ECS库存等问题。
// 实际情况下设置了DryRun参数后Amount必须为1MinAmount必须为空您可以根据实际需求修改代码。
// .setDryRun(true)
.setDryRun(false)
.setSystemDisk(new RunInstancesRequest.RunInstancesRequestSystemDisk()
.setSize(size)
.setCategory(category));
String result = "";
try {
com.aliyun.teaconsole.Client.log("--------------------批量创建实例开始--------------------");
RunInstancesResponse responces = client.runInstances(request);
com.aliyun.teaconsole.Client.log("--------------------创建实例成功实例ID:" + Common.toJSONString(responces.body.instanceIdSets.instanceIdSet) + "--------------------");
//返回实例ID
result = responces.body.instanceIdSets.instanceIdSet + "";//前后带 []
result = UserUtil.removeBrackets(result);//前后不带[]
} catch (TeaException error) {
com.aliyun.teaconsole.Client.log("--------------------创建实例失败:" + Common.toJSONString(error.code) + "--------------------" + error.message);
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
com.aliyun.teaconsole.Client.log("--------------------创建实例失败:" + Common.toJSONString(error.code) + "--------------------" + error.message);
}
return result;
}
/**
* 获取指定区域的实例ID列表
*
* @Date: 2024/4/19 20:02
* @Param: []
* @Return: java.util.List<java.lang.String>
**/
public List<String> getIDList() throws Exception {
java.util.List<String> regionIds = com.aliyun.darabonbastring.Client.split(aliConfig.getRegionId(), ",", 50);
String regionId = regionIds.get(0);
DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest()
.setPageSize(100)
.setRegionId(regionId);
DescribeInstancesResponse resp = this.client.describeInstances(describeInstancesRequest);
java.util.List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> instances = resp.body.instances.instance;
log.info("{} 下 ECS 实例列表:", regionId);
//存储结果的List
ArrayList<String> result = new ArrayList<>();
for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance instance : instances) {
// log.info("主机名:" + instance.hostName + " 实例ID" + instance.instanceId + " CPU" + instance.cpu + " 内存:" + instance.memory + " MB 规格:" + instance.instanceType + " 系统:" + instance.OSType + "(" + instance.OSName + ") 状态:" + instance.status);
result.add(instance.instanceId);
}
//将查询到的ecs服务器id列表 打印控制台
log.info(JSON.toJSONString(result));
//返回结果
return result;
}
/**
* 通过实例ID释放实例 多个实例ID用英文逗号分隔
*
* @Author: LiuYunHu
* @Date: 2024/4/16 20:19
* @Description:
* @Param: instanceIds 要删除实例ID
**/
public void releaseInstances(String instanceIds) throws Exception {
// 实例名称,支持使用通配符*进行模糊搜索
String instanceName = "*";
// 强制删除有删除保护的机器
String deleteProtected = "true";
// 强制删除运行中的机器
String force = "true";
//判断是否为强制删除
if (Common.equalString(deleteProtected, "true")) {
DescribeInstancesResponse describeInstancesResp = DescribeInstances(client, aliConfig.getRegionId(), instanceIds, instanceName);
instanceIds = "";
for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance instance : describeInstancesResp.body.instances.instance) {
instanceIds = instance.instanceId + "," + instanceIds;
if (instance.deletionProtection) {
ModifyInstanceAttribute(client, instance.instanceId);
}
}
instanceIds = com.aliyun.darabonbastring.Client.subString(instanceIds, 0, -1);
}
//如果入参为空
if (Common.empty(instanceIds)) {
com.aliyun.teaconsole.Client.log("--------------------无有效实例可删除--------------------");
return;
}
DeleteInstances(client, aliConfig.getRegionId(), instanceIds, force);
}
/**
* 创建并运行实例
*
* @Author: LiuYunHu
* @Date: 2024/4/16 21:44
* @Param: []
* @Return: java.lang.String
**/
public String createAndRunInstance() throws Exception {
//获取实例规格
// 地域Id
String regionId = aliConfig.getRegionId();
// 镜像 ID启动实例时选择的镜像资源。
String imageId = instanceSpecification.getImageId();
// 实例规格
String instanceType = instanceSpecification.getInstanceType();
// 新创建实例所属于的安全组 ID。
String securityGroupId = instanceSpecification.getSecurityGroupId();
// 虚拟交换机 ID。
String vSwitchId = instanceSpecification.getVSwitchId();
// 公网出带宽最大值,单位为 Mbit/s。取值范围0~100。 默认值0。
Integer internetMaxBandwidthOut = com.aliyun.darabonbanumber.Client.parseInt(instanceSpecification.getInternetMaxBandwidthOut());
// 网络计费类型。取值范围:
// PayByBandwidth: 按固定带宽计费。
// PayByTraffic: 按使用流量计费。
// 默认值PayByTraffic。
String internetChargeType = instanceSpecification.getInternetChargeType();
// 系统盘大小
String size = instanceSpecification.getSize();
// 系统盘的云盘种类
String category = instanceSpecification.getCategory();
// ECS实例的计费方式
// PrePaid包年包月
// PostPaid按量付费
String instanceChargeType = instanceSpecification.getInstanceChargeType();
// 批量创建实例
return RunInstances(client, regionId, imageId, instanceType, securityGroupId, vSwitchId, internetMaxBandwidthOut, internetChargeType, size, category, instanceChargeType);
}
/**
* 查询一台或多台实例的信息 多台实例用英文逗号拼接
*
* @Author: LiuYunHu
* @Date: 2024/4/16 22:02
* @Param: [instanceIds] i-uf6chlqotgoc9h173alu
**/
public List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> queryInstancesInformation(String instanceIds) {
DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest()
.setRegionId(aliConfig.getRegionId())
.setInstanceName("*")
.setInstanceIds(Common.toJSONString(com.aliyun.darabonbastring.Client.split(instanceIds, ",", 50)))
.setPageSize(10);
RuntimeOptions runtime = new RuntimeOptions();
//初始化返回值
List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> instances = null;
try {
// 复制代码运行请自行打印 API 的返回值
DescribeInstancesResponse describeInstancesResponse = client.describeInstancesWithOptions(describeInstancesRequest, runtime);
DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstances bodyInstances = describeInstancesResponse.getBody().getInstances();
//
instances = bodyInstances.getInstance();
} catch (TeaException error) {
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
// 错误 message
log.error(error.getMessage());
// 诊断地址
log.error(error.getData().get("Recommend").toString());
com.aliyun.teautil.Common.assertAsString(error.message);
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
// 错误 message
log.error(error.getMessage());
// 诊断地址
log.error(error.getData().get("Recommend").toString());
Common.assertAsString(error.message);
}
return instances;
}
}