diff --git a/pom.xml b/pom.xml
index 986f6b9..1a47e35 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,9 +8,9 @@
vehicle
1.0-SNAPSHOT
- 20
- 20
- 2.7.18
+ 17
+ 17
+ 2.7.13
UTF-8
@@ -218,8 +218,4 @@
-
-
-
-
diff --git a/src/main/java/com/loadCenter/aliyun/common/aliyun/config/AliConfig.java b/src/main/java/com/loadCenter/aliyun/common/aliyun/config/AliConfig.java
index 046c3a3..0821377 100644
--- a/src/main/java/com/loadCenter/aliyun/common/aliyun/config/AliConfig.java
+++ b/src/main/java/com/loadCenter/aliyun/common/aliyun/config/AliConfig.java
@@ -17,18 +17,16 @@ import org.springframework.context.annotation.Configuration;
* @Author ZeJinG.Su
*/
@Configuration
-@ConfigurationProperties(prefix = "config.aliyun")
@Data
@AllArgsConstructor
@NoArgsConstructor
-@ToString
-@SuperBuilder
+@ConfigurationProperties(prefix = "config.ali")
public class AliConfig {
/**
* 阿里云access-key-id
*/
- private String accessKetId;
+ private String accessKeyId;
/**
* 阿里云access-key-secret
*/
@@ -42,7 +40,7 @@ public class AliConfig {
@Bean
public Client createEcsClient(AliConfig aliConfig) throws Exception {
Config config = new Config()
- .setAccessKeyId(aliConfig.getAccessKetId())
+ .setAccessKeyId(aliConfig.getAccessKeyId())
.setAccessKeySecret(aliConfig.getAccessKeySecret())
.setRegionId(aliConfig.getRegionId());
return new Client(config);
diff --git a/src/main/java/com/loadCenter/aliyun/common/aliyun/model/InstanceConfig.java b/src/main/java/com/loadCenter/aliyun/common/aliyun/model/InstanceConfig.java
index 3812457..1b8a261 100644
--- a/src/main/java/com/loadCenter/aliyun/common/aliyun/model/InstanceConfig.java
+++ b/src/main/java/com/loadCenter/aliyun/common/aliyun/model/InstanceConfig.java
@@ -5,7 +5,10 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
- *创建实例的参数映射yml
+ * @ClassName InstanceConfig
+ * @Description 创建实例的参数映射yml
+ * @Author ZeJinG.Su
+ * @Date 10:39 2024/4/20
*/
@Data
@Configuration
diff --git a/src/main/java/com/loadCenter/aliyun/common/aliyun/service/AliYunEcsService.java b/src/main/java/com/loadCenter/aliyun/common/aliyun/service/AliYunEcsService.java
index 9c71cf1..4a23949 100644
--- a/src/main/java/com/loadCenter/aliyun/common/aliyun/service/AliYunEcsService.java
+++ b/src/main/java/com/loadCenter/aliyun/common/aliyun/service/AliYunEcsService.java
@@ -40,7 +40,11 @@ public class AliYunEcsService {
}
- //区域实例集合
+ /**
+ * 区域实例集合
+ * @return
+ * @throws Exception
+ */
public List getIDList() throws Exception {
List regionIds = com.aliyun.darabonbastring.Client.split(aliConfig.getRegionId(), ",", 50);
@@ -63,7 +67,11 @@ public class AliYunEcsService {
return result;
}
- //释放实例
+ /**
+ * 释放实例
+ * @param instanceIds
+ * @throws Exception
+ */
public void releaseInstances(String instanceIds) throws Exception {
// 实例名称,支持使用通配符*进行模糊搜索
@@ -96,7 +104,15 @@ public class AliYunEcsService {
DeleteInstances(client, aliConfig.getRegionId(), instanceIds, force);
}
- //查询需要删除实例
+ /**
+ * 查询需要删除实例
+ * @param client
+ * @param regionId
+ * @param instanceIds
+ * @param instanceName
+ * @return
+ * @throws Exception
+ */
public static DescribeInstancesResponse DescribeInstances(Client client, String regionId, String instanceIds, String instanceName) throws Exception {
DescribeInstancesRequest req = new DescribeInstancesRequest()
.setRegionId(regionId)
@@ -110,7 +126,12 @@ public class AliYunEcsService {
return resp;
}
- //修改实例删除保护
+ /**
+ * 修改实例删除保护
+ * @param client
+ * @param instatnceId
+ * @throws Exception
+ */
public static void ModifyInstanceAttribute(Client client, String instatnceId) throws Exception {
ModifyInstanceAttributeRequest req = new ModifyInstanceAttributeRequest()
.setInstanceId(instatnceId)
@@ -119,7 +140,14 @@ public class AliYunEcsService {
com.aliyun.teaconsole.Client.log("--------------------" + instatnceId + "释放保护取消成功--------------------");
}
- //执行释放实例
+ /**
+ * 执行释放实例
+ * @param client
+ * @param regionId
+ * @param instanceIds
+ * @param force
+ * @throws Exception
+ */
public static void DeleteInstances(Client client, String regionId, String instanceIds, String force) throws Exception {
DeleteInstancesRequest req = new DeleteInstancesRequest()
.setRegionId(regionId)
@@ -131,34 +159,22 @@ public class AliYunEcsService {
}
- //创建实例(创建成功后自启动)
+ /**
+ * 创建实例(创建成功后自启动)
+ * @return
+ * @throws Exception
+ */
public String createAndRunInstance() throws Exception {
- //获取实例规格
- // 地域Id
String regionId = aliConfig.getRegionId();
- // 镜像 ID,启动实例时选择的镜像资源。
String imageId = instanceConfig.getImageId();
- // 实例规格
String instanceType = instanceConfig.getInstanceType();
- // 新创建实例所属于的安全组 ID。
String securityGroupId = instanceConfig.getSecurityGroupId();
- // 虚拟交换机 ID。
String vSwitchId = instanceConfig.getVSwitchId();
- // 公网出带宽最大值,单位为 Mbit/s。取值范围:0~100。 默认值:0。
Integer internetMaxBandwidthOut = com.aliyun.darabonbanumber.Client.parseInt(instanceConfig.getInternetMaxBandwidthOut());
- // 网络计费类型。取值范围:
- // PayByBandwidth: 按固定带宽计费。
- // PayByTraffic: 按使用流量计费。
- // 默认值:PayByTraffic。
String internetChargeType = instanceConfig.getInternetChargeType();
- // 系统盘大小
String size = instanceConfig.getSize();
- // 系统盘的云盘种类
String category = instanceConfig.getCategory();
- // ECS实例的计费方式
- // PrePaid:包年包月
- // PostPaid:按量付费
String instanceChargeType = instanceConfig.getInstanceChargeType();
@@ -213,7 +229,11 @@ public class AliYunEcsService {
}
- //查询实例信息
+ /**
+ * 查询实例信息
+ * @param instanceIds
+ * @return
+ */
public List queryInstancesInformation(String instanceIds) {
DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest()
diff --git a/src/main/java/com/loadCenter/aliyun/gateway/model/GatewayNodeInfo.java b/src/main/java/com/loadCenter/aliyun/gateway/model/GatewayNodeInfo.java
index e357236..61ed884 100644
--- a/src/main/java/com/loadCenter/aliyun/gateway/model/GatewayNodeInfo.java
+++ b/src/main/java/com/loadCenter/aliyun/gateway/model/GatewayNodeInfo.java
@@ -16,18 +16,42 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor
public class GatewayNodeInfo {
/**
- * 节点ID
+ * 实例ID
*/
- private String nodeId;
+ private String instanceId;
/**
- * 公网IP地址
+ * 名称
*/
- private String publicIdAddress;
+ private String instanceName;
/**
- * 内网IP地址
+ * 状态
*/
- private String privateIdAddress;
+ private String status;
+ /**
+ * 公网IP
+ */
+ private String publicIpAddress;
+
+ /**
+ * 私网IP
+ */
+ private String privateIpAddress;
+
+ /**
+ * 创建时间
+ */
+ private String creationTime;
+
+ /**
+ * 到期时间
+ */
+ private String expiredTime;
+
+ /**
+ * 是否可回收
+ */
+ private Boolean recyclable;
}
diff --git a/src/main/java/com/loadCenter/aliyun/handle/HandleCache.java b/src/main/java/com/loadCenter/aliyun/handle/HandleCache.java
index db5705f..8e2d211 100644
--- a/src/main/java/com/loadCenter/aliyun/handle/HandleCache.java
+++ b/src/main/java/com/loadCenter/aliyun/handle/HandleCache.java
@@ -10,13 +10,14 @@ import com.loadCenter.aliyun.gateway.model.NodeLoadNum;
import com.loadCenter.aliyun.gateway.model.NodeLoadWeight;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.List;
+import java.util.stream.Collectors;
/**
* @ClassName HandleCache
@@ -29,60 +30,313 @@ import java.util.List;
@Component
@AllArgsConstructor
public class HandleCache {
- @Autowired
- private MqttUtil mqttUtil;
- @Autowired
- private AliYunEcsService aliYunEcsService;
+ private final MqttUtil mqttUtil;
- /*
- * 操作网关节点缓存
- * */
- @Autowired
- private GatewayNodeInfoCache gatewayNodeInfoCache;
- /*
+ private final AliYunEcsService aliYunEcsService;
+
+ /**
+ * 网关节点缓存操作
+ */
+ private final GatewayNodeInfoCache gatewayNodeInfoCache;
+
+ /**
* 操作负载节点IP缓存
- * */
- @Autowired
- private GatewayNodeIPCache gatewayNodeIpCache;
+ */
+ private final GatewayNodeIPCache gatewayNodeIPCache;
- /*
- * 操作负载节点ID缓存
- * */
- @Autowired
- private GatewayNodeIDCache gatewayNodeIdCache;
+ /**
+ * 操作节点ID缓存
+ */
+ private final GatewayNodeIDCache gatewayNodeIDCache;
- /*
- * 操作实例IP和负载量缓存
- * */
- @Autowired
- private GatewayIpLoadCountKey gatewayIpLoadCountKey;
+ /**
+ * 操作节点权重缓存
+ */
+ private final GatewayWeightCache gatewayWeightCache;
- /*
- * 操作实例IP和权重缓存
- * */
- @Autowired
- private GatewayWeightCache gatewayWeightCache;
+ /**
+ * 操作节点IP负载计数缓存
+ */
+ private final GatewayIpLoadCountKey gatewayIpLoadCountKey;
- /*
- * 操作实例IP序列缓存
- * */
- @Autowired
- private GatewayOrderCache gatewayOrderCache;
+ /**
+ * 操作节点ID排序缓存
+ */
+ private final GatewayOrderCache gatewayOrderCache;
-// //刷新所有的缓存
-// @Scheduled(cron = "0/2 * * * * ?")
-// public void refreshAllCache() {
-// this.getNodeIDList();
-// this.getNodeInfos();
-// this.getNodeIPList();
-// this.getIpAndLoadCounts();
-// this.getIpAndWeights();
-// this.getLoadNodeOrderListByIpAndWeights();
-// }
+ /**
+ * 定时任务,每隔5秒执行一次
+ */
+ @Scheduled(fixedRate = 5000)
+ public void handleCache() {
+ //节点列表缓存刷新
+ this.getNodeIDList();
+ //实例信息缓存刷新
+ this.getNodeInfo();
+ //节点公网IP列表缓存刷新
+ this.getNodeIPList();
+ //各个IP的负载量缓存刷新
+ this.getIpAndLoadCounts();
+ //各个IP的权重缓存刷新
+ this.getIpAndWeights();
+ //负载节点IP序列缓存刷新
+ this.getLoadNodeOrderListByIpAndWeights();
+ }
+
+ /**
+ * 获取节点ID列表
+ */
+ @PostConstruct
+ public void getNodeIDList(){
+ try {
+ //获取实例列表
+ List idList = aliYunEcsService.getIDList();
+ //为空则创建新节点
+ if(idList == null || idList.isEmpty()){
+ aliYunEcsService.createAndRunInstance();
+ }
+ log.info("实例ID列表:{}", idList);
+ gatewayNodeIDCache.put(idList);
+ } catch (Exception e) {
+ log.error("获取实例ID列表失败:" + e.getMessage());
+ log.error(e.getMessage());
+ }
+ }
+
+ /**
+ * 获取实例信息
+ */
+ public void getNodeInfo() {
+ Long count = 0L;
+
+ ArrayList gatewayNodeInfos = new ArrayList<>();
+
+ try {
+
+ //获取ID集合
+ List ecsIDList = gatewayNodeIDCache.get();
+ if (ecsIDList == null || ecsIDList.isEmpty()) {
+ log.error("实例ID为空");
+ return;
+ }
+
+ StringBuilder ids = new StringBuilder();
+ for (String id : ecsIDList) {
+ ids.append(id).append(",");
+ }
+ ids = new StringBuilder(ids.substring(0, ids.length() - 1));
+
+ //查询所有ID实例的详细信息
+ List response = aliYunEcsService.queryInstancesInformation(ids.toString());
+ for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance item : response) {
+ log.info("查询第{}个实例的ID:{}" ,count+1, item.getInstanceId());
+
+ log.info("地域ID:{}",item.getRegionId());
+
+ log.info("CPU核心数:{}", item.getCpu());
+
+ log.info("内存大小:{}MB", item.getMemory());
+
+ log.info("公网出带宽值:{}Mbit/s",item.getInternetMaxBandwidthOut() + "");
+
+ log.info("公网IP:{}", UserUtil.removeBrackets(item.getPublicIpAddress().getIpAddress().toString()));
+
+ log.info("私网IP:{}", UserUtil.removeBrackets(item.getVpcAttributes().getPrivateIpAddress().ipAddress.toString()));
+
+ log.info("创建时间:{}",item.getCreationTime());
+
+ log.info("过期时间:{}",item.getExpiredTime());
+
+ log.info("是否可回收:{}",item.getRecyclable());
+
+ log.info("实例名称:{}",item.getInstanceName());
+
+ log.info("实例状态:{}",item.getStatus());
+
+ log.info("-----------------------------分割线-----------------------------------"+"/n/n/n");
+
+
+ //实例状态为运行中才加入列表
+ //停止的实例不加入列表
+ if(item.getStatus().equals("Stopped")){
+ //停止的实例不加入列表
+ log.info("实例状态为停止,不加入列表");
+ continue;
+ }
+ //运行中
+ if (item.getStatus().equals("Running")) {
+ //存入集合
+ gatewayNodeInfos.add(
+ new GatewayNodeInfo(
+ item.getInstanceId(),
+ item.getInstanceName(),
+ item.getStatus(),
+ UserUtil.removeBrackets(item.getPublicIpAddress().getIpAddress().toString()),
+ UserUtil.removeBrackets(item.getVpcAttributes().getPrivateIpAddress().ipAddress.toString()),
+ item.getCreationTime(),
+ item.getExpiredTime(),
+ item.getRecyclable()
+ )
+ );
+ count++;
+ }
+ }
+
+
+ } catch (Exception e) {
+ throw new RuntimeException("获取实例列表失败:" + e.getMessage());
+ }
+ log.info("实例信息列表:{}", gatewayNodeInfos);
+
+ //存入缓存
+ gatewayNodeInfoCache.put(gatewayNodeInfos);
+
+ }
+
+ /**
+ * 获取节点公网IP列表
+ */
+ public void getNodeIPList() {
+ //存IP的List
+ ArrayList nodeIPList = new ArrayList<>();
+
+ //从缓存中拿到实例信息列表
+ List gatewayNodeInfoList = gatewayNodeInfoCache.get();
+
+ if (gatewayNodeInfoList.isEmpty()) {
+ log.error("实例信息列表为空!");
+ return;
+ }
+
+ gatewayNodeInfoList.forEach(item -> {
+ //获取IP
+ String ip = item.getPublicIpAddress();
+ //存入集合
+ nodeIPList.add(ip);
+ });
+
+
+ log.info("实例公网IP列表:{}", nodeIPList);
+
+ //将IP列表存入redis
+ gatewayNodeIPCache.put(nodeIPList);
+
+ }
+
+ /**
+ * 获取各个IP的负载量
+ */
+ public void getIpAndLoadCounts() {
+ //从缓存中获取实例公网IP列表
+ List nodeIPList = gatewayNodeIPCache.get();
+ if (nodeIPList.isEmpty()) {
+ log.error("实例公网IP列表为空!");
+ return;
+ }
+
+ //存各个 服务器的负载量
+ ArrayList ipAndLoadCounts = new ArrayList<>();
+
+ //拿到IP后,获取各个IP的负载量
+ nodeIPList.forEach(ip -> {
+ ipAndLoadCounts.add(mqttUtil.getFetchLoad(ip));
+ });
+
+ log.info("各个IP的负载量:{}", ipAndLoadCounts);
+
+ gatewayIpLoadCountKey.put(ipAndLoadCounts);
+ }
+
+ /**
+ * 计算各个IP的权重
+ */
+ public void getIpAndWeights() {
+ //从缓存中获取公网IP和负载量列表
+ List ipAndLoadCounts = gatewayIpLoadCountKey.get();
+ if (ipAndLoadCounts.isEmpty()) {
+ log.error("负载量列表为空!");
+ return;
+ }
+
+
+ //求出空负载的总量
+ int emptyLoadCount = 0;
+ for (NodeLoadNum ipAndLoadCount : ipAndLoadCounts) {
+ //假设使用2/8原则 一个节点最多能有100个连接
+ emptyLoadCount += (80 - ipAndLoadCount.getLoadNum());
+ }
+
+ //存储IP和对应的权重
+ ArrayList ipAndWeights = new ArrayList<>();
+ for (NodeLoadNum ipAndLoadCount : ipAndLoadCounts) {
+
+ NodeLoadWeight ipAndWeight = new NodeLoadWeight(
+ ipAndLoadCount.getIpName(),
+ (80 - ipAndLoadCount.getLoadNum()) * 100 / emptyLoadCount
+ );
+ ipAndWeights.add(ipAndWeight);
+ }
+
+ log.info("实例IP和对应的权重:{}", ipAndWeights);//[IpAndWeight(nodeIp=47.102.158.233, weight=55), IpAndWeight(nodeIp=47.102.123.209, weight=44)]
+
+ gatewayWeightCache.put(ipAndWeights);
+ }
+
+ /**
+ * 获取负载节点IP序列
+ */
+ public void getLoadNodeOrderListByIpAndWeights() {
+ //从缓存中获取公网IP和权重列表
+ List ipAndWeights = gatewayWeightCache.get();
+ if (ipAndWeights.isEmpty()) {
+ log.error("负载节点IP和权重列表为空!");
+ return;
+ }
+
+ ArrayList loadNodeList = new ArrayList<>();
+
+ Long sum = ipAndWeights.stream()
+ .mapToLong(NodeLoadWeight::getWeight)
+ .sum();
+ if (sum < 100) {
+ List list = ipAndWeights.stream()
+ .sorted(Comparator.comparingLong(NodeLoadWeight::getWeight).reversed())
+ .collect(Collectors.toList());
+
+ //给权重高的节点 权重再加一个
+ int countWeight = 0;
+ for (Long i = sum; i < 100; i++) {
+ NodeLoadWeight ipAndWeight = list.get(countWeight++ % list.size());
+ ipAndWeight.setWeight(ipAndWeight.getWeight() + 1);
+ }
+ }
+
+ whFor:
+ while (true) {
+ for (NodeLoadWeight ipAndWeight : ipAndWeights) {
+ Long weight = ipAndWeight.getWeight();
+ if (weight > 0) {
+ loadNodeList.add(ipAndWeight.getIpName());
+ }
+ ipAndWeight.setWeight(weight - 1);
+ }
+
+ Long sum1 = ipAndWeights.stream()
+ .mapToLong(NodeLoadWeight::getWeight)
+ .sum();
+ if (sum1 <= 0) {
+ break whFor;
+ }
+ }
+
+
+ //IP序列存入缓存
+ gatewayOrderCache.put(loadNodeList);
+ }
}
diff --git a/src/main/java/com/loadCenter/aliyun/job/LoadCenterController.java b/src/main/java/com/loadCenter/aliyun/job/LoadCenterController.java
deleted file mode 100644
index daa017c..0000000
--- a/src/main/java/com/loadCenter/aliyun/job/LoadCenterController.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package com.loadCenter.aliyun.job;
-
-import com.alibaba.fastjson2.JSONArray;
-import com.alibaba.fastjson2.JSONObject;
-import com.loadCenter.aliyun.common.aliyun.service.AliYunEcsService;
-import lombok.extern.log4j.Log4j2;
-import okhttp3.OkHttpClient;
-import okhttp3.Request;
-import okhttp3.Response;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
-import com.loadCenter.aliyun.common.redis.service.RedisService;
-import java.util.Set;
-
-
-/**
- * @ClassName LoadCenterController
- * @Author ZeJinG.Su
- */
-@Component
-@Log4j2
-public class LoadCenterController {
- int aa=0;
- int bb=0;
- @Autowired
- StringRedisTemplate redisTemplate;
-
- @Autowired
- private RedisService redisService;
- @Autowired
- private AliYunEcsService aliYunEcsService;
-
- /*
- * 30秒扫描一次服务器,负载情况
- */
- @Scheduled(cron = "0/5 * * * * ?")
- public void scheduleECS() throws Exception {
- //假设这里出现了超出预设连接数大于80%,则进行扩容
- OkHttpClient client = new OkHttpClient();
- Set ipCacheSet = redisService.getCacheZSet("ECS");
- log.info("共有个"+ipCacheSet.size()+"服务器");
-
- for (String ip : ipCacheSet) {
-
- String URL = "http://"+ip+":8080/public/cluster";
- Request request = new Request.Builder()
- .url(URL)
- .get()
- .addHeader("User-Agent", "Apifox/1.0.0 (https://apifox.com)")
- .addHeader("Accesstoken", "")
- .build();
-
- try {
- Response response = client.newCall(request).execute();
-
- JSONArray jsonArray = JSONArray.parseArray(response.body().string());
- JSONObject jsonObject = jsonArray.getJSONObject(0);
- JSONObject mqttInfo = jsonObject.getJSONObject("mqttInfo");
- int connectSize = mqttInfo.getIntValue("connectSize");
-
- log.info("服务器:"+ip+"-车辆连接数:"+connectSize);
-
- redisService.setCacheZSet("ECS", ip,connectSize);
-
- if (connectSize>=5){
- aa++;
- log.info("服务器:"+ip+"-----"+aa+"=="+ipCacheSet.size()+"就可以扩容");
-
- if (aa==ipCacheSet.size()){
-
- log.info("服务器个数:"+ipCacheSet.size()+",-----循环第"+aa+"次,相等了,需要扩容");
- log.info("执行扩容机制");
-
- log.info("扩容中休眠5秒,再返回,确保先创建,确保查询得到结果-------");
- Thread.sleep(5000);
-
-
- log.info("实例id和公网ip存入redis");
- aa=0;
- }
-
- } else {
-
- aa=0;
- }
-
-
- } catch (Exception e) {
- e.printStackTrace();
- }
-
-
- }
-
-
- }
-
-
-
-
-}
diff --git a/src/main/java/com/loadCenter/aliyun/job/ScheduledTask.java b/src/main/java/com/loadCenter/aliyun/job/ScheduledTask.java
new file mode 100644
index 0000000..c970148
--- /dev/null
+++ b/src/main/java/com/loadCenter/aliyun/job/ScheduledTask.java
@@ -0,0 +1,137 @@
+package com.loadCenter.aliyun.job;
+
+import com.loadCenter.aliyun.common.aliyun.service.AliYunEcsService;
+import com.loadCenter.aliyun.gateway.cache.GatewayIpLoadCountKey;
+import com.loadCenter.aliyun.gateway.cache.GatewayNodeIDCache;
+import com.loadCenter.aliyun.gateway.cache.GatewayNodeInfoCache;
+import com.loadCenter.aliyun.gateway.model.GatewayNodeInfo;
+import com.loadCenter.aliyun.gateway.model.NodeLoadNum;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+
+/**
+ * @ClassName ScheduledTask
+ * @Author ZeJinG.Su
+ */
+@Component
+@Log4j2
+public class ScheduledTask {
+
+ /*
+ * 阿里云api接口类
+ * */
+ private final AliYunEcsService aliYunEcsService;
+
+ /*
+ * 操作缓存
+ * */
+ private final GatewayIpLoadCountKey gatewayIpLoadCountKey;
+
+ private final GatewayNodeIDCache gatewayNodeIdCache;
+
+ private final GatewayNodeInfoCache gatewayNodeInfoCache;
+
+ public ScheduledTask(AliYunEcsService aliYunEcsService, GatewayIpLoadCountKey gatewayIpLoadCountKey, GatewayNodeIDCache gatewayNodeIdCache, GatewayNodeInfoCache gatewayNodeInfoCache) {
+ this.aliYunEcsService = aliYunEcsService;
+ this.gatewayIpLoadCountKey = gatewayIpLoadCountKey;
+ this.gatewayNodeIdCache = gatewayNodeIdCache;
+ this.gatewayNodeInfoCache = gatewayNodeInfoCache;
+ }
+
+
+ @Scheduled(cron = "0/10 * * * * ?")
+ /**
+ * 动态扩容
+ */
+ public void dynamicExpansion() {
+ //先获取所有的负载列表
+ List ipAndLoadCounts = gatewayIpLoadCountKey.get();
+ if (ipAndLoadCounts.isEmpty()) {
+ log.error("负载量列表为空!");
+ return;
+ }
+
+ //计算所有节点的负载
+ Long connectSize = ipAndLoadCounts.stream().mapToLong(NodeLoadNum::getLoadNum).sum();
+
+ //求出平均值
+ Long 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 * * * * ?")
+ /**
+ * 动态缩容
+ */
+ public void dynamicReduction() {
+ //求出所有的节点ID
+ List nodeIds = gatewayNodeIdCache.get();
+
+ //如果节点数量小于等于1,则不执行缩容,至少保留一个节点
+ if (nodeIds.size() <= 1) {
+ log.info("暂无节点可删除!");
+ return;
+ }
+
+
+ //先获取所有的负载列表
+ List ipAndLoadCounts = gatewayIpLoadCountKey.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();
+ //获取当前循环节点的负载
+ Long loadCount = ipAndLoadCounts.stream().filter(ipAndLoadCount -> ipAndLoadCount.getIpName().equals(ip)).findFirst().get().getLoadNum();
+ //判断节点的负载是否小于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/main/java/com/loadCenter/aliyun/service/impl/GatewayLoadServiceImpl.java b/src/main/java/com/loadCenter/aliyun/service/impl/GatewayLoadServiceImpl.java
index 86f2f1e..f938e37 100644
--- a/src/main/java/com/loadCenter/aliyun/service/impl/GatewayLoadServiceImpl.java
+++ b/src/main/java/com/loadCenter/aliyun/service/impl/GatewayLoadServiceImpl.java
@@ -2,22 +2,41 @@ package com.loadCenter.aliyun.service.impl;
import com.loadCenter.aliyun.common.aliyun.config.Result;
+import com.loadCenter.aliyun.gateway.cache.GatewayOrderCache;
import com.loadCenter.aliyun.gateway.model.GatewayNodeInfo;
+import com.loadCenter.aliyun.handle.HandleCache;
import com.loadCenter.aliyun.service.GatewayLoadService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
+import java.util.List;
+
@Service
@AllArgsConstructor
public class GatewayLoadServiceImpl implements GatewayLoadService {
private final Long nodeLength = 100L;
+ /**
+ * 负载节点列表
+ */
+ private final HandleCache handleCache;
+ /**
+ * 负载节点信息列表
+ */
+ private final GatewayOrderCache gatewayOrderCache;
+ /**
+ * 获取负载节点的IP序列列表,并返回最后一个IP进行返回
+ * @return
+ */
@Override
public Result getAssignedServer() {
+ handleCache.getLoadNodeOrderListByIpAndWeights();
+ List nodeOrderList = gatewayOrderCache.get();
+ String result = nodeOrderList.get(nodeOrderList.size() - 1);
- return null;
+ return Result.success(result);
}
}
diff --git a/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 8192759..a9747b5 100644
--- a/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1,2 +1,3 @@
com.loadCenter.aliyun.common.redis.configure.RedisConfig
com.loadCenter.aliyun.common.redis.service.RedisService
+
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index e1391fb..4528a6d 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -1,10 +1,9 @@
-# Tomcat
server:
port: 9010
Spring:
redis:
host: 10.10.25.3
-# host: 127.0.0.1
+ # host: 127.0.0.1
port: 6379
password: fffdev