parent
ea62395c0e
commit
b85e8795da
|
@ -1,4 +1,5 @@
|
|||
package com.loadcenter.common.aliyun.service;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.aliyun.ecs20140526.Client;
|
||||
import com.aliyun.ecs20140526.models.*;
|
||||
|
@ -13,16 +14,17 @@ import com.loadcenter.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;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* @ClassName AliYunEcsService
|
||||
* @Description 阿里云ecs服务器openAPI调用
|
||||
* @Author Can.J
|
||||
* @Date 2024/4/16
|
||||
* @ClassName AliYunEcsService
|
||||
* @Description 阿里云ecs服务器openAPI调用
|
||||
* @Author Can.J
|
||||
* @Date 2024/4/16
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
|
@ -33,7 +35,6 @@ public class AliYunEcsService {
|
|||
@Autowired
|
||||
private InstanceSpecification instanceSpecification;
|
||||
|
||||
|
||||
//应用阿里云客户端配置
|
||||
private final AliConfig aliConfig;
|
||||
private final Client client;
|
||||
|
@ -51,6 +52,7 @@ public class AliYunEcsService {
|
|||
|
||||
/**
|
||||
* 获取指定区域的实例ID列表
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
|
@ -89,6 +91,7 @@ public class AliYunEcsService {
|
|||
|
||||
/**
|
||||
* 通过实例ID释放实例 多个实例ID,用英文逗号分隔
|
||||
*
|
||||
* @param instanceIds
|
||||
* @throws Exception
|
||||
*/
|
||||
|
@ -124,6 +127,7 @@ public class AliYunEcsService {
|
|||
|
||||
/**
|
||||
* 查询要删除的实例
|
||||
*
|
||||
* @param client
|
||||
* @param regionId
|
||||
* @param instanceIds
|
||||
|
@ -146,6 +150,7 @@ public class AliYunEcsService {
|
|||
|
||||
/**
|
||||
* 修改实例的属性 取消 ‘释放保护’
|
||||
*
|
||||
* @param client
|
||||
* @param instatnceId
|
||||
* @throws Exception
|
||||
|
@ -160,6 +165,7 @@ public class AliYunEcsService {
|
|||
|
||||
/**
|
||||
* 执行释放实例
|
||||
*
|
||||
* @param client
|
||||
* @param regionId
|
||||
* @param instanceIds
|
||||
|
@ -178,6 +184,7 @@ public class AliYunEcsService {
|
|||
|
||||
/**
|
||||
* 创建并运行实例
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
|
@ -210,41 +217,26 @@ public class AliYunEcsService {
|
|||
String instanceChargeType = instanceSpecification.getInstanceChargeType();
|
||||
|
||||
// 批量创建实例
|
||||
return RunInstances(client, regionId, imageId, instanceType, securityGroupId, vSwitchId, internetMaxBandwidthOut, internetChargeType, size, category, instanceChargeType);
|
||||
return RunInstances();
|
||||
}
|
||||
|
||||
/**
|
||||
* RunInstances
|
||||
* 通过备选实例规格创建ECS实例最佳实践
|
||||
* 该场景中,在调用RunInstances创建ECS实例时判断是否发生库存不足等错误,
|
||||
* 如果发生错误,将调用DescribeRecommendInstanceType查询备选实例,
|
||||
* 然后通过备选实例规格重新创建ECS实例。
|
||||
* @param client
|
||||
* @param regionId
|
||||
* @param imageId
|
||||
* @param instanceType
|
||||
* @param securityGroupId
|
||||
* @param vSwitchId
|
||||
* @param internetMaxBandwidthOut
|
||||
* @param internetChargeType
|
||||
* @param size
|
||||
* @param category
|
||||
* @param instanceChargeType
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
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 {
|
||||
public String RunInstances() throws Exception {
|
||||
RunInstancesRequest request = new RunInstancesRequest()
|
||||
.setRegionId(regionId)
|
||||
.setImageId(imageId)
|
||||
.setInstanceType(instanceType)
|
||||
.setSecurityGroupId(securityGroupId)
|
||||
.setVSwitchId(vSwitchId)
|
||||
.setRegionId(aliConfig.getRegionId())
|
||||
.setImageId(instanceSpecification.getImageId())
|
||||
.setInstanceType(instanceSpecification.getInstanceType())
|
||||
.setSecurityGroupId(instanceSpecification.getSecurityGroupId())
|
||||
.setVSwitchId(instanceSpecification.getVSwitchId())
|
||||
.setInstanceName("自动创建的实例节点")
|
||||
.setDescription(new Date().toLocaleString() + " 创建的实例节点")
|
||||
.setInternetMaxBandwidthOut(internetMaxBandwidthOut)
|
||||
.setInternetChargeType(internetChargeType)
|
||||
.setInstanceChargeType(instanceChargeType)
|
||||
.setInternetMaxBandwidthOut(Integer.valueOf(instanceSpecification.getInternetMaxBandwidthOut()))
|
||||
.setInternetChargeType(instanceSpecification.getInternetChargeType())
|
||||
.setInstanceChargeType(instanceSpecification.getInstanceChargeType())
|
||||
// 批量创建五台ECS实例,如果不设置该参数,默认创建一台ECS实例。
|
||||
// amount = 5,
|
||||
// 如果缺少库存可以接受的最低创建数量。
|
||||
|
@ -254,8 +246,8 @@ public class AliYunEcsService {
|
|||
// .setDryRun(true)
|
||||
.setDryRun(false)
|
||||
.setSystemDisk(new RunInstancesRequest.RunInstancesRequestSystemDisk()
|
||||
.setSize(size)
|
||||
.setCategory(category));
|
||||
.setSize(instanceSpecification.getSize())
|
||||
.setCategory(instanceSpecification.getCategory()));
|
||||
|
||||
|
||||
String result = "";
|
||||
|
@ -277,6 +269,7 @@ public class AliYunEcsService {
|
|||
|
||||
/**
|
||||
* 查询一台或多台实例的信息 多台实例用英文逗号拼接
|
||||
*
|
||||
* @param instanceIds
|
||||
* @return
|
||||
* @throws Exception
|
||||
|
@ -364,4 +357,75 @@ public class AliYunEcsService {
|
|||
}
|
||||
return instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* 传入实例ID
|
||||
*/
|
||||
public InstancesInformation selectList(String instanceId) throws Exception {
|
||||
|
||||
DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest()
|
||||
.setRegionId(aliConfig.getRegionId())
|
||||
.setInstanceName("*")
|
||||
.setInstanceIds(com.aliyun.teautil.Common.toJSONString(com.aliyun.darabonbastring.Client.split(instanceId, ",", 50)))
|
||||
.setPageSize(10);
|
||||
|
||||
|
||||
//初始化返回值
|
||||
List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> instanceList = null;
|
||||
|
||||
|
||||
try {
|
||||
|
||||
// 复制代码运行请自行打印 API 的返回值
|
||||
DescribeInstancesResponse describeInstancesResponse = client.describeInstancesWithOptions(describeInstancesRequest, new RuntimeOptions());
|
||||
DescribeInstancesResponseBody body = describeInstancesResponse.getBody();
|
||||
DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstances instances = body.getInstances();
|
||||
|
||||
instanceList = instances.getInstance();
|
||||
|
||||
if (instanceList == null || instanceList.isEmpty()){
|
||||
return new InstancesInformation();
|
||||
}
|
||||
|
||||
|
||||
InstancesInformation ecsInstanceInfo = new InstancesInformation();
|
||||
instanceList.forEach(item -> {
|
||||
|
||||
ecsInstanceInfo.setInstanceName(item.getInstanceName());
|
||||
|
||||
ecsInstanceInfo.setInstanceId(item.getInstanceId());
|
||||
|
||||
ecsInstanceInfo.setStatus(item.status);
|
||||
|
||||
ecsInstanceInfo.setPublicIpAddress(UserUtil.removeBrackets(item.getPublicIpAddress().getIpAddress().toString()));
|
||||
|
||||
ecsInstanceInfo.setRecyclable(item.getRecyclable());
|
||||
|
||||
ecsInstanceInfo.setPrivateIpAddress(item.getVpcAttributes().getPrivateIpAddress().ipAddress.toString());
|
||||
|
||||
});
|
||||
return ecsInstanceInfo;
|
||||
|
||||
} catch (TeaException error) {
|
||||
log.error("code:[{}], message: [{}],data: [{}]",error.getCode(),error.getMessage(),error.getData());
|
||||
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// 错误 message
|
||||
System.out.println(error.getMessage());
|
||||
// 诊断地址
|
||||
System.out.println(error.getData().get("Recommend"));
|
||||
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||
} catch (Exception _error) {
|
||||
TeaException error = new TeaException(_error.getMessage(), _error);
|
||||
|
||||
log.error("message: [{}]",_error.getMessage(),_error);
|
||||
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// 错误 message
|
||||
System.out.println(error.getMessage());
|
||||
// 诊断地址
|
||||
System.out.println(error.getData().get("Recommend"));
|
||||
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||
}
|
||||
|
||||
return new InstancesInformation();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package com.loadcenter.service.impl;
|
|||
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.loadcenter.common.aliyun.service.AliYunEcsService;
|
||||
import com.loadcenter.common.domain.InstancesInformation;
|
||||
import com.loadcenter.gateway.cache.*;
|
||||
import com.loadcenter.gateway.model.GatewayNodeInfo;
|
||||
import com.loadcenter.gateway.model.WorkGatewayNode;
|
||||
|
@ -12,6 +14,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -54,6 +57,9 @@ public class GatewayLoadServiceImpl implements GatewayLoadService {
|
|||
|
||||
private final GatewayNodeScoreCache gatewayNodeScoreCache;
|
||||
|
||||
@Autowired
|
||||
private AliYunEcsService aliYunEcsService;
|
||||
|
||||
/**
|
||||
* 负载节点
|
||||
*
|
||||
|
@ -183,16 +189,32 @@ public class GatewayLoadServiceImpl implements GatewayLoadService {
|
|||
/**
|
||||
* 动态ECS
|
||||
*/
|
||||
public void dynamicEcs(){
|
||||
public void dynamicEcs() throws Exception {
|
||||
//上线最大数量
|
||||
Long vehicleMaxOnlineNum = gatewayNodeScoreCache.getNodeMaxOnlineNum();
|
||||
//当前连接数
|
||||
Long vehicleOnlineNowNum = gatewayNodeScoreCache.getNodeNowNum();
|
||||
|
||||
BigDecimal loadRate = new BigDecimal(vehicleMaxOnlineNum).divide(new BigDecimal(vehicleOnlineNowNum), 0, BigDecimal.ROUND_HALF_UP);
|
||||
|
||||
if(loadRate.longValue()>80){
|
||||
log.info("负载率:[{}]",loadRate);
|
||||
if(loadRate.longValue()>=80L){
|
||||
//调用扩容逻辑
|
||||
log.info("负载过高,开始扩容");
|
||||
String instanceId = aliYunEcsService.RunInstances();
|
||||
|
||||
log.info("扩容的节点是:[{}]",instanceId);
|
||||
|
||||
//休眠5秒确保新实例创建完成
|
||||
Thread.sleep(5000);
|
||||
|
||||
//获取新实例信息放入redis
|
||||
InstancesInformation instancesInformation = aliYunEcsService.selectList(instanceId);
|
||||
|
||||
GatewayNodeInfo gatewayNodeInfo = new GatewayNodeInfo();
|
||||
gatewayNodeInfo.setNodeId(instancesInformation.getInstanceId());
|
||||
gatewayNodeInfo.setPublicAddress(instancesInformation.getPublicIpAddress());
|
||||
gatewayNodeInfo.setPrivateAddress(instancesInformation.getPrivateIpAddress());
|
||||
|
||||
}else if (loadRate.longValue()<20){
|
||||
//调用缩容逻辑
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue