[server][ xray]- 代理节点的数据库内容 - 1

This commit is contained in:
zeaslity
2023-03-01 15:46:57 +08:00
parent 1881fb0710
commit ced891c5e6
9 changed files with 247 additions and 46 deletions

View File

@@ -16,7 +16,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static io.wdd.func.xray.beans.node.ProxyNodeSet.*;
import static io.wdd.func.xray.persisit.cache.ProxyNodeCache.*;
@RestController
@RequestMapping("/server/func/xray")

View File

@@ -3,7 +3,6 @@ package io.wdd.func.xray.beans.node;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@@ -22,7 +21,7 @@ public class Edge {
@ApiModelProperty("权重值, 值的范围在0-100,数字越小表示阻力越小")
int weight;
Edge(ProxyNode source, ProxyNode destination, int weight) {
public Edge(ProxyNode source, ProxyNode destination, int weight) {
this.source = source;
this.destination = destination;
this.weight = weight;

View File

@@ -5,7 +5,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static io.wdd.func.xray.beans.node.ProxyNodeSet.*;
import static io.wdd.func.xray.persisit.cache.ProxyNodeCache.ProxyNodeStaticMap;
/**
@@ -91,10 +91,10 @@ class Graph {
for (int heigh = 0; heigh < height; heigh++) {
List<Integer> list = adj_matrix.get(heigh);
System.out.print("FROM [ " + ProxyNodeMap.get(heigh) + " ] ==> ");
System.out.print("FROM [ " + ProxyNodeStaticMap.get(heigh) + " ] ==> ");
for (int width = 0; width < weight; width++) {
if (list.get(width) != 0) {
System.out.print(ProxyNodeMap.get(width) + ": "+ list.get(width) + "\t");
System.out.print(ProxyNodeStaticMap.get(width) + ": " + list.get(width) + "\t");
}
}
System.out.print("\n");

View File

@@ -20,13 +20,12 @@ public class ProxyNode {
String name;
/**
* 用于定位在中的 顺序位置
* 用于定位在邻接图(有向加权图)中的 顺序位置
*/
int num;
String agentName;
String agentTopicName;
String location;

View File

@@ -1,13 +1,19 @@
package io.wdd.func.xray.beans.node;
/**
* 关系应该具备包含关系,即下一层的属性包含了上一层的功能
* ProxyNode的功能层级划分
*/
public enum ProxyNodeType {
// 数据库中标记为0
INTERFACE,
// 数据库中标记为1
RELAY,
// 关系应该具备包含关系,即下一层的属性包含了上一层的功能
// 数据库中标记为0
EXTERNAL
}

View File

@@ -0,0 +1,134 @@
package io.wdd.func.xray.persisit;
import io.wdd.func.xray.beans.node.ProxyNode;
import io.wdd.func.xray.beans.node.XrayConfigInfo;
import io.wdd.server.beans.vo.ServerInfoVO;
import io.wdd.server.coreService.CoreServerService;
import io.wdd.server.service.AppInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import static io.wdd.func.xray.persisit.cache.ProxyNodeCache.ProxyNodeMap;
import static io.wdd.func.xray.persisit.cache.ProxyNodeCache.ProxyNodeStaticMap;
import static io.wdd.rpc.init.AcceptAgentInitInfo.ALL_SERVER_CITY_INDEX;
/**
* 为Xray Config信息 操作数据库而创建
*/
@Service
@Slf4j
public class XrayDBOperator {
@Resource
CoreServerService coreServerService;
@Resource
AppInfoService appInfoService;
@PostConstruct
public void cache() {
// 初始化就需要缓存相应的信息
this.CacheAllProxyNodeInfo();
}
/**
* 从数据库中查询到所有 代理节点的信息,并且生成 ProxyNode然后缓存至
*/
public void CacheAllProxyNodeInfo() {
List<ServerInfoVO> serverInfoVOList = coreServerService.serverGetAll();
transferServerInfoToProxyNode(serverInfoVOList);
}
private void transferServerInfoToProxyNode(List<ServerInfoVO> serverInfoVOList) {
// 临时内容
int[] bitmap = new int[ALL_SERVER_CITY_INDEX.size()];
//
int[] finalBitmap = bitmap;
List<ProxyNode> proxyNodeList = serverInfoVOList
.stream()
.map(
serverInfoVO -> {
String serverCity = serverInfoVO
.getLocation()
.split(" ")[0];
int cityBitMapBase = ALL_SERVER_CITY_INDEX.get(serverCity) * 10;
int serverGraphNum = cityBitMapBase;
for (int index = cityBitMapBase; index < cityBitMapBase + 10; index++) {
if (finalBitmap[index] == 0) {
finalBitmap[index] = 1;
serverGraphNum = index;
break;
}
}
return ProxyNode
.builder()
.agentTopicName(serverInfoVO.getTopicName())
.num(serverGraphNum)
.publicIPv4(serverInfoVO.getServerIpPbV4())
.publicIPv6(serverInfoVO.getServerIpPbV6())
.name(serverCity + serverGraphNum)
.agentName(serverInfoVO.getServerName())
.location(serverCity)
.xrayConfigInfo(new XrayConfigInfo())
.build();
}
)
.sorted(
Comparator.comparing(
ProxyNode::getNum
)
)
.collect(Collectors.toList());
// 收缩邻接表的Index
for (int realIndex = 0; realIndex < proxyNodeList.size(); realIndex++) {
proxyNodeList
.get(realIndex)
.setNum(realIndex);
}
// 缓存内容
ProxyNodeMap.clear();
ProxyNodeStaticMap.clear();
proxyNodeList
.stream()
.forEach(
proxyNode -> {
ProxyNodeMap.put(
proxyNode.getAgentTopicName(),
proxyNode
);
ProxyNodeStaticMap.put(
proxyNode.getNum(),
proxyNode
);
}
);
//help gc
bitmap = null;
proxyNodeList = null;
}
}

View File

@@ -1,8 +1,10 @@
package io.wdd.func.xray.beans.node;
package io.wdd.func.xray.persisit.cache;
import static io.wdd.func.xray.beans.node.ProxyNodeSet.*;
import io.wdd.func.xray.beans.node.Edge;
public class EdgeSet {
import static io.wdd.func.xray.persisit.cache.ProxyNodeCache.*;
public class EdgeWeightCache {
public static Edge chengduToShanghai;

View File

@@ -1,10 +1,19 @@
package io.wdd.func.xray.beans.node;
package io.wdd.func.xray.persisit.cache;
import io.wdd.func.xray.beans.node.ProxyNode;
import io.wdd.func.xray.beans.node.ProxyNodeType;
import java.util.HashMap;
public class ProxyNodeSet {
public class ProxyNodeCache {
public static final HashMap<Integer, ProxyNode> ProxyNodeMap = new HashMap<>();
/**
* 保存 AgentTopicName - ProxyNode 的全局缓存
*/
public static final HashMap<String, ProxyNode> ProxyNodeMap = new HashMap<>();
public static final HashMap<Integer, ProxyNode> ProxyNodeStaticMap = new HashMap<>();
public static ProxyNode chengdu;
public static ProxyNode shanghai;
@@ -130,43 +139,43 @@ public class ProxyNodeSet {
.agentTopicName("Seoul-arm64-02-oracle")
.build();
ProxyNodeMap.put(
ProxyNodeStaticMap.put(
chengdu.getNum(),
chengdu
);
ProxyNodeMap.put(
ProxyNodeStaticMap.put(
hongkong.getNum(),
hongkong
);
ProxyNodeMap.put(
ProxyNodeStaticMap.put(
shanghai.getNum(),
shanghai
);
ProxyNodeMap.put(
ProxyNodeStaticMap.put(
seoul2.getNum(),
seoul2
);
ProxyNodeMap.put(
ProxyNodeStaticMap.put(
tokyo2.getNum(),
tokyo2
);
ProxyNodeMap.put(
ProxyNodeStaticMap.put(
phoenix2.getNum(),
phoenix2
);
ProxyNodeMap.put(
ProxyNodeStaticMap.put(
london2.getNum(),
london2
);
ProxyNodeMap.put(
ProxyNodeStaticMap.put(
chengduAgent.getNum(),
chengduAgent
);
ProxyNodeMap.put(
ProxyNodeStaticMap.put(
tokyoDev.getNum(),
tokyoDev
);
ProxyNodeMap.put(
ProxyNodeStaticMap.put(
seoul5.getNum(),
seoul5
);

View File

@@ -13,6 +13,7 @@ import io.wdd.server.utils.DaemonDatabaseOperator;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.data.redis.core.RedisTemplate;
@@ -22,10 +23,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
@@ -35,14 +33,31 @@ import java.util.concurrent.TimeUnit;
@Slf4j(topic = "octopus agent init ")
public class AcceptAgentInitInfo {
public static Set<String> ALL_SERVER_CITY_INFO = new HashSet<>(
Arrays.asList(
"HongKong", "Tokyo", "Seoul", "Phoenix", "London", "Shanghai", "Chengdu"
public static final HashMap<String, Integer> ALL_SERVER_CITY_INDEX = new HashMap<>(
Map.of(
"Chengdu",
1,
"Shanghai",
2,
"HongKong",
3,
"Seoul",
4,
"Tokyo",
5,
"Phoenix",
6,
"London",
7
)
);
public static Set<String> ALL_SERVER_ARCH_INFO = new HashSet<>(
Arrays.asList(
"amd64", "arm64", "arm32", "xia32", "miples"
"amd64",
"arm64",
"arm32",
"xia32",
"miples"
)
);
@Resource
@@ -91,7 +106,10 @@ public class AcceptAgentInitInfo {
try {
serverInfoVO = objectMapper.readValue(message.getBody(), ServerInfoVO.class);
serverInfoVO = objectMapper.readValue(
message.getBody(),
ServerInfoVO.class
);
// 1. check if information is correct
if (!validateServerInfo(serverInfoVO)) {
@@ -132,7 +150,11 @@ public class AcceptAgentInitInfo {
// long deliveryTag, boolean multiple, boolean requeue
channel.basicNack(deliveryTag, false, true);
channel.basicNack(
deliveryTag,
false,
true
);
// long deliveryTag, boolean requeue
// channel.basicReject(deliveryTag,true);
@@ -158,8 +180,14 @@ public class AcceptAgentInitInfo {
*/
// ack the rabbitmq info
// If all logic is successful
log.info("Agent [ {} ] has init successfully !", serverInfoVO.getTopicName());
channel.basicAck(deliveryTag, false);
log.info(
"Agent [ {} ] has init successfully !",
serverInfoVO.getTopicName()
);
channel.basicAck(
deliveryTag,
false
);
}
private void generateAgentStatusRedisStreamConsumerGroup(String agentTopicName) {
@@ -170,7 +198,12 @@ public class AcceptAgentInitInfo {
log.debug(" not find the group, recreate");
// not find the group, recreate
redisTemplate.opsForStream().createGroup(statusStreamKey, "OctopusServer");
redisTemplate
.opsForStream()
.createGroup(
statusStreamKey,
"OctopusServer"
);
}
// check for octopus-server consumer group
@@ -185,12 +218,18 @@ public class AcceptAgentInitInfo {
redisTemplate.opsForStream().createGroup(statusStreamKey, "OctopusServer");
}*/
log.debug("octopus agent [ {} ] status report stream key [ {} ] has been created !", agentTopicName, statusStreamKey);
log.debug(
"octopus agent [ {} ] status report stream key [ {} ] has been created !",
agentTopicName,
statusStreamKey
);
}
private boolean checkAgentAlreadyRegister(String agentQueueTopic) {
Optional<String> first = databaseOperator.getAllServerName().stream().
Optional<String> first = databaseOperator
.getAllServerName()
.stream().
filter(serverName -> agentQueueTopic.startsWith(serverName))
.findFirst();
@@ -199,7 +238,8 @@ public class AcceptAgentInitInfo {
private boolean sendInitMessageToAgent(ServerInfoVO serverInfoVO) {
OctopusMessage octopusMessage = OctopusMessage.builder()
OctopusMessage octopusMessage = OctopusMessage
.builder()
.type(OctopusMessageType.INIT)
// should be the OctopusExchange Name
.content(String.valueOf(initRabbitMQConfig.OCTOPUS_EXCHANGE))
@@ -230,17 +270,29 @@ public class AcceptAgentInitInfo {
// topic generate strategy
String serverName = serverInfoVO.getServerName();
serverName.replace(" ", "");
serverName.replace(
" ",
""
);
serverInfoVO.setServerName(serverName);
// validate serverName
String[] split = serverName.split("-");
if (split.length <= 2 || !ALL_SERVER_CITY_INFO.contains(split[0]) || !ALL_SERVER_ARCH_INFO.contains(split[1])) {
log.error("server info from agent are {}", serverInfoVO);
if (split.length <= 2 || !ALL_SERVER_CITY_INDEX.containsKey(split[0]) || !ALL_SERVER_ARCH_INFO.contains(split[1])) {
log.error(
"server info from agent are {}",
serverInfoVO
);
throw new MyRuntimeException("server name not validated !");
}
String machineIdPrefixSixBytes = String.valueOf(serverInfoVO.getMachineId().toCharArray(), 0, 6);
String machineIdPrefixSixBytes = String.valueOf(
serverInfoVO
.getMachineId()
.toCharArray(),
0,
6
);
return serverName + "-" + machineIdPrefixSixBytes;
}