diff --git a/src/main/java/com/lyh/common/aliyun/service/AliYunEcsService.java b/src/main/java/com/lyh/common/aliyun/service/AliYunEcsService.java index d3a4d13..f4d2e37 100644 --- a/src/main/java/com/lyh/common/aliyun/service/AliYunEcsService.java +++ b/src/main/java/com/lyh/common/aliyun/service/AliYunEcsService.java @@ -69,12 +69,13 @@ public class AliYunEcsService { .setRegionId(regionId); DescribeInstancesResponse resp = this.client.describeInstances(describeInstancesRequest); java.util.List instances = resp.body.instances.instance; + log.info(regionId + " 下 ECS 实例列表:"); //存储结果的List ArrayList 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); +// 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); } diff --git a/src/main/java/com/lyh/handle/HandleCache.java b/src/main/java/com/lyh/handle/HandleCache.java index bcf556d..4f22380 100644 --- a/src/main/java/com/lyh/handle/HandleCache.java +++ b/src/main/java/com/lyh/handle/HandleCache.java @@ -77,7 +77,7 @@ public class HandleCache { this.getIpAndLoadCounts(); this.getIpAndWeights(); this.getLoadNodeOrderListByIpAndWeights(); -} + } /* @@ -98,7 +98,7 @@ public class HandleCache { gatewayNodeIdCache.put(ecsIDList); } catch (Exception e) { - log.error("获取节点ID失败:{}", e.getMessage()); + throw new RuntimeException("获取节点ID失败" + e.getMessage()); } } @@ -124,36 +124,37 @@ public class HandleCache { } //将ID进行拼接,用逗号分隔 - String ids = ""; + StringBuilder ids = new StringBuilder(); for (String id : ecsIDList) { - ids += id + ","; + ids.append(id).append(","); } - ids = ids.substring(0, ids.length() - 1); + ids = new StringBuilder(ids.substring(0, ids.length() - 1)); //查询所有ID实例的详细信息 - List response = aliYunEcsService.queryInstancesInformation(ids); + List response = aliYunEcsService.queryInstancesInformation(ids.toString()); for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance item : response) { - log.info("查询第{" + count + "}个实例的ID:" + item.getInstanceId()); - log.info("名称:" + item.getInstanceName()); + + log.info("查询第{" + count + 1 + "}个实例的ID:" + item.getInstanceId()); +// log.info("名称:" + item.getInstanceName()); log.info("地域ID:" + item.getRegionId()); - log.info("状态:" + item.getStatus()); - log.info("类型:" + item.getInstanceType()); +// log.info("状态:" + item.getStatus()); +// log.info("类型:" + item.getInstanceType()); log.info("CPU核心数:" + item.getCpu()); log.info("内存大小:" + item.getMemory() + "MB"); - log.info("磁盘大小:" + item.getLocalStorageCapacity() + "G"); - log.info("操作系统:" + item.getOSName()); - log.info("网络类型:" + item.getInstanceNetworkType()); +// log.info("磁盘大小:" + item.getLocalStorageCapacity() + "G"); +// log.info("操作系统:" + item.getOSName()); +// log.info("网络类型:" + item.getInstanceNetworkType()); log.info("公网出带宽值:" + item.getInternetMaxBandwidthOut() + "Mbit/s"); - log.info("公网入带宽值:" + item.getInternetMaxBandwidthIn() + "Mbit/s"); +// log.info("公网入带宽值:" + item.getInternetMaxBandwidthIn() + "Mbit/s"); log.info("公网IP:" + UserUtil.removeBrackets(item.getPublicIpAddress().getIpAddress().toString())); log.info("私网IP:" + UserUtil.removeBrackets(item.getVpcAttributes().getPrivateIpAddress().ipAddress.toString())); - log.info("专有网络VPCID:" + item.getVpcAttributes().getVpcId()); - log.info("安全组ID:" + UserUtil.removeBrackets(item.getSecurityGroupIds().getSecurityGroupId().toString())); +// log.info("专有网络VPCID:" + item.getVpcAttributes().getVpcId()); +// log.info("安全组ID:" + UserUtil.removeBrackets(item.getSecurityGroupIds().getSecurityGroupId().toString())); log.info("创建时间:" + item.getCreationTime()); - log.info("到期时间:" + item.getExpiredTime()); - log.info("是否可以回收:" + (item.getRecyclable() ? "是" : "否") + "\n\n"); +// log.info("到期时间:" + item.getExpiredTime()); +// log.info("是否可以回收:" + (item.getRecyclable() ? "是" : "否") + "\n\n"); //存入集合 gatewayNodeInfos.add( @@ -283,6 +284,7 @@ public class HandleCache { } log.info("实例IP和对应的权重:{}", ipAndWeights);//[IpAndWeight(nodeIp=47.102.158.233, weight=55), IpAndWeight(nodeIp=47.102.123.209, weight=44)] + log.info("\n\n\n"); gatewayIpAndLoadWeightCache.put(ipAndWeights); } @@ -336,7 +338,8 @@ public class HandleCache { } } - log.info("负载节点的IP序列列表:{}", loadNodeList); +// log.info("负载节点的IP序列列表:{}", loadNodeList); + //节点IP序列存入缓存 gatewayNodeOrderCache.put(loadNodeList); } diff --git a/src/main/java/com/lyh/job/Timer.java b/src/main/java/com/lyh/job/Timer.java index 4d5315c..458de5a 100644 --- a/src/main/java/com/lyh/job/Timer.java +++ b/src/main/java/com/lyh/job/Timer.java @@ -3,9 +3,10 @@ package com.lyh.job; import com.lyh.common.aliyun.service.AliYunEcsService; import com.lyh.gateway.cache.GatewayIpAndLoadCountCache; import com.lyh.gateway.cache.GatewayNodeIdCache; +import com.lyh.gateway.cache.GatewayNodeInfoCache; +import com.lyh.gateway.mode.GatewayNodeInfo; import com.lyh.gateway.mode.IpAndLoadCount; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -24,20 +25,26 @@ public class Timer { /* * 阿里云api接口类 * */ - @Autowired - private AliYunEcsService aliYunEcsService; + private final AliYunEcsService aliYunEcsService; /* * 操作缓存 * */ - @Autowired - private GatewayIpAndLoadCountCache gatewayIpAndLoadCountCache; + private final GatewayIpAndLoadCountCache gatewayIpAndLoadCountCache; - @Autowired - private GatewayNodeIdCache gatewayNodeIdCache; + private final GatewayNodeIdCache gatewayNodeIdCache; + + private final GatewayNodeInfoCache gatewayNodeInfoCache; + + public Timer(AliYunEcsService aliYunEcsService, GatewayIpAndLoadCountCache gatewayIpAndLoadCountCache, GatewayNodeIdCache gatewayNodeIdCache, GatewayNodeInfoCache gatewayNodeInfoCache) { + this.aliYunEcsService = aliYunEcsService; + this.gatewayIpAndLoadCountCache = gatewayIpAndLoadCountCache; + this.gatewayNodeIdCache = gatewayNodeIdCache; + this.gatewayNodeInfoCache = gatewayNodeInfoCache; + } - @Scheduled(cron = "0/5 * * * * ?") + @Scheduled(cron = "0/10 * * * * ?") /* * @Description: 动态扩容 * @Date: 2024/4/19 9:44 @@ -47,6 +54,10 @@ public class Timer { public void dynamicExpansion() { //先获取所有的负载列表 List ipAndLoadCounts = gatewayIpAndLoadCountCache.get(); + if (ipAndLoadCounts.isEmpty()) { + log.error("负载量列表为空!"); + return; + } //计算所有节点的负载 int connectSize = ipAndLoadCounts.stream().mapToInt(IpAndLoadCount::getLoadCount).sum(); @@ -58,7 +69,7 @@ public class Timer { //执行节点扩容 //返回实例的ID - String instanceId = null; + String instanceId; try { instanceId = aliYunEcsService.createAndRunInstance(); } catch (Exception e) { @@ -66,8 +77,7 @@ public class Timer { } if (!instanceId.isEmpty()) { - log.info("扩容 成功!"); - log.info("扩容的节点ip为:" + instanceId); + log.info("扩容 成功!扩容的节点ip为:" + instanceId); } } else { log.info("暂时不需要扩容"); @@ -75,51 +85,60 @@ public class Timer { } -// @Scheduled(cron = "0/5 * * * * ?") + @Scheduled(cron = "0/10 * * * * ?") /* TODO 缩容有问题 * @Description: 动态缩容 * @Date: 2024/4/19 9:44 * @Param: [] * @Return: void **/ -// public void dynamicReduction() { -// //求出所有的节点ID -// List nodeIds = gatewayNodeIdCache.get(); -// -// if (nodeIds.size() <= 1) { -// log.error("暂无节点可删除!"); -// return; -// } -// -// -// //先获取所有的负载列表 -// List ipAndLoadCounts = gatewayIpAndLoadCountCache.get(); -// if (ipAndLoadCounts.size() <= 1) { -// log.error("负载列表为空!"); -// return; -// } -// -// //计算所有节点的负载 -// int connectSize = ipAndLoadCounts.stream().mapToInt(IpAndLoadCount::getLoadCount).sum(); -// -// //求出平均值 -// int avg = connectSize / ipAndLoadCounts.size(); -// -// if (avg <= 30) { -// -// -// request = request.substring(0, request.length() - 1); -// -// //执行节点缩容 -// try { -// aliYunEcsService.releaseInstances(request); -// } catch (Exception e) { -// throw new RuntimeException("节点缩容失败!" + e.getMessage()); -// } -// } else { -// log.info("暂时不需要缩容"); -// } -// } + public void dynamicReduction() { + //求出所有的节点ID + List nodeIds = gatewayNodeIdCache.get(); + + //如果节点数量小于等于1,则不执行缩容,至少保留一个节点 + if (nodeIds.size() <= 1) { + log.info("暂无节点可删除!"); + return; + } + + + //先获取所有的负载列表 + List ipAndLoadCounts = gatewayIpAndLoadCountCache.get(); + if (ipAndLoadCounts.size() <= 1) { + log.error("负载列表为空!"); + return; + } + + //获取节点信息(IP)集合 + List gatewayNodeInfoList = gatewayNodeInfoCache.get(); + if (gatewayNodeInfoList.isEmpty()) { + log.error("节点信息为空!"); + return; + } + + //判断哪个节点的负载小于30 + + for (GatewayNodeInfo gatewayNodeInfo : gatewayNodeInfoList) {//获取节点的IP + String ip = gatewayNodeInfo.getPublicIpAddress(); + //获取当前循环节点的负载 + int loadCount = ipAndLoadCounts.stream().filter(ipAndLoadCount -> ipAndLoadCount.getIp().equals(ip)).findFirst().get().getLoadCount(); + //判断节点的负载是否小于30 + if (loadCount < 30) { + //对这个节点进行缩容 + String instanceId = gatewayNodeInfo.getInstanceId(); + try { + aliYunEcsService.releaseInstances(instanceId); + } catch (Exception e) { + throw new RuntimeException("节点缩容失败!" + e.getMessage()); + } + log.info("节点缩容成功"); + //一次只删除一个节点 + break; + } + } + + } } diff --git a/src/test/java/Test.java b/src/test/java/Test.java index b042459..8dc7875 100644 --- a/src/test/java/Test.java +++ b/src/test/java/Test.java @@ -72,7 +72,7 @@ public class Test { **/ @org.junit.jupiter.api.Test public void releaseInstances() throws Exception { - aliYunEcsService.releaseInstances("i-uf62wv013unz2ee2tsl6"); + aliYunEcsService.releaseInstances("i-uf6h4s0jtpvrtgx574s1,"); } /*