parent
fd259fcba6
commit
f35e44a18b
|
@ -12,16 +12,18 @@ import com.loadcenter.common.utils.mqtt.MqttUtil;
|
||||||
import com.loadcenter.service.LoadCenterService;
|
import com.loadcenter.service.LoadCenterService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ClassName LoadCenterServiceImpl
|
* @ClassName LoadCenterServiceImpl
|
||||||
* @Description 负载中心业务实现层
|
* @Description 负载中心业务实现层
|
||||||
* @Author Can.J
|
* @Author Can.J
|
||||||
* @Date 2024/4/16
|
* @Date 2024/4/16
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -33,73 +35,143 @@ public class LoadCenterServiceImpl implements LoadCenterService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private AliYunEcsService aliYunEcsService;
|
private AliYunEcsService aliYunEcsService;
|
||||||
|
|
||||||
|
@Scheduled(cron = "0/2 * * * * ?")
|
||||||
|
public void refreshECSIPListCache() {
|
||||||
|
getECSIPList();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 分配的一个服务器IP
|
* 获取 分配的一个服务器IP
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Result<String> getAssignedServer() {
|
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
|
//存IP的List
|
||||||
ArrayList<String> ipList = new ArrayList<>();
|
ArrayList<String> ecsIPList = new ArrayList<>();
|
||||||
//获取张家口区的实例ID列表
|
|
||||||
try {
|
try {
|
||||||
|
//获取张家口区的实例ID列表
|
||||||
|
List<String> ecsIDList = aliYunEcsService.getIDList();
|
||||||
|
|
||||||
List<String> idList = aliYunEcsService.getIDList();
|
//将ID进行拼接,用逗号分隔
|
||||||
idList.forEach(id -> {
|
String ids = "";
|
||||||
//调用方法,获取对应ID实例的IP
|
for (String id : ecsIDList) {
|
||||||
try {
|
ids += id + ",";
|
||||||
List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> result = aliYunEcsService.queryInstancesInformation(id);
|
}
|
||||||
|
ids = ids.substring(0, ids.length() - 1);
|
||||||
|
|
||||||
//获取集合第一个的属性
|
List<DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance> response = aliYunEcsService.queryInstancesInformation(ids);
|
||||||
DescribeInstancesResponseBody.DescribeInstancesResponseBodyInstancesInstance response = result.get(0);
|
response.forEach(item -> {
|
||||||
|
//获取添加的实例的公网ipe
|
||||||
//获取添加的实例的公网ip
|
String ip = UserUtil.removeBrackets(item.getPublicIpAddress().getIpAddress().toString());
|
||||||
String instanceIp = UserUtil.removeBrackets(response.getPublicIpAddress().getIpAddress().toString());
|
ecsIPList.add(ip);
|
||||||
ipList.add(instanceIp);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error(e.getMessage());
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(e.getMessage());
|
log.error("获取实例ID列表失败:{}", e.getMessage());
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info(JSON.toJSONString(ipList));
|
|
||||||
|
|
||||||
//将IP列表存入redis
|
//将IP列表存入redis
|
||||||
redis.deleteObject("服务器列表:");
|
redis.deleteObject("实例IP列表:");
|
||||||
redis.setCacheList("服务器列表:", ipList);
|
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<>();
|
ArrayList<IpAndLoadCount> ipAndLoadCounts = new ArrayList<>();
|
||||||
|
|
||||||
ipList.forEach(ip -> {
|
//拿到IP后,获取各个IP的负载量
|
||||||
//拿到IP后,获取各个IP的负载量
|
ecsIPList.forEach(ip -> {
|
||||||
int fetchLoad = mqttUtil.getFetchLoad(ip);
|
int fetchLoad = mqttUtil.getFetchLoad(ip);
|
||||||
ipAndLoadCounts.add(new IpAndLoadCount(ip, fetchLoad));
|
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;
|
int emptyLoadCount = 0;
|
||||||
for (IpAndLoadCount ipAndLoadCount : ipAndLoadCounts) {
|
for (IpAndLoadCount ipAndLoadCount : ipAndLoadCounts) {
|
||||||
//假设使用2/8原则
|
//假设使用2/8原则 一个节点最多能有100个连接
|
||||||
emptyLoadCount += (80 - ipAndLoadCount.getLoadCount());
|
emptyLoadCount += (80 - ipAndLoadCount.getLoadCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
//存储IP和对应的权重
|
//存储IP和对应的权重
|
||||||
ArrayList<IpAndWeight> ipAndWeights = new ArrayList<>();
|
ArrayList<IpAndWeight> ipAndWeights = new ArrayList<>();
|
||||||
for (IpAndLoadCount ipAndLoadCount : ipAndLoadCounts) {
|
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);
|
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<>();
|
ArrayList<String> loadNodeList = new ArrayList<>();
|
||||||
|
|
||||||
int sum = ipAndWeights.stream().mapToInt(IpAndWeight::getWeight).sum();
|
int sum = ipAndWeights.stream()
|
||||||
|
.mapToInt(IpAndWeight::getWeight)
|
||||||
|
.sum();
|
||||||
if (sum < 100) {
|
if (sum < 100) {
|
||||||
List<IpAndWeight> list = ipAndWeights.stream().sorted(((o1, o2) -> o2.getWeight() - o1.getWeight())).toList();
|
List<IpAndWeight> list = ipAndWeights.stream().sorted(((o1, o2) -> o2.getWeight() - o1.getWeight())).toList();
|
||||||
|
|
||||||
|
@ -128,16 +200,14 @@ public class LoadCenterServiceImpl implements LoadCenterService {
|
||||||
break whFor;
|
break whFor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//节点IP列表存入缓存
|
//节点IP列表存入缓存
|
||||||
redis.deleteObject("work:node:gateway");
|
redis.deleteObject("work:node:gateway");
|
||||||
redis.setCacheList("work:node:gateway", loadNodeList);
|
redis.setCacheList("work:node:gateway", loadNodeList);
|
||||||
|
|
||||||
//获取缓存里最后一个IP进行返回
|
log.info("负载节点的IP列表:{}", loadNodeList);
|
||||||
//最后一个IP进行返回
|
return loadNodeList;
|
||||||
String result = loadNodeList.get(loadNodeList.size() - 1);
|
|
||||||
return Result.success(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue