From 7dc10779355ae32d8621e66ebd4eb33a66f4c592 Mon Sep 17 00:00:00 2001
From: Wang Hao <3388656408@qq.com>
Date: Sat, 20 Apr 2024 10:29:23 +0800
Subject: [PATCH] 420
---
.gitignore | 39 ++
pom.xml | 193 +++++++++
.../java/com/muyu/LoadCenterApplication.java | 29 ++
.../java/com/muyu/aly/ALYunEcsService.java | 301 ++++++++++++++
.../java/com/muyu/aly/config/AliConfig.java | 91 +++++
.../com/muyu/aly/model/EcsRemoveModel.java | 33 ++
.../com/muyu/aly/model/EcsSelectModel.java | 37 ++
.../java/com/muyu/aly/model/InstanceInfo.java | 40 ++
.../muyu/common/constant/CacheConstants.java | 52 +++
.../muyu/common/constant/LoadConstants.java | 42 ++
.../java/com/muyu/common/domain/Result.java | 111 +++++
.../java/com/muyu/common/model/CPUInfo.java | 41 ++
.../java/com/muyu/common/model/FlowInfo.java | 38 ++
.../java/com/muyu/common/model/JVMInfo.java | 66 +++
.../java/com/muyu/common/model/MqttInfo.java | 61 +++
.../com/muyu/common/model/TotalNumber.java | 32 ++
.../FastJson2JsonRedisSerializer.java | 50 +++
.../common/redis/configure/RedisConfig.java | 43 ++
.../common/redis/service/RedisService.java | 386 ++++++++++++++++++
.../muyu/controller/GatewayController.java | 35 ++
.../com/muyu/gateway/cache/LoadNodeCache.java | 60 +++
.../muyu/gateway/cache/LoadSeriesCache.java | 59 +++
.../com/muyu/gateway/cache/NodeCache.java | 52 +++
.../com/muyu/gateway/cache/NodeReduced.java | 68 +++
.../muyu/gateway/cache/NodeScoreCache.java | 78 ++++
.../muyu/gateway/cache/NodeSetVinCache.java | 55 +++
.../gateway/cache/VehicleLineNodeCache.java | 63 +++
.../gateway/cache/abs/GatewayCacheAbs.java | 30 ++
.../java/com/muyu/gateway/model/NodeInfo.java | 39 ++
.../java/com/muyu/gateway/model/NodeJoin.java | 30 ++
.../com/muyu/gateway/model/NodeVehicle.java | 31 ++
.../muyu/gateway/model/WorkGatewayNode.java | 27 ++
.../com/muyu/service/GatewayLoadService.java | 16 +
.../service/impl/GatewayLoadServiceImpl.java | 203 +++++++++
src/main/java/com/muyu/task/Collection.java | 182 +++++++++
.../task/contraction/ContractionVolume.java | 129 ++++++
src/main/resources/application.yml | 17 +
src/test/java/com/muyu/LoadTest.java | 153 +++++++
38 files changed, 3012 insertions(+)
create mode 100644 .gitignore
create mode 100644 pom.xml
create mode 100644 src/main/java/com/muyu/LoadCenterApplication.java
create mode 100644 src/main/java/com/muyu/aly/ALYunEcsService.java
create mode 100644 src/main/java/com/muyu/aly/config/AliConfig.java
create mode 100644 src/main/java/com/muyu/aly/model/EcsRemoveModel.java
create mode 100644 src/main/java/com/muyu/aly/model/EcsSelectModel.java
create mode 100644 src/main/java/com/muyu/aly/model/InstanceInfo.java
create mode 100644 src/main/java/com/muyu/common/constant/CacheConstants.java
create mode 100644 src/main/java/com/muyu/common/constant/LoadConstants.java
create mode 100644 src/main/java/com/muyu/common/domain/Result.java
create mode 100644 src/main/java/com/muyu/common/model/CPUInfo.java
create mode 100644 src/main/java/com/muyu/common/model/FlowInfo.java
create mode 100644 src/main/java/com/muyu/common/model/JVMInfo.java
create mode 100644 src/main/java/com/muyu/common/model/MqttInfo.java
create mode 100644 src/main/java/com/muyu/common/model/TotalNumber.java
create mode 100644 src/main/java/com/muyu/common/redis/configure/FastJson2JsonRedisSerializer.java
create mode 100644 src/main/java/com/muyu/common/redis/configure/RedisConfig.java
create mode 100644 src/main/java/com/muyu/common/redis/service/RedisService.java
create mode 100644 src/main/java/com/muyu/controller/GatewayController.java
create mode 100644 src/main/java/com/muyu/gateway/cache/LoadNodeCache.java
create mode 100644 src/main/java/com/muyu/gateway/cache/LoadSeriesCache.java
create mode 100644 src/main/java/com/muyu/gateway/cache/NodeCache.java
create mode 100644 src/main/java/com/muyu/gateway/cache/NodeReduced.java
create mode 100644 src/main/java/com/muyu/gateway/cache/NodeScoreCache.java
create mode 100644 src/main/java/com/muyu/gateway/cache/NodeSetVinCache.java
create mode 100644 src/main/java/com/muyu/gateway/cache/VehicleLineNodeCache.java
create mode 100644 src/main/java/com/muyu/gateway/cache/abs/GatewayCacheAbs.java
create mode 100644 src/main/java/com/muyu/gateway/model/NodeInfo.java
create mode 100644 src/main/java/com/muyu/gateway/model/NodeJoin.java
create mode 100644 src/main/java/com/muyu/gateway/model/NodeVehicle.java
create mode 100644 src/main/java/com/muyu/gateway/model/WorkGatewayNode.java
create mode 100644 src/main/java/com/muyu/service/GatewayLoadService.java
create mode 100644 src/main/java/com/muyu/service/impl/GatewayLoadServiceImpl.java
create mode 100644 src/main/java/com/muyu/task/Collection.java
create mode 100644 src/main/java/com/muyu/task/contraction/ContractionVolume.java
create mode 100644 src/main/resources/application.yml
create mode 100644 src/test/java/com/muyu/LoadTest.java
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d0d38f1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,39 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+.idea
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..96e6623
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,193 @@
+
+
+ 4.0.0
+
+ com.muyu
+ LoadCenter
+ 1.0-SNAPSHOT
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ 2.7.18
+
+
+
+ com.aliyun
+ darabonba-string
+ 0.0.3
+
+
+ com.aliyun
+ tea
+ [1.0.3, 2.0.0)
+
+
+
+ com.aliyun
+ ecs20140526
+ 3.1.2
+
+
+ com.aliyun
+ tea-openapi
+ 0.3.2
+
+
+ com.aliyun
+ tea-util
+ 0.2.21
+
+
+ com.aliyun
+ tea-console
+ 0.0.1
+
+
+ com.aliyun
+ darabonba-env
+ 0.1.1
+
+
+ com.aliyun
+ tea
+ 1.1.14
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ 2.7.18
+ test
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+ 2.7.18
+
+
+ org.eclipse.paho
+ org.eclipse.paho.client.mqttv3
+ 1.2.5
+
+
+ com.alibaba.fastjson2
+ fastjson2
+ 2.0.47
+
+
+
+ org.redisson
+ redisson
+ 3.15.5
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+ provided
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.6.1
+
+ 16
+ 16
+
+
+
+ org.sonatype.plugins
+ nexus-staging-maven-plugin
+ 1.6.3
+ true
+
+ sonatype-nexus-staging
+ https://s01.oss.sonatype.org/
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.1.1
+
+ UTF-8
+ none
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.22.1
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.4.1
+
+
+ jar-with-dependencies
+
+
+
+ true
+ com.aliyun.sample.Sample
+
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/java/com/muyu/LoadCenterApplication.java b/src/main/java/com/muyu/LoadCenterApplication.java
new file mode 100644
index 0000000..6090b00
--- /dev/null
+++ b/src/main/java/com/muyu/LoadCenterApplication.java
@@ -0,0 +1,29 @@
+package com.muyu;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+/**
+ * @Author: wanghao //作者
+ * @CreateDate: 2024/4/12 22:14 //创建时间
+ */
+
+
+@SpringBootApplication
+@EnableScheduling
+public class LoadCenterApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(LoadCenterApplication.class, args);
+ }
+
+
+
+}
+
+
+
+
+
+
+
diff --git a/src/main/java/com/muyu/aly/ALYunEcsService.java b/src/main/java/com/muyu/aly/ALYunEcsService.java
new file mode 100644
index 0000000..7a7b28b
--- /dev/null
+++ b/src/main/java/com/muyu/aly/ALYunEcsService.java
@@ -0,0 +1,301 @@
+package com.muyu.aly;
+
+import com.alibaba.fastjson2.JSON;
+import com.aliyun.ecs20140526.Client;
+import com.aliyun.ecs20140526.models.*;
+import com.aliyun.tea.TeaException;
+
+import com.muyu.aly.config.AliConfig;
+import com.muyu.aly.model.EcsSelectModel;
+import com.muyu.aly.model.EcsRemoveModel;
+import com.muyu.aly.model.InstanceInfo;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.stereotype.Service;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * @Author: wanghao //作者
+ * @CreateDate: 2024/4/20 8:45 //创建时间
+ */
+
+@Service
+@Log4j2
+public class ALYunEcsService {
+
+ private final AliConfig aliConfig;
+
+ private final Client client;
+
+ public ALYunEcsService(AliConfig aliConfig, Client client) {
+ this.aliConfig = aliConfig;
+ this.client = client;
+ }
+
+ /**
+ * 根据实例ID和实例名称查询实例信息
+ * @param instanceName
+ * @return 返回实例集合信息
+ */
+ public List selectECS(String instanceName) throws Exception {
+
+ DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest()
+ .setRegionId(aliConfig.getRegionId())
+ .setInstanceName(instanceName)
+ .setPageSize(10);
+
+ com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
+
+ List instanceInfos = new ArrayList<>(); // 用于存储查询到的实例信息
+
+ try {
+ DescribeInstancesResponse describeInstancesResponse = client.describeInstancesWithOptions(describeInstancesRequest, runtime);
+ DescribeInstancesResponseBody body = describeInstancesResponse.getBody();
+ DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstances instances = body.getInstances();
+ List instanceList = instances.getInstance();
+
+ // 修改 selectECS 方法中 IP 地址的处理部分
+ for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance item : instanceList) {
+ InstanceInfo instanceInfo = new InstanceInfo();
+ instanceInfo.setInstanceId(item.getInstanceId());
+ instanceInfo.setInstanceName(item.getInstanceName());
+ String publicIpAddress = item.getPublicIpAddress().getIpAddress().toString();
+ // 去掉方括号
+ publicIpAddress = publicIpAddress.substring(1, publicIpAddress.length() - 1);
+ instanceInfo.setPublicIpAddress(publicIpAddress);
+ String privateIpAddress = item.getVpcAttributes().getPrivateIpAddress().ipAddress.toString();
+ // 去掉方括号
+ privateIpAddress = privateIpAddress.substring(1, privateIpAddress.length() - 1);
+ instanceInfo.setPrivateIpAddress(privateIpAddress);
+ instanceInfos.add(instanceInfo);
+ }
+ } catch (TeaException error) {
+ error.printStackTrace();
+ // 异常处理
+ } catch (Exception _error) {
+ _error.printStackTrace();
+ // 异常处理
+ }
+
+ return instanceInfos;
+ }
+
+
+
+ /**
+ * 创建实例方法
+ * @throws Exception
+ */
+ public String createAnServer(String isNull) throws Exception {
+ // 地域Id
+ //String regionId = "cn-shanghai";
+ String regionId = aliConfig.getRegionId();
+ // 镜像 ID,启动实例时选择的镜像资源。
+ // String imageId = "m-uf6elrscl3c9wk6o762l";
+ String imageId = aliConfig.getImageId();
+ // 实例规格
+ //String instanceType = "ecs.u1-c1m1.large";
+ String instanceType = aliConfig.getInstanceType();
+ // 新创建实例所属于的安全组 ID。
+ //String securityGroupId = "sg-uf6bj6vxp8ruhvffdsau";
+ String securityGroupId = aliConfig.getSecurityGroupId();
+ // 虚拟交换机 ID。
+ //String vSwitchId = "vsw-uf66jtgij0ptqxf1ix6l7 ";
+ String vSwitchId = aliConfig.getVSwitchId();
+ // 公网出带宽最大值,单位为 Mbit/s。取值范围:0~100。 默认值:0。
+ //Integer internetMaxBandwidthOut = Integer.parseInt("2");
+ Integer internetMaxBandwidthOut = Integer.parseInt(aliConfig.getInternetMaxBandwidthOut());
+ // 网络计费类型。取值范围:
+ // PayByBandwidth: 按固定带宽计费。
+ // PayByTraffic: 按使用流量计费。
+ // 默认值:PayByTraffic。
+ //String internetChargeType = "PayByTraffic";
+ String internetChargeType = aliConfig.getInternetChargeType();
+ // 系统盘大小
+ //String size = "20";
+ String size = aliConfig.getSize();
+ // 系统盘的云盘种类
+ //String category = "cloud_essd";
+ String category = aliConfig.getCategory();
+ // ECS实例的计费方式
+ // PrePaid:包年包月
+ // PostPaid:按量付费
+ //String instanceChargeType = "PostPaid";
+ String instanceChargeType = aliConfig.getInstanceChargeType();
+ // 创建 【1台】 实例
+ if (isNull == null){
+ String instances = RunInstance(client, regionId, imageId, instanceType, securityGroupId, vSwitchId, internetMaxBandwidthOut, internetChargeType, size, category, instanceChargeType);
+ return instances; //返回实例ID
+ }
+ // 批量创建实例
+ String instances = RunInstances(client, regionId, imageId, instanceType, securityGroupId, vSwitchId, internetMaxBandwidthOut, internetChargeType, size, category, instanceChargeType);
+ //返回实例ID
+ return instances;
+ }
+
+
+ /**
+ * 批量创建【2】台服务器
+ * RunInstances 通过备选实例规格创建ECS实例最佳实践
+ * 该场景中,在调用RunInstances创建ECS实例时判断是否发生库存不足等错误,如果发生错误,将调用DescribeRecommendInstanceType查询备选实例,然后通过备选实例规格重新创建ECS实例。
+ */
+ public 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 {
+ System.setOut(new java.io.PrintStream(System.out, true, "UTF-8"));
+ RunInstancesRequest request1 = new RunInstancesRequest()
+ .setRegionId(regionId)
+ .setImageId(imageId)
+ .setInstanceType(instanceType)
+ .setSecurityGroupId(securityGroupId)
+ .setVSwitchId(vSwitchId)
+ .setInstanceName("Myname")
+ .setDescription("Myprocure")
+ .setInternetMaxBandwidthOut(internetMaxBandwidthOut)
+ .setInternetChargeType(internetChargeType)
+ .setInstanceChargeType(instanceChargeType)
+ // 批量创建五台ECS实例,如果不设置该参数,默认创建一台ECS实例。
+ .setAmount(2)
+ // 如果缺少库存可以接受的最低创建数量。
+ // minAmount = 2,
+ // 打开预检参数功能,不会实际创建ECS实例,只检查参数正确性、用户权限或者ECS库存等问题。
+ // 实际情况下,设置了DryRun参数后,Amount必须为1,MinAmount必须为空,您可以根据实际需求修改代码。
+ .setDryRun(false)
+ .setSystemDisk(new RunInstancesRequest.RunInstancesRequestSystemDisk()
+ .setSize(size)
+ .setCategory(category));
+ RunInstancesResponse responces = client.runInstances(request1);
+ try {
+ log.info("--------------------批量创建实例开始--------------------");
+
+ log.info("--------------------创建实例成功,实例ID:" + JSON.toJSONString(responces.body.instanceIdSets.instanceIdSet) + "--------------------");
+ } catch (TeaException error) {
+ log.error("--------------------创建实例失败:" + error+ "--------------------");
+ } catch (Exception _error) {
+ TeaException error = new TeaException(_error.getMessage(), _error);
+ log.error("--------------------创建实例失败:" +error + "--------------------");
+ }
+ return JSON.toJSONString(responces.body.instanceIdSets.instanceIdSet);
+ }
+
+
+ /**
+ * 批量创建【1】台服务器
+ * RunInstances 通过备选实例规格创建ECS实例最佳实践
+ * 该场景中,在调用RunInstances创建ECS实例时判断是否发生库存不足等错误,如果发生错误,将调用DescribeRecommendInstanceType查询备选实例,然后通过备选实例规格重新创建ECS实例。
+ */
+ public String RunInstance(Client client, String regionId, String imageId, String instanceType, String securityGroupId, String vSwitchId, Integer internetMaxBandwidthOut, String internetChargeType, String size, String category, String instanceChargeType) throws Exception {
+ System.setOut(new java.io.PrintStream(System.out, true, "UTF-8"));
+ RunInstancesRequest request1 = new RunInstancesRequest()
+ .setRegionId(regionId)
+ .setImageId(imageId)
+ .setInstanceType(instanceType)
+ .setSecurityGroupId(securityGroupId)
+ .setVSwitchId(vSwitchId)
+ .setInstanceName("Myname")
+ .setDescription("Myprocure")
+ .setInternetMaxBandwidthOut(internetMaxBandwidthOut)
+ .setInternetChargeType(internetChargeType)
+ .setInstanceChargeType(instanceChargeType)
+ // 批量创建五台ECS实例,如果不设置该参数,默认创建一台ECS实例。
+ //.setAmount(2)
+ // 如果缺少库存可以接受的最低创建数量。
+ // minAmount = 2,
+ // 打开预检参数功能,不会实际创建ECS实例,只检查参数正确性、用户权限或者ECS库存等问题。
+ // 实际情况下,设置了DryRun参数后,Amount必须为1,MinAmount必须为空,您可以根据实际需求修改代码。
+ .setDryRun(false)
+ .setSystemDisk(new RunInstancesRequest.RunInstancesRequestSystemDisk()
+ .setSize(size)
+ .setCategory(category));
+ RunInstancesResponse responces = client.runInstances(request1);
+ try {
+ log.info("--------------------批量创建实例开始--------------------");
+
+ log.info("--------------------创建实例成功,实例ID:" + JSON.toJSONString(responces.body.instanceIdSets.instanceIdSet) + "--------------------");
+ } catch (TeaException error) {
+ log.error("--------------------创建实例失败:" + error+ "--------------------");
+ } catch (Exception _error) {
+ TeaException error = new TeaException(_error.getMessage(), _error);
+ log.error("--------------------创建实例失败:" +error + "--------------------");
+ }
+ return JSON.toJSONString(responces.body.instanceIdSets.instanceIdSet);
+ }
+
+
+ public DescribeInstancesResponse DescribeInstances(Client client, String regionId, String instanceIds, String instanceName) throws Exception {
+ DescribeInstancesRequest req = new DescribeInstancesRequest()
+ .setRegionId(regionId)
+ .setInstanceName(instanceName);
+ if (!com.aliyun.teautil.Common.empty(instanceIds)) {
+ req.instanceIds = JSON.toJSONString(com.aliyun.darabonbastring.Client.split(instanceIds, ",", 50));
+ }
+
+ DescribeInstancesResponse resp = client.describeInstances(req);
+ log.error("--------------------查询需要删除的实例--------------------");
+ return resp;
+ }
+
+ public void ModifyInstanceAttribute(Client client, String instatnceId) throws Exception {
+ ModifyInstanceAttributeRequest req = new ModifyInstanceAttributeRequest()
+ .setInstanceId(instatnceId)
+ .setDeletionProtection(false);
+ client.modifyInstanceAttribute(req);
+ log.info("--------------------" + instatnceId + "释放保护取消成功--------------------");
+ }
+
+ public void DeleteInstances(Client client, String regionId, String instanceIds, String force) throws Exception {
+ DeleteInstancesRequest req = new DeleteInstancesRequest()
+ .setRegionId(regionId)
+ .setInstanceId(com.aliyun.darabonbastring.Client.split(instanceIds, ",", 50))
+ .setForce(com.aliyun.teautil.Common.equalString(force, "true"));
+ DeleteInstancesResponse resp = client.deleteInstances(req);
+ log.info("--------------------实例释放成功--------------------");
+ log.info(JSON.toJSONString(com.aliyun.teautil.Common.toMap(resp)));
+ }
+
+ /**
+ * 批量删除实力
+ * @param
+ * @throws Exception
+ */
+ public void DeleServerCreateAn(EcsRemoveModel escRemoveModel) throws Exception {
+ // 区域ID
+ //String regionId = "cn-shanghai";
+ String regionId = aliConfig.getRegionId();
+ // 多个实例ID,用英文逗号分隔
+ //String instanceIds = "i-uf6h4s0jtpvobykd7vzc";
+ String instanceIds = escRemoveModel.getInstanceIds();
+ // 实例名称,支持使用通配符*进行模糊搜索
+ //String instanceName = "MyFirstEcsInstance";
+ String instanceName = escRemoveModel.getInstanceName();
+ // 强制删除有删除保护的机器
+ //String deleteProtected = "true";
+ String deleteProtected = "true";
+ // 强制删除运行中的机器
+ //String force = "true";
+ String force = "true";
+ if (com.aliyun.teautil.Common.equalString(deleteProtected, force)) {
+ DescribeInstancesResponse describeInstancesResp = DescribeInstances(client, regionId, instanceIds, instanceName);
+ instanceIds = "";
+ for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance instance : describeInstancesResp.body.instances.instance) {
+ instanceIds = "" + instance.instanceId + "," + instanceIds + "";
+ if (instance.deletionProtection) {
+ ModifyInstanceAttribute(client, instance.instanceId);
+ }
+
+ }
+ instanceIds = com.aliyun.darabonbastring.Client.subString(instanceIds, 0, -1);
+ }
+
+ if (com.aliyun.teautil.Common.empty(instanceIds)) {
+ log.info("--------------------无有效实例可删除--------------------");
+ return ;
+ }
+
+ DeleteInstances(client, regionId, instanceIds, force);
+ }
+
+}
+
+
diff --git a/src/main/java/com/muyu/aly/config/AliConfig.java b/src/main/java/com/muyu/aly/config/AliConfig.java
new file mode 100644
index 0000000..6717e04
--- /dev/null
+++ b/src/main/java/com/muyu/aly/config/AliConfig.java
@@ -0,0 +1,91 @@
+package com.muyu.aly.config;
+
+import com.aliyun.ecs20140526.Client;
+import com.aliyun.teaopenapi.models.Config;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+/**
+ * @Author: wanghao //作者
+ * @CreateDate: 2024/4/20 8:39 //创建时间
+ */
+
+
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "aliyun")
+public class AliConfig {
+
+ private String accessKeyId;
+
+ private String accessKeySecret;
+
+ /**
+ * 地域ID
+ */
+ private String regionId;
+
+ /**
+ * 镜像ID
+ */
+ private String imageId;
+
+ /**
+ * 实例规格
+ */
+ private String instanceType;
+
+ /**
+ * 安全组ID
+ */
+ private String securityGroupId;
+
+ /**
+ * 虚拟交换机ID
+ */
+ private String vSwitchId;
+
+ /**
+ * 公网出带宽最大值,单位为 Mbit/s。取值范围:0~100。 默认值:0。
+ */
+ private String internetMaxBandwidthOut;
+
+ /**
+ * 网络计费类型,取值范围
+ */
+ private String internetChargeType;
+
+ /**
+ * 系统盘大小
+ */
+ private String size;
+
+ /**
+ * 系统盘的云盘种类
+ */
+ private String category;
+
+ /**
+ * ECS实例的计费方式
+ */
+ private String instanceChargeType;
+
+ @Bean
+ public Client createClient(AliConfig aliConfig) throws Exception {
+ // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
+ // 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html。
+ Config config = new Config()
+ // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
+ .setAccessKeyId(aliConfig.getAccessKeyId())
+ // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
+ .setAccessKeySecret(aliConfig.accessKeySecret)
+ .setRegionId(aliConfig.getRegionId());
+ return new Client(config);
+ }
+
+}
+
+
diff --git a/src/main/java/com/muyu/aly/model/EcsRemoveModel.java b/src/main/java/com/muyu/aly/model/EcsRemoveModel.java
new file mode 100644
index 0000000..c6d053c
--- /dev/null
+++ b/src/main/java/com/muyu/aly/model/EcsRemoveModel.java
@@ -0,0 +1,33 @@
+package com.muyu.aly.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @Author: wanghao //作者
+ * @CreateDate: 2024/4/20 8:43 //创建时间
+ */
+
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class EcsRemoveModel {
+
+
+ /**
+ * 实例ID
+ */
+ private String instanceIds;
+
+ /**
+ * 实例名称
+ */
+ private String instanceName;
+
+}
+
+
diff --git a/src/main/java/com/muyu/aly/model/EcsSelectModel.java b/src/main/java/com/muyu/aly/model/EcsSelectModel.java
new file mode 100644
index 0000000..8b1102f
--- /dev/null
+++ b/src/main/java/com/muyu/aly/model/EcsSelectModel.java
@@ -0,0 +1,37 @@
+package com.muyu.aly.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * @Author: wanghao //作者
+ * @CreateDate: 2024/4/20 8:42 //创建时间
+ */
+
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class EcsSelectModel {
+
+ /**
+ * 实例Id
+ * */
+ private List instanceIdList;
+
+
+ /**
+ * 实例名称
+ * */
+ private List instanceNameList;
+
+
+
+}
+
+
diff --git a/src/main/java/com/muyu/aly/model/InstanceInfo.java b/src/main/java/com/muyu/aly/model/InstanceInfo.java
new file mode 100644
index 0000000..894f2c3
--- /dev/null
+++ b/src/main/java/com/muyu/aly/model/InstanceInfo.java
@@ -0,0 +1,40 @@
+package com.muyu.aly.model;
+
+import lombok.*;
+
+/**
+ * @Author: wanghao //作者
+ * @CreateDate: 2024/4/20 8:44 //创建时间
+ */
+
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@ToString
+public class InstanceInfo {
+
+ /**
+ * 节点ID
+ */
+ private String instanceId;
+
+ /**
+ * 节点名称
+ */
+ private String instanceName;
+
+ /**
+ * 公网IP地址
+ */
+ private String publicIpAddress;
+
+ /**
+ * 内网IP地址
+ */
+ private String privateIpAddress;
+
+}
+
+
diff --git a/src/main/java/com/muyu/common/constant/CacheConstants.java b/src/main/java/com/muyu/common/constant/CacheConstants.java
new file mode 100644
index 0000000..a390ee7
--- /dev/null
+++ b/src/main/java/com/muyu/common/constant/CacheConstants.java
@@ -0,0 +1,52 @@
+package com.muyu.common.constant;
+
+/**
+ * @Author: wanghao //作者
+ * @CreateDate: 2024/4/20 8:47 //创建时间
+ */
+
+
+public class CacheConstants {
+ /**
+ * 缓存有效时间 50分钟
+ */
+ public final static int EXPIRATIOTIME = 50;
+
+ /**
+ * 通用节点缓存前缀 encode
+ */
+ public final static String GATEWAY_COMMON = "gateway:load:";
+
+ /**
+ * 网关负载节点缓存
+ */
+ public final static String GATEWAY_LOAD_NODE_KEY = "node";
+
+ /**
+ * 网关负载序列
+ */
+ public final static String GATEWAY_LOAD_SERIES_KEY = "series";
+
+ /**
+ * 网关节点缓存前缀
+ */
+ public final static String GATE_WAY_NODE_INFO= "gateway:node:info:";
+
+ /**
+ * 网关节点连接数前缀
+ */
+ public final static String GATEWAY_NODE_SCORE_CACHE = "score";
+
+ /**
+ * 网关节点存储VIN信息
+ */
+ public final static String GATEWAY_VEHICLE= "gateway:vehicle:";
+
+ /**
+ * 网关车辆对应网关节点ID
+ */
+ public final static String GATEWAY_VEHICLE_LINE= "gateway:vehicleLine:";
+
+}
+
+
diff --git a/src/main/java/com/muyu/common/constant/LoadConstants.java b/src/main/java/com/muyu/common/constant/LoadConstants.java
new file mode 100644
index 0000000..35689a3
--- /dev/null
+++ b/src/main/java/com/muyu/common/constant/LoadConstants.java
@@ -0,0 +1,42 @@
+package com.muyu.common.constant;
+
+/**
+ * @Author: wanghao //作者
+ * @CreateDate: 2024/4/20 8:48 //创建时间
+ */
+
+
+public class LoadConstants {
+ /**
+ * 负载的长度
+ */
+ public final static Long NODE_LENGTH = 100L;
+
+ /**
+ * 每个节点最大连接数
+ */
+ public final static Long MAX_NUMBER = 100L;
+
+ /**
+ * 创建节点 判断
+ */
+ public final static String IS_NULL = "isNotNull";
+
+ /**
+ * 节点 扩容百分比 60% 一台
+ */
+ public final static Long INTERMEDIATE = 60L;
+
+ /**
+ * 节点 扩容百分比 80% 两台
+ */
+ public final static Long MAXIMUM = 80L;
+
+ /**
+ * 通用数值 100
+ */
+ public final static int BE_COMMON = 100;
+
+}
+
+
diff --git a/src/main/java/com/muyu/common/domain/Result.java b/src/main/java/com/muyu/common/domain/Result.java
new file mode 100644
index 0000000..d7890b1
--- /dev/null
+++ b/src/main/java/com/muyu/common/domain/Result.java
@@ -0,0 +1,111 @@
+package com.muyu.common.domain;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 响应信息主体
+ *
+ * @author muyu
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class Result implements Serializable {
+ /**
+ * 成功
+ */
+ public static final int SUCCESS = 200;
+ /**
+ * 失败
+ */
+ public static final int FAIL = 500;
+ /**
+ * 警告
+ */
+ public static final int WARN = 800;
+
+ private static final long serialVersionUID = 1L;
+ private int code;
+
+ private String msg;
+
+ private T data;
+
+ public static Result success () {
+ return restResult(null, SUCCESS, null);
+ }
+
+ public static Result success (T data) {
+ return restResult(data, SUCCESS, null);
+ }
+
+ public static Result success (T data, String msg) {
+ return restResult(data, SUCCESS, msg);
+ }
+
+ public static Result error () {
+ return restResult(null, FAIL, null);
+ }
+
+ public static Result error (String msg) {
+ return restResult(null, FAIL, msg);
+ }
+
+ public static Result error (T data) {
+ return restResult(data, FAIL, null);
+ }
+
+ public static Result error (T data, String msg) {
+ return restResult(data, FAIL, msg);
+ }
+
+ public static Result error (int code, String msg) {
+ return restResult(null, code, msg);
+ }
+
+
+
+ public static Result warn () {
+ return restResult(null, WARN, null);
+ }
+
+ public static Result warn (String msg) {
+ return restResult(null, WARN, msg);
+ }
+
+ public static Result warn (T data) {
+ return restResult(data, WARN, null);
+ }
+
+ public static Result warn (T data, String msg) {
+ return restResult(data, WARN, msg);
+ }
+
+ public static Result warn (int code, String msg) {
+ return restResult(null, code, msg);
+ }
+
+ private static Result restResult (T data, int code, String msg) {
+ return Result.builder()
+ .code(code)
+ .data(data)
+ .msg(msg)
+ .build();
+ }
+
+ public static Boolean isError (Result ret) {
+ return !isSuccess(ret);
+ }
+
+ public static Boolean isSuccess (Result ret) {
+ return Result.SUCCESS == ret.getCode();
+ }
+
+}
diff --git a/src/main/java/com/muyu/common/model/CPUInfo.java b/src/main/java/com/muyu/common/model/CPUInfo.java
new file mode 100644
index 0000000..eb6ec1b
--- /dev/null
+++ b/src/main/java/com/muyu/common/model/CPUInfo.java
@@ -0,0 +1,41 @@
+package com.muyu.common.model;
+
+import lombok.Data;
+
+/**
+ * @Author: wanghao //作者
+ * @CreateDate: 2024/4/20 8:49 //创建时间
+ */
+
+@Data
+public class CPUInfo {
+ /**
+ * CPU核数
+ */
+ private long cpuNum;
+ /**
+ * 内核态使用率
+ */
+ private String cSys;
+ /**
+ * 空闲率
+ */
+ private String idle;
+ /**
+ * I/O等待
+ */
+ private String iowait;
+ /**
+ * 用户态使用率
+ */
+ private String user;
+
+
+
+
+
+
+
+}
+
+
diff --git a/src/main/java/com/muyu/common/model/FlowInfo.java b/src/main/java/com/muyu/common/model/FlowInfo.java
new file mode 100644
index 0000000..c92a39a
--- /dev/null
+++ b/src/main/java/com/muyu/common/model/FlowInfo.java
@@ -0,0 +1,38 @@
+package com.muyu.common.model;
+
+import lombok.Data;
+
+/**
+ * @Author: wanghao //作者
+ * @CreateDate: 2024/4/20 8:49 //创建时间
+ */
+
+@Data
+public class FlowInfo {
+
+ /**
+ * 上次读取吞吐量
+ */
+ private String lastReadThroughput;
+ /**
+ * 上次写入吞吐量
+ */
+ private String lastWriteThroughput;
+ /**
+ * 读取总吞吐量
+ */
+ private String readBytesHistory;
+ /**
+ * 实写字节
+ */
+ private String realWriteBytes;
+ /**
+ * 写入总吞吐量
+ */
+ private String writeBytesHistory;
+
+
+
+}
+
+
diff --git a/src/main/java/com/muyu/common/model/JVMInfo.java b/src/main/java/com/muyu/common/model/JVMInfo.java
new file mode 100644
index 0000000..f5cd625
--- /dev/null
+++ b/src/main/java/com/muyu/common/model/JVMInfo.java
@@ -0,0 +1,66 @@
+package com.muyu.common.model;
+
+import lombok.Data;
+
+/**
+ * @Author: wanghao //作者
+ * @CreateDate: 2024/4/20 8:49 //创建时间
+ */
+
+@Data
+public class JVMInfo {
+
+
+ /**
+ * 文件描述(句柄)
+ */
+ private String fileDescriptors;
+ /**
+ * 堆内存
+ */
+ private String heapCommit;
+ /**
+ * 堆初始化空间
+ */
+ private String heapInit;
+ /**
+ * 堆最大内存
+ */
+ private String heapMax;
+ /**
+ * 堆使用空间
+ */
+ private String heapUsed;
+ /**
+ * JAVA目录
+ */
+ private String jdkHome;
+ /**
+ * JDK版本
+ */
+ private String jdkVersion;
+ /**
+ * 非堆空间
+ */
+ private String noHeapCommit;
+ /**
+ * 非堆初始化空间
+ */
+ private String noHeapInit;
+ /**
+ * 非堆最大空间
+ */
+ private String noHeapMax;
+ /**
+ * 非堆使用空间
+ */
+ private String noHeapUsed;
+ /**
+ * 线程数量
+ */
+ private long threadCount;
+
+
+}
+
+
diff --git a/src/main/java/com/muyu/common/model/MqttInfo.java b/src/main/java/com/muyu/common/model/MqttInfo.java
new file mode 100644
index 0000000..85daeb7
--- /dev/null
+++ b/src/main/java/com/muyu/common/model/MqttInfo.java
@@ -0,0 +1,61 @@
+package com.muyu.common.model;
+
+import lombok.Data;
+
+/**
+ * @Author: wanghao //作者
+ * @CreateDate: 2024/4/20 8:49 //创建时间
+ */
+
+
+@Data
+public class MqttInfo {
+
+ /**
+ * 关闭事件数量
+ */
+ private long closeEventSize;
+ /**
+ * 连接事件数量
+ */
+ private long connectEventSize;
+ /**
+ * 链接总数
+ */
+ private long connectSize;
+ /**
+ * 断开链接数量
+ */
+ private long disconnectEventSize;
+ /**
+ * 推送数量
+ */
+ private long publishEventSize;
+ /**
+ * 发布重试事件数量
+ */
+ private long publishRetryEventSize;
+ /**
+ * 保留消息数量
+ */
+ private long retainSize;
+ /**
+ * 订阅事件数量
+ */
+ private long subscribeEventSize;
+ /**
+ * 订阅数量
+ */
+ private long subscribeSize;
+ /**
+ * 主题数量
+ */
+ private long topicSize;
+ /**
+ * 取消订阅数量
+ */
+ private long unSubscribeEventSize;
+
+}
+
+
diff --git a/src/main/java/com/muyu/common/model/TotalNumber.java b/src/main/java/com/muyu/common/model/TotalNumber.java
new file mode 100644
index 0000000..536931e
--- /dev/null
+++ b/src/main/java/com/muyu/common/model/TotalNumber.java
@@ -0,0 +1,32 @@
+package com.muyu.common.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @Author: wanghao //作者
+ * @CreateDate: 2024/4/20 8:50 //创建时间
+ */
+
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class TotalNumber {
+
+ /**
+ * 节点数量
+ */
+ private Long nodeNumber;
+
+ /**
+ * 连接总数
+ */
+ private Long ConnectionTotal;
+
+}
+
+
diff --git a/src/main/java/com/muyu/common/redis/configure/FastJson2JsonRedisSerializer.java b/src/main/java/com/muyu/common/redis/configure/FastJson2JsonRedisSerializer.java
new file mode 100644
index 0000000..6079f51
--- /dev/null
+++ b/src/main/java/com/muyu/common/redis/configure/FastJson2JsonRedisSerializer.java
@@ -0,0 +1,50 @@
+package com.muyu.common.redis.configure;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.JSONWriter;
+import com.alibaba.fastjson2.filter.Filter;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.SerializationException;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Redis使用FastJson序列化
+ *
+ * @author muyu
+ */
+public class FastJson2JsonRedisSerializer implements RedisSerializer {
+
+ public static final String[] JSON_WHITELIST_STR = {"org.springframework", "com.muyu"};
+
+ public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
+
+ static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(JSON_WHITELIST_STR);
+
+ private Class clazz;
+
+ public FastJson2JsonRedisSerializer (Class clazz) {
+ super();
+ this.clazz = clazz;
+ }
+
+ @Override
+ public byte[] serialize (T t) throws SerializationException {
+ if (t == null) {
+ return new byte[0];
+ }
+ return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
+ }
+
+ @Override
+ public T deserialize (byte[] bytes) throws SerializationException {
+ if (bytes == null || bytes.length <= 0) {
+ return null;
+ }
+ String str = new String(bytes, DEFAULT_CHARSET);
+
+ return JSON.parseObject(str, clazz, AUTO_TYPE_FILTER);
+ }
+}
diff --git a/src/main/java/com/muyu/common/redis/configure/RedisConfig.java b/src/main/java/com/muyu/common/redis/configure/RedisConfig.java
new file mode 100644
index 0000000..1697d37
--- /dev/null
+++ b/src/main/java/com/muyu/common/redis/configure/RedisConfig.java
@@ -0,0 +1,43 @@
+package com.muyu.common.redis.configure;
+
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * redis配置
+ *
+ * @author muyu
+ */
+@Configuration
+@EnableCaching
+@AutoConfigureBefore(RedisAutoConfiguration.class)
+public class RedisConfig extends CachingConfigurerSupport {
+
+
+ @Bean
+ @SuppressWarnings(value = {"unchecked", "rawtypes"})
+ public RedisTemplate