parent
ea62395c0e
commit
b85e8795da
|
@ -1,4 +1,5 @@
|
||||||
package com.loadcenter.common.aliyun.service;
|
package com.loadcenter.common.aliyun.service;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.aliyun.ecs20140526.Client;
|
import com.aliyun.ecs20140526.Client;
|
||||||
import com.aliyun.ecs20140526.models.*;
|
import com.aliyun.ecs20140526.models.*;
|
||||||
|
@ -13,6 +14,7 @@ import com.loadcenter.common.utils.user.UserUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -33,7 +35,6 @@ public class AliYunEcsService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private InstanceSpecification instanceSpecification;
|
private InstanceSpecification instanceSpecification;
|
||||||
|
|
||||||
|
|
||||||
//应用阿里云客户端配置
|
//应用阿里云客户端配置
|
||||||
private final AliConfig aliConfig;
|
private final AliConfig aliConfig;
|
||||||
private final Client client;
|
private final Client client;
|
||||||
|
@ -51,6 +52,7 @@ public class AliYunEcsService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取指定区域的实例ID列表
|
* 获取指定区域的实例ID列表
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
|
@ -89,6 +91,7 @@ public class AliYunEcsService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过实例ID释放实例 多个实例ID,用英文逗号分隔
|
* 通过实例ID释放实例 多个实例ID,用英文逗号分隔
|
||||||
|
*
|
||||||
* @param instanceIds
|
* @param instanceIds
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
|
@ -124,6 +127,7 @@ public class AliYunEcsService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询要删除的实例
|
* 查询要删除的实例
|
||||||
|
*
|
||||||
* @param client
|
* @param client
|
||||||
* @param regionId
|
* @param regionId
|
||||||
* @param instanceIds
|
* @param instanceIds
|
||||||
|
@ -146,6 +150,7 @@ public class AliYunEcsService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改实例的属性 取消 ‘释放保护’
|
* 修改实例的属性 取消 ‘释放保护’
|
||||||
|
*
|
||||||
* @param client
|
* @param client
|
||||||
* @param instatnceId
|
* @param instatnceId
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
|
@ -160,6 +165,7 @@ public class AliYunEcsService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行释放实例
|
* 执行释放实例
|
||||||
|
*
|
||||||
* @param client
|
* @param client
|
||||||
* @param regionId
|
* @param regionId
|
||||||
* @param instanceIds
|
* @param instanceIds
|
||||||
|
@ -178,6 +184,7 @@ public class AliYunEcsService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建并运行实例
|
* 创建并运行实例
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
|
@ -210,41 +217,26 @@ public class AliYunEcsService {
|
||||||
String instanceChargeType = instanceSpecification.getInstanceChargeType();
|
String instanceChargeType = instanceSpecification.getInstanceChargeType();
|
||||||
|
|
||||||
// 批量创建实例
|
// 批量创建实例
|
||||||
return RunInstances(client, regionId, imageId, instanceType, securityGroupId, vSwitchId, internetMaxBandwidthOut, internetChargeType, size, category, instanceChargeType);
|
return RunInstances();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RunInstances
|
|
||||||
* 通过备选实例规格创建ECS实例最佳实践
|
* 通过备选实例规格创建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
|
* @return
|
||||||
* @throws Exception
|
* @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()
|
RunInstancesRequest request = new RunInstancesRequest()
|
||||||
.setRegionId(regionId)
|
.setRegionId(aliConfig.getRegionId())
|
||||||
.setImageId(imageId)
|
.setImageId(instanceSpecification.getImageId())
|
||||||
.setInstanceType(instanceType)
|
.setInstanceType(instanceSpecification.getInstanceType())
|
||||||
.setSecurityGroupId(securityGroupId)
|
.setSecurityGroupId(instanceSpecification.getSecurityGroupId())
|
||||||
.setVSwitchId(vSwitchId)
|
.setVSwitchId(instanceSpecification.getVSwitchId())
|
||||||
.setInstanceName("自动创建的实例节点")
|
.setInstanceName("自动创建的实例节点")
|
||||||
.setDescription(new Date().toLocaleString() + " 创建的实例节点")
|
.setDescription(new Date().toLocaleString() + " 创建的实例节点")
|
||||||
.setInternetMaxBandwidthOut(internetMaxBandwidthOut)
|
.setInternetMaxBandwidthOut(Integer.valueOf(instanceSpecification.getInternetMaxBandwidthOut()))
|
||||||
.setInternetChargeType(internetChargeType)
|
.setInternetChargeType(instanceSpecification.getInternetChargeType())
|
||||||
.setInstanceChargeType(instanceChargeType)
|
.setInstanceChargeType(instanceSpecification.getInstanceChargeType())
|
||||||
// 批量创建五台ECS实例,如果不设置该参数,默认创建一台ECS实例。
|
// 批量创建五台ECS实例,如果不设置该参数,默认创建一台ECS实例。
|
||||||
// amount = 5,
|
// amount = 5,
|
||||||
// 如果缺少库存可以接受的最低创建数量。
|
// 如果缺少库存可以接受的最低创建数量。
|
||||||
|
@ -254,8 +246,8 @@ public class AliYunEcsService {
|
||||||
// .setDryRun(true)
|
// .setDryRun(true)
|
||||||
.setDryRun(false)
|
.setDryRun(false)
|
||||||
.setSystemDisk(new RunInstancesRequest.RunInstancesRequestSystemDisk()
|
.setSystemDisk(new RunInstancesRequest.RunInstancesRequestSystemDisk()
|
||||||
.setSize(size)
|
.setSize(instanceSpecification.getSize())
|
||||||
.setCategory(category));
|
.setCategory(instanceSpecification.getCategory()));
|
||||||
|
|
||||||
|
|
||||||
String result = "";
|
String result = "";
|
||||||
|
@ -277,6 +269,7 @@ public class AliYunEcsService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询一台或多台实例的信息 多台实例用英文逗号拼接
|
* 查询一台或多台实例的信息 多台实例用英文逗号拼接
|
||||||
|
*
|
||||||
* @param instanceIds
|
* @param instanceIds
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
|
@ -364,4 +357,75 @@ public class AliYunEcsService {
|
||||||
}
|
}
|
||||||
return instances;
|
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.JSONArray;
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
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.cache.*;
|
||||||
import com.loadcenter.gateway.model.GatewayNodeInfo;
|
import com.loadcenter.gateway.model.GatewayNodeInfo;
|
||||||
import com.loadcenter.gateway.model.WorkGatewayNode;
|
import com.loadcenter.gateway.model.WorkGatewayNode;
|
||||||
|
@ -12,6 +14,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -54,6 +57,9 @@ public class GatewayLoadServiceImpl implements GatewayLoadService {
|
||||||
|
|
||||||
private final GatewayNodeScoreCache gatewayNodeScoreCache;
|
private final GatewayNodeScoreCache gatewayNodeScoreCache;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AliYunEcsService aliYunEcsService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 负载节点
|
* 负载节点
|
||||||
*
|
*
|
||||||
|
@ -183,16 +189,32 @@ public class GatewayLoadServiceImpl implements GatewayLoadService {
|
||||||
/**
|
/**
|
||||||
* 动态ECS
|
* 动态ECS
|
||||||
*/
|
*/
|
||||||
public void dynamicEcs(){
|
public void dynamicEcs() throws Exception {
|
||||||
//上线最大数量
|
//上线最大数量
|
||||||
Long vehicleMaxOnlineNum = gatewayNodeScoreCache.getNodeMaxOnlineNum();
|
Long vehicleMaxOnlineNum = gatewayNodeScoreCache.getNodeMaxOnlineNum();
|
||||||
//当前连接数
|
//当前连接数
|
||||||
Long vehicleOnlineNowNum = gatewayNodeScoreCache.getNodeNowNum();
|
Long vehicleOnlineNowNum = gatewayNodeScoreCache.getNodeNowNum();
|
||||||
|
|
||||||
BigDecimal loadRate = new BigDecimal(vehicleMaxOnlineNum).divide(new BigDecimal(vehicleOnlineNowNum), 0, BigDecimal.ROUND_HALF_UP);
|
BigDecimal loadRate = new BigDecimal(vehicleMaxOnlineNum).divide(new BigDecimal(vehicleOnlineNowNum), 0, BigDecimal.ROUND_HALF_UP);
|
||||||
|
log.info("负载率:[{}]",loadRate);
|
||||||
if(loadRate.longValue()>80){
|
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){
|
}else if (loadRate.longValue()<20){
|
||||||
//调用缩容逻辑
|
//调用缩容逻辑
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue