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.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.List; /** * @ProjectName: LoadCenter * @Author: LiuYunHu * @CreateTime: 2024/4/13 * @Description: */ @Component @Slf4j public class Timer { /* * 阿里云api接口类 * */ private final AliYunEcsService aliYunEcsService; /* * 操作缓存 * */ private final GatewayIpAndLoadCountCache gatewayIpAndLoadCountCache; 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/10 * * * * ?") /* * @Description: 动态扩容 * @Date: 2024/4/19 9:44 * @Param: [] * @Return: void **/ public void dynamicExpansion() { //先获取所有的负载列表 List ipAndLoadCounts = gatewayIpAndLoadCountCache.get(); if (ipAndLoadCounts.isEmpty()) { log.error("负载量列表为空!"); return; } //计算所有节点的负载 int connectSize = ipAndLoadCounts.stream().mapToInt(IpAndLoadCount::getLoadCount).sum(); //求出平均值 int avg = connectSize / ipAndLoadCounts.size(); if (avg >= 80) { //执行节点扩容 //返回实例的ID String instanceId; try { instanceId = aliYunEcsService.createAndRunInstance(); } catch (Exception e) { throw new RuntimeException("节点扩容失败!" + e.getMessage()); } if (!instanceId.isEmpty()) { log.info("扩容 成功!扩容的节点ip为:" + instanceId); } } else { log.info("暂时不需要扩容"); } } @Scheduled(cron = "0/10 * * * * ?") /* TODO 缩容有问题 * @Description: 动态缩容 * @Date: 2024/4/19 9:44 * @Param: [] * @Return: void **/ 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; } } } }