4-21
parent
a889cd9388
commit
9803ea2248
|
@ -0,0 +1,46 @@
|
||||||
|
######################################################################
|
||||||
|
# Build Tools
|
||||||
|
|
||||||
|
.gradle
|
||||||
|
/build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# IDE
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### JRebel ###
|
||||||
|
rebel.xml
|
||||||
|
### NetBeans ###
|
||||||
|
nbproject/private/
|
||||||
|
build/*
|
||||||
|
nbbuild/
|
||||||
|
dist/
|
||||||
|
nbdist/
|
||||||
|
.nb-gradle/
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Others
|
||||||
|
*.log
|
||||||
|
*.xml.versionsBackup
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
!*/build/*.java
|
||||||
|
!*/build/*.html
|
||||||
|
!*/build/*.xml
|
|
@ -97,8 +97,8 @@ public class ALYunEcsService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实例ID查询实例
|
* 实例ID查询实例
|
||||||
* @param ecsSelectModel
|
* @param ecsSelectModel 入参
|
||||||
* @return
|
* @return 返回InstanceInfo节点信息对象
|
||||||
*/
|
*/
|
||||||
public InstanceInfo selectInstanceId(EcsSelectModel ecsSelectModel) {
|
public InstanceInfo selectInstanceId(EcsSelectModel ecsSelectModel) {
|
||||||
|
|
||||||
|
@ -165,44 +165,6 @@ public class ALYunEcsService {
|
||||||
return new InstanceInfo();
|
return new InstanceInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<InstanceInfo> selectInstance(EcsSelectModel ecsSelectModel) throws Exception {
|
|
||||||
List<InstanceInfo> instan = new ArrayList<>();
|
|
||||||
// 1. 初始化配置
|
|
||||||
Config config = new Config();
|
|
||||||
// 您的AccessKey ID
|
|
||||||
config.accessKeyId = aliConfig.getAccessKeyId();
|
|
||||||
// 您的AccessKey Secret
|
|
||||||
config.accessKeySecret = aliConfig.getAccessKeySecret();
|
|
||||||
//设置请求地址
|
|
||||||
config.endpoint = aliConfig.getEndpoint();
|
|
||||||
// 设置连接超时为5000毫秒
|
|
||||||
config.connectTimeout = 5000;
|
|
||||||
// 设置读超时为5000毫秒
|
|
||||||
config.readTimeout = 5000;
|
|
||||||
// 2. 初始化客户端
|
|
||||||
Client client = new Client(config);
|
|
||||||
java.util.List<String> regionIds = com.aliyun.darabonbastring.Client.split(ecsSelectModel.getInstanceIdList().toString(), ",", 50);
|
|
||||||
for (String regionId : regionIds) {
|
|
||||||
DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest()
|
|
||||||
.setPageSize(100)
|
|
||||||
.setRegionId(regionId);
|
|
||||||
DescribeInstancesResponse resp = client.describeInstances(describeInstancesRequest);
|
|
||||||
java.util.List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> instances = resp.body.instances.instance;
|
|
||||||
com.aliyun.teaconsole.Client.log("" + regionId + " 下 ECS 实例列表:");
|
|
||||||
for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance instance : instances) {
|
|
||||||
InstanceInfo instanceInfo = new InstanceInfo();
|
|
||||||
instanceInfo.setInstanceId(instance.getInstanceId());
|
|
||||||
instanceInfo.setInstanceName(instance.getInstanceName());
|
|
||||||
instanceInfo.setPublicIpAddress(instance.getPublicIpAddress().toString());
|
|
||||||
instanceInfo.setPrivateIpAddress(instance.getVpcAttributes().getPrivateIpAddress().toString());
|
|
||||||
instan.add(instanceInfo);
|
|
||||||
com.aliyun.teaconsole.Client.log(" " + instance.hostName + " 实例ID " + instance.instanceId + " CPU:" + instance.cpu + " 内存:" + instance.memory + " MB 规格:" + instance.instanceType + " 系统:" + instance.OSType + "(" + instance.OSName + ") 状态:" + instance.status + "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return instan;
|
|
||||||
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 创建实例方法
|
* 创建实例方法
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
|
@ -245,11 +207,11 @@ public class ALYunEcsService {
|
||||||
String instanceChargeType = aliConfig.getInstanceChargeType();
|
String instanceChargeType = aliConfig.getInstanceChargeType();
|
||||||
// 创建 【1台】 实例
|
// 创建 【1台】 实例
|
||||||
if (isNull == null){
|
if (isNull == null){
|
||||||
String instances = RunInstance(client, regionId, imageId, instanceType, securityGroupId, vSwitchId, internetMaxBandwidthOut, internetChargeType, size, category, instanceChargeType);
|
String instances = runInstance(client, regionId, imageId, instanceType, securityGroupId, vSwitchId, internetMaxBandwidthOut, internetChargeType, size, category, instanceChargeType);
|
||||||
return instances; //返回实例ID
|
return instances; //返回实例ID
|
||||||
}
|
}
|
||||||
// 批量创建实例
|
// 批量创建实例
|
||||||
String instances = RunInstances(client, regionId, imageId, instanceType, securityGroupId, vSwitchId, internetMaxBandwidthOut, internetChargeType, size, category, instanceChargeType);
|
String instances = runInstances(client, regionId, imageId, instanceType, securityGroupId, vSwitchId, internetMaxBandwidthOut, internetChargeType, size, category, instanceChargeType);
|
||||||
//返回实例ID
|
//返回实例ID
|
||||||
return instances;
|
return instances;
|
||||||
}
|
}
|
||||||
|
@ -260,7 +222,7 @@ public class ALYunEcsService {
|
||||||
* RunInstances 通过备选实例规格创建ECS实例最佳实践
|
* RunInstances 通过备选实例规格创建ECS实例最佳实践
|
||||||
* 该场景中,在调用RunInstances创建ECS实例时判断是否发生库存不足等错误,如果发生错误,将调用DescribeRecommendInstanceType查询备选实例,然后通过备选实例规格重新创建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 {
|
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"));
|
System.setOut(new java.io.PrintStream(System.out, true, "UTF-8"));
|
||||||
RunInstancesRequest request1 = new RunInstancesRequest()
|
RunInstancesRequest request1 = new RunInstancesRequest()
|
||||||
.setRegionId(regionId)
|
.setRegionId(regionId)
|
||||||
|
@ -303,7 +265,7 @@ public class ALYunEcsService {
|
||||||
* RunInstances 通过备选实例规格创建ECS实例最佳实践
|
* RunInstances 通过备选实例规格创建ECS实例最佳实践
|
||||||
* 该场景中,在调用RunInstances创建ECS实例时判断是否发生库存不足等错误,如果发生错误,将调用DescribeRecommendInstanceType查询备选实例,然后通过备选实例规格重新创建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 {
|
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"));
|
System.setOut(new java.io.PrintStream(System.out, true, "UTF-8"));
|
||||||
RunInstancesRequest request1 = new RunInstancesRequest()
|
RunInstancesRequest request1 = new RunInstancesRequest()
|
||||||
.setRegionId(regionId)
|
.setRegionId(regionId)
|
||||||
|
@ -341,77 +303,44 @@ public class ALYunEcsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public DescribeInstancesResponse DescribeInstances(Client client, String regionId, String instanceIds, String instanceName) throws Exception {
|
/**
|
||||||
DescribeInstancesRequest req = new DescribeInstancesRequest()
|
* 根据实例ID批量删除实例
|
||||||
.setRegionId(regionId)
|
* @param instanceIds 包含实例ID的模型
|
||||||
.setInstanceName(instanceName);
|
* @throws Exception
|
||||||
if (!com.aliyun.teautil.Common.empty(instanceIds)) {
|
*/
|
||||||
req.instanceIds = JSON.toJSONString(com.aliyun.darabonbastring.Client.split(instanceIds, ",", 50));
|
public void deleServerCreateAn(String instanceIds) throws Exception {
|
||||||
|
// 获取区域ID
|
||||||
|
String regionId = aliConfig.getRegionId();
|
||||||
|
|
||||||
|
// 如果实例ID为空,则直接返回
|
||||||
|
if (com.aliyun.teautil.Common.empty(instanceIds)) {
|
||||||
|
log.info("--------------------实例ID为空,无有效实例可删除--------------------");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DescribeInstancesResponse resp = client.describeInstances(req);
|
// 删除实例
|
||||||
log.error("--------------------查询需要删除的实例--------------------");
|
deleteInstances(client, regionId, instanceIds);
|
||||||
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
|
* @param client 阿里云客户端
|
||||||
|
* @param regionId 区域ID
|
||||||
|
* @param instanceIds 实例ID列表,逗号分隔
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void DeleServerCreateAn(EscRemoveModel escRemoveModel) throws Exception {
|
private void deleteInstances(Client client, String regionId, String instanceIds) throws Exception {
|
||||||
// 区域ID
|
// 创建删除实例请求
|
||||||
//String regionId = "cn-shanghai";
|
DeleteInstancesRequest req = new DeleteInstancesRequest()
|
||||||
String regionId = aliConfig.getRegionId();
|
.setRegionId(regionId)
|
||||||
// 多个实例ID,用英文逗号分隔
|
.setInstanceId(com.aliyun.darabonbastring.Client.split(instanceIds, ",", 50));
|
||||||
//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);
|
DeleteInstancesResponse resp = client.deleteInstances(req);
|
||||||
}
|
|
||||||
|
|
||||||
if (com.aliyun.teautil.Common.empty(instanceIds)) {
|
// 打印删除结果
|
||||||
log.info("--------------------无有效实例可删除--------------------");
|
log.info("--------------------实例释放成功--------------------");
|
||||||
return ;
|
log.info(JSON.toJSONString(com.aliyun.teautil.Common.toMap(resp)));
|
||||||
}
|
|
||||||
|
|
||||||
DeleteInstances(client, regionId, instanceIds, force);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,14 @@ import org.springframework.context.annotation.Configuration;
|
||||||
@ConfigurationProperties(prefix = "aliyun")
|
@ConfigurationProperties(prefix = "aliyun")
|
||||||
public class AliConfig {
|
public class AliConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 访问密钥
|
||||||
|
*/
|
||||||
private String accessKeyId;
|
private String accessKeyId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API请求签名
|
||||||
|
*/
|
||||||
private String accessKeySecret;
|
private String accessKeySecret;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,6 +82,12 @@ public class AliConfig {
|
||||||
*/
|
*/
|
||||||
private String endpoint;
|
private String endpoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建阿里云客户端对象 初始化Client 交由Spring管理
|
||||||
|
* @param aliConfig 配置信息
|
||||||
|
* @return 返回client
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public Client createClient(AliConfig aliConfig) throws Exception {
|
public Client createClient(AliConfig aliConfig) throws Exception {
|
||||||
// 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
|
// 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
|
||||||
|
|
|
@ -16,7 +16,7 @@ import java.util.List;
|
||||||
@Builder
|
@Builder
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class EcsSelectModel {
|
public class EcsSelectModel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 实例ID
|
* 实例ID
|
||||||
|
|
|
@ -57,6 +57,16 @@ public class Constans {
|
||||||
*/
|
*/
|
||||||
public final static Long NUMERICAL_VALUE_LONG_ZERO = 0L;
|
public final static Long NUMERICAL_VALUE_LONG_ZERO = 0L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断对错 默认错
|
||||||
|
*/
|
||||||
|
public final static Boolean IS_BOOLEAN_METHOD_FALSE= false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断对错 默认对
|
||||||
|
*/
|
||||||
|
public final static Boolean IS_BOOLEAN_METHOD_TRUE= true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.guo.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author gxb
|
||||||
|
* @description 配置RESTful客户端发送HTTP请求
|
||||||
|
* @date 2024-04-15 17:20
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class RestClientConfig {
|
||||||
|
@Bean
|
||||||
|
public RestTemplate restTemplate(){
|
||||||
|
return new RestTemplate();
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,8 @@ public class GateWayController {
|
||||||
private GateWayLoadService gateWayLoadService;
|
private GateWayLoadService gateWayLoadService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取负载节点
|
* 车辆上线
|
||||||
|
* @param VehicleVIN 车辆VIN
|
||||||
* @return 返回公网IP
|
* @return 返回公网IP
|
||||||
*/
|
*/
|
||||||
@PostMapping("/load/node/{VehicleVIN}")
|
@PostMapping("/load/node/{VehicleVIN}")
|
||||||
|
@ -27,4 +28,12 @@ public class GateWayController {
|
||||||
return Result.success(gateWayLoadService.loadNode(VehicleVIN));
|
return Result.success(gateWayLoadService.loadNode(VehicleVIN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆下线
|
||||||
|
* @param VehicleVIN 车辆VIN
|
||||||
|
*/
|
||||||
|
@PostMapping("/vehicle/removal/{VehicleVIN}")
|
||||||
|
public void vehicleRemoval(@PathVariable("VehicleVIN") String VehicleVIN){
|
||||||
|
gateWayLoadService.vehicleRemoval(VehicleVIN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,8 @@ package com.guo.service.impl;
|
||||||
public interface GateWayLoadService {
|
public interface GateWayLoadService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取负载节点
|
* 车辆上线
|
||||||
|
* @param VehicleVIN 车辆VIN
|
||||||
* @return 返回公网IP
|
* @return 返回公网IP
|
||||||
*/
|
*/
|
||||||
String loadNode(String VehicleVIN);
|
String loadNode(String VehicleVIN);
|
||||||
|
@ -18,4 +19,9 @@ public interface GateWayLoadService {
|
||||||
*/
|
*/
|
||||||
void refreshLoad();
|
void refreshLoad();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆下线
|
||||||
|
* @param vehicleVIN 车辆VIN
|
||||||
|
*/
|
||||||
|
void vehicleRemoval(String vehicleVIN);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.guo.service.impl;
|
package com.guo.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.guo.common.constant.LoadConstants;
|
import com.guo.common.constant.LoadConstants;
|
||||||
import com.guo.gateway.cache.*;
|
import com.guo.gateway.cache.*;
|
||||||
import com.guo.gateway.model.NodeInfo;
|
import com.guo.gateway.model.NodeInfo;
|
||||||
|
@ -12,6 +14,7 @@ import org.springframework.stereotype.Service;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author gxb
|
* @author gxb
|
||||||
|
@ -73,11 +76,15 @@ public class GateWayLoadServicelmpl implements GateWayLoadService {
|
||||||
Long seriesLoadIndex = seriesLoad % LoadConstants.NODE_LENGTH;
|
Long seriesLoadIndex = seriesLoad % LoadConstants.NODE_LENGTH;
|
||||||
//获取负载下标通过获取节点ID
|
//获取负载下标通过获取节点ID
|
||||||
String loadNodeId = loadNodeCache.getFindByIndex(seriesLoadIndex);
|
String loadNodeId = loadNodeCache.getFindByIndex(seriesLoadIndex);
|
||||||
|
|
||||||
//存储 key:实例ID value:VIN
|
//存储 key:实例ID value:VIN
|
||||||
NodeVehicle nodeVehicle = new NodeVehicle();
|
NodeVehicle nodeVehicle = new NodeVehicle();
|
||||||
nodeVehicle.setNodeId(loadNodeId);
|
nodeVehicle.setNodeId(loadNodeId);
|
||||||
nodeVehicle.setVehicleVin(VehicleVIN);
|
nodeVehicle.setVehicleVin(VehicleVIN);
|
||||||
|
//存入车辆VIN 和 节点ID
|
||||||
vehicleLineNodeCache.save(nodeVehicle);
|
vehicleLineNodeCache.save(nodeVehicle);
|
||||||
|
//存入车辆信息 key:车辆VIN 值nodeVehicle
|
||||||
|
nodeSetVinCache.put(nodeVehicle);
|
||||||
//获取缓存内节点的公网/内网信息
|
//获取缓存内节点的公网/内网信息
|
||||||
NodeInfo nodeInfo = nodeCache.get(loadNodeId);
|
NodeInfo nodeInfo = nodeCache.get(loadNodeId);
|
||||||
// 返回公网IP
|
// 返回公网IP
|
||||||
|
@ -117,11 +124,6 @@ public class GateWayLoadServicelmpl implements GateWayLoadService {
|
||||||
.build())
|
.build())
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
|
||||||
System.out.println(workGatewayNodes);
|
|
||||||
|
|
||||||
System.out.println(workGatewayNodeWeight);
|
|
||||||
|
|
||||||
List<String> loadNodeList = new ArrayList<>();
|
List<String> loadNodeList = new ArrayList<>();
|
||||||
|
|
||||||
int count = workGatewayNodeWeight.stream().mapToInt(WorkGatewayNode::getWeight).sum();
|
int count = workGatewayNodeWeight.stream().mapToInt(WorkGatewayNode::getWeight).sum();
|
||||||
|
@ -169,6 +171,34 @@ public class GateWayLoadServicelmpl implements GateWayLoadService {
|
||||||
// refreshLoadLock.unlock();
|
// refreshLoadLock.unlock();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆下线
|
||||||
|
* @param vehicleVIN 车辆VIN
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void vehicleRemoval(String vehicleVIN) {
|
||||||
|
//对应节点下的车辆VIN剔除
|
||||||
|
String nodeVehicleString = nodeSetVinCache.get(vehicleVIN);
|
||||||
|
NodeVehicle nodeVehicle = JSONObject.parseObject(nodeVehicleString, NodeVehicle.class);
|
||||||
|
//节点ID
|
||||||
|
String nodeId = nodeVehicle.getNodeId();
|
||||||
|
|
||||||
|
//获取车辆VIN集合
|
||||||
|
Set<String> vinSetList = vehicleLineNodeCache.get(nodeId);
|
||||||
|
//剔除掉下线的车辆VIN
|
||||||
|
for (String vin : vinSetList) {
|
||||||
|
if (!vehicleVIN.equals(vin)){
|
||||||
|
NodeVehicle Vehicle = new NodeVehicle();
|
||||||
|
Vehicle.setNodeId(nodeId);
|
||||||
|
Vehicle.setVehicleVin(vin);
|
||||||
|
//存入车辆VIN 和 节点ID
|
||||||
|
vehicleLineNodeCache.save(nodeVehicle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 动态ECS
|
* 动态ECS
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,6 +19,7 @@ import okhttp3.Response;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -26,10 +27,11 @@ import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author gxb
|
* @author gxb
|
||||||
* @description 定时器去扫描节点情况
|
* @description 定时器扫描节点情况
|
||||||
* @date 2024-04-18 19:01
|
* @date 2024-04-18 19:01
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
|
@Service
|
||||||
@Log4j2
|
@Log4j2
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class Collection {
|
public class Collection {
|
||||||
|
@ -150,7 +152,7 @@ public class Collection {
|
||||||
nodeJoin.setLinkingNumber(Long.valueOf(connectSize));
|
nodeJoin.setLinkingNumber(Long.valueOf(connectSize));
|
||||||
nodeScoreCache.save(nodeJoin);
|
nodeScoreCache.save(nodeJoin);
|
||||||
|
|
||||||
//加层判断,把不满足缩容条件的缓存删除 连接数 > 最低阈值
|
//判断,把不满足缩容条件的缓存删除 连接数 > 最低阈值 且 记录过
|
||||||
if (connectSize > beforemaxNumber && nodeReduced.isWhether(instance.getInstanceId())) {
|
if (connectSize > beforemaxNumber && nodeReduced.isWhether(instance.getInstanceId())) {
|
||||||
nodeReduced.remove(instance.getInstanceId());
|
nodeReduced.remove(instance.getInstanceId());
|
||||||
}
|
}
|
||||||
|
@ -172,7 +174,11 @@ public class Collection {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询节点连接数
|
||||||
|
* @param publicIPaddress 公网IP地址
|
||||||
|
* @return 返回连接数 int
|
||||||
|
*/
|
||||||
public int querymqttConnections(String publicIPaddress){
|
public int querymqttConnections(String publicIPaddress){
|
||||||
|
|
||||||
//获取每个FluxMQ运行信息
|
//获取每个FluxMQ运行信息
|
||||||
|
|
|
@ -1,21 +1,31 @@
|
||||||
package com.guo.task.Contraction;
|
package com.guo.task.Contraction;
|
||||||
|
|
||||||
import com.guo.aly.ALYunEcsService;
|
import com.guo.aly.ALYunEcsService;
|
||||||
|
import com.guo.aly.model.EscRemoveModel;
|
||||||
|
import com.guo.common.constant.Constans;
|
||||||
import com.guo.common.constant.LoadConstants;
|
import com.guo.common.constant.LoadConstants;
|
||||||
|
import com.guo.common.domain.Result;
|
||||||
import com.guo.common.model.TotalNumber;
|
import com.guo.common.model.TotalNumber;
|
||||||
|
import com.guo.config.RestClientConfig;
|
||||||
import com.guo.gateway.cache.NodeReduced;
|
import com.guo.gateway.cache.NodeReduced;
|
||||||
|
import com.guo.gateway.cache.NodeScoreCache;
|
||||||
import com.guo.gateway.cache.VehicleLineNodeCache;
|
import com.guo.gateway.cache.VehicleLineNodeCache;
|
||||||
|
import com.guo.gateway.model.NodeJoin;
|
||||||
|
import com.guo.gateway.model.WorkGatewayNode;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
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 org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author gxb
|
* @author gxb
|
||||||
* @description 扩缩容
|
* @description 节点扩缩容
|
||||||
* @date 2024-04-18 19:52
|
* @date 2024-04-18 19:52
|
||||||
*/
|
*/
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ -28,6 +38,10 @@ public class ContractionVolume {
|
||||||
*/
|
*/
|
||||||
private final VehicleLineNodeCache vehicleLineNodeCache;
|
private final VehicleLineNodeCache vehicleLineNodeCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网关节点连接数
|
||||||
|
*/
|
||||||
|
private final NodeScoreCache nodeScoreCache;
|
||||||
/**
|
/**
|
||||||
* 数值 5
|
* 数值 5
|
||||||
*/
|
*/
|
||||||
|
@ -36,6 +50,9 @@ public class ContractionVolume {
|
||||||
@Autowired
|
@Autowired
|
||||||
private ALYunEcsService alYunEcsService;
|
private ALYunEcsService alYunEcsService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缩容缓存
|
* 缩容缓存
|
||||||
*/
|
*/
|
||||||
|
@ -43,9 +60,9 @@ public class ContractionVolume {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缩容
|
* 缩容
|
||||||
* @param nodeId
|
* @param nodeId 节点ID
|
||||||
*/
|
*/
|
||||||
public void reduction(String nodeId){
|
public void reduction(String nodeId) throws Exception {
|
||||||
//非空判断
|
//非空判断
|
||||||
if (null != nodeId){
|
if (null != nodeId){
|
||||||
//判断是否被标记过
|
//判断是否被标记过
|
||||||
|
@ -59,16 +76,52 @@ public class ContractionVolume {
|
||||||
|
|
||||||
//比较 剩余时间 小于5分钟
|
//比较 剩余时间 小于5分钟
|
||||||
if (expire < fiveMinutesSeconds){
|
if (expire < fiveMinutesSeconds){
|
||||||
|
|
||||||
|
//默认false
|
||||||
|
boolean flag = Constans.IS_BOOLEAN_METHOD_FALSE;
|
||||||
|
|
||||||
//根据节点ID获取缓存内的车辆VIN值
|
//根据节点ID获取缓存内的车辆VIN值
|
||||||
Set<String> vehicleVinSetList = vehicleLineNodeCache.get(nodeId);
|
Set<String> vehicleVinSetList = vehicleLineNodeCache.get(nodeId);
|
||||||
|
|
||||||
//判断是否存在车辆信息
|
//判断是否存在车辆信息
|
||||||
if (!vehicleVinSetList.isEmpty()){
|
if (!vehicleVinSetList.isEmpty()){
|
||||||
|
|
||||||
//执行下线
|
//执行下线
|
||||||
|
for (String vehicleVin : vehicleVinSetList) {
|
||||||
|
//通过RestTemplate发送http请求车辆下线操作 选择要释放节点下的车辆信息
|
||||||
|
String url = "http://127.0.0.1:81/vehicle/instance/client/close/"+vehicleVin;
|
||||||
|
//响应
|
||||||
|
restTemplate.postForObject(url, null, Result.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
flag = Constans.IS_BOOLEAN_METHOD_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//删除节点 释放
|
||||||
|
alYunEcsService.deleServerCreateAn(nodeId);
|
||||||
|
|
||||||
//删除节点信息
|
//刷新连接数和IP地址
|
||||||
|
List<WorkGatewayNode> workGatewayNodes = nodeScoreCache.getNodeScore();
|
||||||
|
for (WorkGatewayNode workGatewayNode : workGatewayNodes) {
|
||||||
|
if (!nodeId.equals(workGatewayNode.getNodeId())){
|
||||||
|
NodeJoin nodeJoin = new NodeJoin();
|
||||||
|
nodeJoin.setNodeId(workGatewayNode.getNodeId());
|
||||||
|
nodeJoin.setLinkingNumber(Long.valueOf(String.valueOf(workGatewayNode.getWeight())));
|
||||||
|
nodeScoreCache.save(nodeJoin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//车辆上线
|
||||||
|
if (flag){
|
||||||
|
|
||||||
|
//执行重新下线
|
||||||
|
for (String vehicleVin : vehicleVinSetList) {
|
||||||
|
//通过RestTemplate发送http请求车辆上线操作 选择要释放节点下的车辆信息
|
||||||
|
String url = "http://127.0.0.1:81/vehicle/instance/client/init/" + vehicleVin;
|
||||||
|
restTemplate.postForObject(url, null, Result.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//记录
|
//记录
|
||||||
|
@ -79,7 +132,7 @@ public class ContractionVolume {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扩容
|
* 扩容
|
||||||
* @param totalNumber
|
* @param totalNumber 封装记录节点数量 - 节点总连接数
|
||||||
*/
|
*/
|
||||||
public void contractionVolume(TotalNumber totalNumber){
|
public void contractionVolume(TotalNumber totalNumber){
|
||||||
//特殊情况 无节点
|
//特殊情况 无节点
|
||||||
|
@ -88,7 +141,8 @@ public class ContractionVolume {
|
||||||
log.error("当前未存在节点信息");
|
log.error("当前未存在节点信息");
|
||||||
try {
|
try {
|
||||||
//创建实例方法 【2台】
|
//创建实例方法 【2台】
|
||||||
//alYunEcsService.createAnServer(LoadConstants.IS_NULL);
|
alYunEcsService.createAnServer(null);
|
||||||
|
Thread.sleep(5000);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("扩容失败!!!!!");
|
log.error("扩容失败!!!!!");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -98,13 +152,17 @@ public class ContractionVolume {
|
||||||
}
|
}
|
||||||
//调用计算
|
//调用计算
|
||||||
Long value = this.percentage(totalNumber);
|
Long value = this.percentage(totalNumber);
|
||||||
|
|
||||||
|
log.info("当前节点负载率:" + value + "%");
|
||||||
|
|
||||||
//判断达到60%
|
//判断达到60%
|
||||||
if (value >= LoadConstants.INTERMEDIATE && value < LoadConstants.MAXIMUM){
|
if (value >= LoadConstants.INTERMEDIATE && value < LoadConstants.MAXIMUM){
|
||||||
//当节点负载达到 60%时,调用扩容一台方法
|
//当节点负载达到 60%时,调用扩容一台方法
|
||||||
log.info("Node 节点负载达到 :" + value + "%,达到扩容一台的条件☑");
|
log.info("Node 节点负载达到 :" + value + "%,达到扩容一台的条件☑");
|
||||||
try {
|
try {
|
||||||
//创建实例方法 【1台】
|
//创建实例方法 【1台】
|
||||||
//alYunEcsService.createAnServer(null);
|
alYunEcsService.createAnServer(null);
|
||||||
|
Thread.sleep(5000);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("扩容失败!!!!!");
|
log.error("扩容失败!!!!!");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -117,6 +175,7 @@ public class ContractionVolume {
|
||||||
try {
|
try {
|
||||||
//创建实例方法 【2台】
|
//创建实例方法 【2台】
|
||||||
// alYunEcsService.createAnServer(LoadConstants.IS_NULL);
|
// alYunEcsService.createAnServer(LoadConstants.IS_NULL);
|
||||||
|
Thread.sleep(5000);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("扩容失败!!!!!");
|
log.error("扩容失败!!!!!");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -126,21 +185,21 @@ public class ContractionVolume {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算百分比方法
|
* 计算负载率
|
||||||
*/
|
*/
|
||||||
private Long percentage(TotalNumber totalNumber){
|
private Long percentage(TotalNumber totalNumber){
|
||||||
//获取节点数量
|
//获取节点数量
|
||||||
Long nodeNumber = totalNumber.getNodeNumber();
|
Long nodeNumber = totalNumber.getNodeNumber();
|
||||||
//根据nodeNumber去获取最大节点数 默认 100
|
//根据nodeNumber去获取最大节点数 默认 80
|
||||||
Long sumNodeNumber = nodeNumber * LoadConstants.MAX_NUMBER;
|
Long sumNodeNumber = nodeNumber * LoadConstants.MAXIMUM;
|
||||||
//获取节点连接总数
|
//获取节点连接总数
|
||||||
Long connectionTotal = totalNumber.getConnectionTotal();
|
Long connectionTotal = totalNumber.getConnectionTotal();
|
||||||
//计算空余连接数
|
//计算空余连接数
|
||||||
// Long vacantNumber = sumNodeNumber - connectionTotal;
|
// Long vacantNumber = sumNodeNumber - connectionTotal;
|
||||||
//计算当前负载情况
|
//计算当前负载情况 连接总数 / 最大连接数
|
||||||
double loadPercentage = (double)connectionTotal / sumNodeNumber;
|
double loadPercentage = (double)connectionTotal / sumNodeNumber;
|
||||||
//进行四舍五入取整
|
//进行四舍五入取整
|
||||||
long roundLoadPercentage = Math.round(loadPercentage) * LoadConstants.BE_COMMON;
|
long roundLoadPercentage = Math.round(loadPercentage * LoadConstants.BE_COMMON);
|
||||||
//返回百分比
|
//返回百分比
|
||||||
return roundLoadPercentage;
|
return roundLoadPercentage;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ spring:
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
port: 6379
|
port: 6379
|
||||||
|
|
||||||
|
# 阿里云配置
|
||||||
aliyun:
|
aliyun:
|
||||||
accessKeyId: LTAI5tPDLpTbAX9bUSrTSrPH
|
accessKeyId: LTAI5tPDLpTbAX9bUSrTSrPH
|
||||||
accessKeySecret: rbLG6bh8ZSttUPMxUspk9j8XLzvLU0
|
accessKeySecret: rbLG6bh8ZSttUPMxUspk9j8XLzvLU0
|
||||||
|
|
Loading…
Reference in New Issue