第5次优化 代码业务分离

master
liuyunhu 2024-04-17 20:21:17 +08:00
parent 6e588ec204
commit ff7dfdc1e4
5 changed files with 164 additions and 100 deletions

30
pom.xml
View File

@ -99,41 +99,11 @@
<!-- 阿里云openAPI释放实例依赖 开始 -->
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>tea-console</artifactId>-->
<!-- <version>0.0.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>darabonba-env</artifactId>-->
<!-- <version>0.1.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>tea-openapi</artifactId>-->
<!-- <version>0.0.11</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>ecs20140526</artifactId>-->
<!-- <version>1.0.1</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>tea-util</artifactId>-->
<!-- <version>0.2.10</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>darabonba-string</artifactId>
<version>0.0.3</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.aliyun</groupId>-->
<!-- <artifactId>tea</artifactId>-->
<!-- <version>[1.0.3, 2.0.0)</version>-->
<!-- </dependency>-->
<!-- 阿里云openAPI释放实例依赖 结束 -->
</dependencies>

View File

@ -6,11 +6,11 @@ import com.aliyun.ecs20140526.models.*;
import com.aliyun.tea.TeaException;
import com.aliyun.teautil.Common;
import com.aliyun.teautil.models.RuntimeOptions;
import com.lyh.common.aliyun.model.InstanceSpecification;
import com.lyh.common.aliyun.config.AliConfig;
import com.lyh.domain.InstancesInformation;
import com.lyh.common.aliyun.model.InstanceSpecification;
import com.lyh.common.redis.service.RedisService;
import com.lyh.common.utils.user.UserUtil;
import com.lyh.domain.InstancesInformation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@ -111,7 +111,7 @@ public class AliYunEcsService {
DescribeInstancesResponse describeInstancesResp = DescribeInstances(client, aliConfig.getRegionId(), instanceIds, instanceName);
instanceIds = "";
for (DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance instance : describeInstancesResp.body.instances.instance) {
instanceIds = "" + instance.instanceId + "," + instanceIds + "";
instanceIds = instance.instanceId + "," + instanceIds;
if (instance.deletionProtection) {
ModifyInstanceAttribute(client, instance.instanceId);
}
@ -276,7 +276,7 @@ public class AliYunEcsService {
* @Description:
* @Param: [instanceIds] i-uf6chlqotgoc9h173alu
**/
public List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> queryInstancesInformation(String instanceIds) throws Exception {
public List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> queryInstancesInformation(String instanceIds) {
//初始化计数器
AtomicInteger count = new AtomicInteger();
@ -364,4 +364,6 @@ public class AliYunEcsService {
}
return instances;
}
}

View File

@ -48,25 +48,29 @@ public class Timer {
log.info(String.valueOf(response));
JSONArray jsonArray = JSONArray.parseArray(response.body().string());
JSONObject jsonObject = jsonArray.getJSONObject(0);
//获取mqttInfo对象的值
JSONObject mqttInfo = jsonObject.getJSONObject("mqttInfo");
//获取连接数
int connectSize = mqttInfo.getIntValue("connectSize");
JSONArray jsonArray = null;
if (null != response.body()) {
jsonArray = JSONArray.parseArray(response.body().string());
log.info(ip + " 的fluxmq连接数为" + connectSize);
JSONObject jsonObject = jsonArray.getJSONObject(0);
//获取mqttInfo对象的值
JSONObject mqttInfo = jsonObject.getJSONObject("mqttInfo");
//获取连接数
int connectSize = mqttInfo.getIntValue("connectSize");
log.info(ip + " 的fluxmq连接数为" + connectSize);
if (connectSize >= 80) {
//执行节点扩容
if (connectSize >= 80) {
//执行节点扩容
//返回实例的ID
String instanceId = aliYunEcsService.createAndRunInstance();
//返回实例的ID
String instanceId = aliYunEcsService.createAndRunInstance();
if (!instanceId.isEmpty()) {
log.info("扩容 成功!");
log.info("扩容的节点ip为" + instanceId);
if (!instanceId.isEmpty()) {
log.info("扩容 成功!");
log.info("扩容的节点ip为" + instanceId);
}
}
}
@ -76,4 +80,6 @@ public class Timer {
}
}

View File

@ -3,17 +3,18 @@ package com.lyh.service.impl;
import com.alibaba.fastjson2.JSON;
import com.aliyun.ecs20140526.models.DescribeInstancesResponseBody;
import com.lyh.common.aliyun.service.AliYunEcsService;
import com.lyh.common.redis.service.RedisService;
import com.lyh.common.utils.mqtt.MqttUtil;
import com.lyh.common.utils.user.UserUtil;
import com.lyh.domain.IpAndLoadCount;
import com.lyh.domain.IpAndWeight;
import com.lyh.domain.resp.Result;
import com.lyh.common.redis.service.RedisService;
import com.lyh.common.utils.user.UserUtil;
import com.lyh.common.utils.mqtt.MqttUtil;
import com.lyh.service.LoadCenterService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
@ -45,75 +46,150 @@ public class LoadCenterServiceImpl implements LoadCenterService {
@Override
public Result<String> getAssignedServer() {
//存IP的List
ArrayList<String> ipList = new ArrayList<>();
//获取上海区的实例ID列表
try {
//刷新一下 实例公网IP列 缓存
this.getEcsIPList();
List<String> idList = aliYunEcsService.getIDList();
idList.forEach(id -> {
//调用方法获取对应ID实例的IP
try {
List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> result = aliYunEcsService.queryInstancesInformation(id);
//获取集合第一个的属性
DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance response = result.get(0);
//获取添加的实例的公网ip
String instanceIp = UserUtil.removeBrackets(response.getPublicIpAddress().getIpAddress().toString());
ipList.add(instanceIp);
} catch (Exception e) {
log.error(e.getMessage());
}
});
} catch (Exception e) {
log.error(e.getMessage());
//从缓存中获取实例公网IP列表
if (redis.getCacheList("实例IP列表:").isEmpty()) {
throw new RuntimeException("实例IP列表为空");
}
log.info(JSON.toJSONString(ipList));
//将结果转成JSON串
String string = JSON.toJSONString(redis.getCacheList("实例IP列表:"));
//再转成String泛型 的 List
List<String> ecsIPList = JSON.parseArray(string, String.class);
//通过IP列表 获取各个IP对应的负载量
List<IpAndLoadCount> ipAndLoadCounts = this.getIpAndLoadCounts(ecsIPList);
//通过IP和对应的负载量计算出IP对应的权重
List<IpAndWeight> ipAndWeights = this.getIpAndWeights(ipAndLoadCounts);
//通过IP和权重计算负载节点的IP列表
List<String> loadNodeList = this.getLoadNodeListByIpAndWeights(ipAndWeights);
//获取缓存里最后一个IP进行返回
//最后一个IP进行返回
String result = loadNodeList.get(loadNodeList.size() - 1);
return Result.success(result);
}
/*
* @Author: LiuYunHu
* @Date: 2024/4/17 17:14
* @Description: IP
* @Param: []
* @Return: List<String>
**/
@PostConstruct
public void getEcsIPList() {
//存IP的List
ArrayList<String> ecsIPList = new ArrayList<>();
try {
//获取上海区的实例ID列表
List<String> ecsIDList = aliYunEcsService.getIDList();
//将ID进行拼接用逗号分隔
String ids = "";
for (String id : ecsIDList) {
ids += id + ",";
}
ids = ids.substring(0, ids.length() - 1);
List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> response = aliYunEcsService.queryInstancesInformation(ids);
response.forEach(item -> {
//获取添加的实例的公网ip
String ip = UserUtil.removeBrackets(item.getPublicIpAddress().getIpAddress().toString());
ecsIPList.add(ip);
});
} catch (Exception e) {
log.error("获取实例ID列表失败{}", e.getMessage());
throw new RuntimeException(e);
}
//将IP列表存入redis
redis.deleteObject("服务器列表:");
redis.setCacheList("服务器列表:", ipList);
redis.deleteObject("实例IP列表:");
redis.setCacheList("实例IP列表:", ecsIPList);
log.info("实例公网IP列表:{}", ecsIPList);
}
/*
* @Author: LiuYunHu
* @Date: 2024/4/17 19:41
* @Description: IPIP
* @Param: ecsIPList
* @Return: List<IpAndLoadCount>
**/
public List<IpAndLoadCount> getIpAndLoadCounts(List<String> ecsIPList) {
//存各个 服务器的负载量
ArrayList<IpAndLoadCount> ipAndLoadCounts = new ArrayList<>();
ipList.forEach(ip -> {
//拿到IP后获取各个IP的负载量
//拿到IP后获取各个IP的负载量
ecsIPList.forEach(ip -> {
int fetchLoad = mqttUtil.getFetchLoad(ip);
ipAndLoadCounts.add(new IpAndLoadCount(ip, fetchLoad));
});
log.info("各个IP的负载量{}", ipAndLoadCounts);
return ipAndLoadCounts;
}
/*
* @Author: LiuYunHu
* @Date: 2024/4/17 19:49
* @Description: IPIP
* @Param: ipAndLoadCountList
* @Return: List<IpAndWeight>
**/
public List<IpAndWeight> getIpAndWeights(List<IpAndLoadCount> ipAndLoadCounts) {
//求出空负载的总量
int emptyLoadCount = 0;
for (IpAndLoadCount ipAndLoadCount : ipAndLoadCounts) {
//假设使用2/8原则
//假设使用2/8原则 一个节点最多能有100个连接
emptyLoadCount += (80 - ipAndLoadCount.getLoadCount());
}
//存储IP和对应的权重
ArrayList<IpAndWeight> ipAndWeights = new ArrayList<>();
for (IpAndLoadCount ipAndLoadCount : ipAndLoadCounts) {
IpAndWeight ipAndWeight = new IpAndWeight(ipAndLoadCount.getIp(), (80 - ipAndLoadCount.getLoadCount()) * 100 / emptyLoadCount);
IpAndWeight ipAndWeight = new IpAndWeight(
ipAndLoadCount.getIp(),
(80 - ipAndLoadCount.getLoadCount()) * 100 / emptyLoadCount
);
ipAndWeights.add(ipAndWeight);
}
log.info(JSON.toJSONString(ipAndWeights));//[IpAndWeight(nodeIp=47.102.158.233, weight=55), IpAndWeight(nodeIp=47.102.123.209, weight=44)]
log.info("实例IP和对应的权重{}", ipAndWeights);//[IpAndWeight(nodeIp=47.102.158.233, weight=55), IpAndWeight(nodeIp=47.102.123.209, weight=44)]
return ipAndWeights;
}
//*******************************************以下为改老师的代码
/*
* @Author: LiuYunHu
* @Date: 2024/4/17 20:02
* @Description: IPIP TODO
* @Param: []
* @Return:
**/
public List<String> getLoadNodeListByIpAndWeights(List<IpAndWeight> ipAndWeights) {
ArrayList<String> loadNodeList = new ArrayList<>();
int sum = ipAndWeights.stream().mapToInt(IpAndWeight::getWeight).sum();
int sum = ipAndWeights.stream()
.mapToInt(IpAndWeight::getWeight)
.sum();
if (sum < 100) {
List<IpAndWeight> list = ipAndWeights.stream().sorted(((o1, o2) -> o2.getWeight() - o1.getWeight())).toList();
@ -147,14 +223,9 @@ public class LoadCenterServiceImpl implements LoadCenterService {
redis.deleteObject("work:node:gateway");
redis.setCacheList("work:node:gateway", loadNodeList);
//获取缓存里最后一个IP进行返回
//最后一个IP进行返回
String result = loadNodeList.get(loadNodeList.size() - 1);
return Result.success(result);
log.info("负载节点的IP列表{}", loadNodeList);
return loadNodeList;
}
}

View File

@ -1,7 +1,6 @@
import com.aliyun.ecs20140526.models.DescribeInstancesResponseBody;
import com.lyh.LoadCenterApplication;
import com.lyh.common.aliyun.service.AliYunEcsService;
import com.lyh.common.redis.service.RedisService;
import com.lyh.common.utils.user.UserUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -20,8 +19,6 @@ import java.util.List;
@SpringBootTest(classes = LoadCenterApplication.class)
@Slf4j
public class Test {
@Autowired
private RedisService redisService;
@Autowired
private AliYunEcsService aliYunEcsService;
@ -75,7 +72,7 @@ public class Test {
**/
@org.junit.jupiter.api.Test
public void releaseInstances() throws Exception {
aliYunEcsService.releaseInstances("i-uf6if4mw6iu6rjffrs2c,i-uf6a4lwh3qdqwa5t5237");
aliYunEcsService.releaseInstances("i-uf624nmh7j2nzlzxnd1u");
}
/*
@ -90,8 +87,26 @@ public class Test {
String instanceId = aliYunEcsService.createAndRunInstance();
System.out.println(instanceId);
}
@org.junit.jupiter.api.Test
public void aaaaaa() {
//获取上海区的实例ID列表
List<String> ecsIDList = null;
try {
ecsIDList = aliYunEcsService.getIDList();
} catch (Exception e) {
throw new RuntimeException(e);
}
//将ID进行拼接用逗号分隔
String ids = "";
for (String id : ecsIDList) {
ids += id + ",";
}
ids = ids.substring(0, ids.length() - 1);
log.info(ids);
}
}