代码优化,拆分
master
JangCan 2024-04-18 14:14:37 +08:00
parent fd259fcba6
commit f35e44a18b
1 changed files with 108 additions and 38 deletions

View File

@ -12,16 +12,18 @@ import com.loadcenter.common.utils.mqtt.MqttUtil;
import com.loadcenter.service.LoadCenterService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName LoadCenterServiceImpl
* @Description
* @Author Can.J
* @Date 2024/4/16
* @ClassName LoadCenterServiceImpl
* @Description
* @Author Can.J
* @Date 2024/4/16
*/
@Service
@Slf4j
@ -33,73 +35,143 @@ public class LoadCenterServiceImpl implements LoadCenterService {
@Autowired
private AliYunEcsService aliYunEcsService;
@Scheduled(cron = "0/2 * * * * ?")
public void refreshECSIPListCache() {
getECSIPList();
}
/**
* IP
*
* @return
*/
@Override
public Result<String> getAssignedServer() {
//从缓存中获取实例公网IP列表
if (redis.getCacheList("实例IP列表").isEmpty()) {
throw new RuntimeException("实例IP列表为空!");
}
//将结果转成JSON串
String string = JSON.toJSONString(redis.getCacheList("实例IP列表:"));
//再转成String泛型 的 List
List<String> escIPList = JSON.parseArray(string, String.class);
//通过IP列表 获取各个IP对应的负载量
List<IpAndLoadCount> ipAndLoadCounts = this.getIpAndLoadCounts(escIPList);
//通过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);
}
/**
* IP
*/
@PostConstruct
public void getECSIPList() {
//存IP的List
ArrayList<String> ipList = new ArrayList<>();
//获取张家口区的实例ID列表
ArrayList<String> ecsIPList = new ArrayList<>();
try {
//获取张家口区的实例ID列表
List<String> ecsIDList = aliYunEcsService.getIDList();
List<String> idList = aliYunEcsService.getIDList();
idList.forEach(id -> {
//调用方法获取对应ID实例的IP
try {
List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> result = aliYunEcsService.queryInstancesInformation(id);
//将ID进行拼接用逗号分隔
String ids = "";
for (String id : ecsIDList) {
ids += id + ",";
}
ids = ids.substring(0, ids.length() - 1);
//获取集合第一个的属性
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());
}
List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> response = aliYunEcsService.queryInstancesInformation(ids);
response.forEach(item -> {
//获取添加的实例的公网ipe
String ip = UserUtil.removeBrackets(item.getPublicIpAddress().getIpAddress().toString());
ecsIPList.add(ip);
});
} catch (Exception e) {
log.error(e.getMessage());
log.error("获取实例ID列表失败{}", e.getMessage());
throw new RuntimeException(e);
}
log.info(JSON.toJSONString(ipList));
//将IP列表存入redis
redis.deleteObject("服务器列表:");
redis.setCacheList("服务器列表:", ipList);
redis.deleteObject("实例IP列表:");
redis.setCacheList("实例IP列表:", ecsIPList);
log.info("实例公网IP列表:{}", ecsIPList);
}
/**
* @ClassName LoadCenterServiceImpl
* @Description IPIP
* @Author Can.J
* @Date 2024/4/18
*/
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;
}
/**
* @ClassName LoadCenterServiceImpl
* @Description IPIP
* @Author Can.J
* @Date 2024/4/18
*/
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));
log.info("实例IP和对应的权重{}", ipAndWeights);//[IpAndWeight(nodeIp=47.102.158.233, weight=55), IpAndWeight(nodeIp=47.102.123.209, weight=44)]
return ipAndWeights;
}
/**
* @ClassName LoadCenterServiceImpl
* @Description IPIP
* @Author Can.J
* @Date 2024/4/18 14:09
*/
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();
@ -128,16 +200,14 @@ public class LoadCenterServiceImpl implements LoadCenterService {
break whFor;
}
}
//节点IP列表存入缓存
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;
}
}