parent
fd259fcba6
commit
f35e44a18b
|
@ -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 通过IP获取各个IP的负载量
|
||||
* @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 通过IP和对应的负载量,计算出IP对应的权重
|
||||
* @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 通过IP和权重,计算负载节点的IP列表
|
||||
* @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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue