Files
ProjectOctopus/server/src/main/java/io/wdd/rpc/status/CommonAndStatusCache.java
2023-08-02 14:30:01 +08:00

235 lines
7.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package io.wdd.rpc.status;
import io.wdd.common.utils.TimeUtils;
import io.wdd.server.beans.vo.ServerInfoVO;
import io.wdd.server.coreService.CoreServerService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
* Server启动或者运行的时候需要初 缓存一系列的信息
* <p>
* 所有Agent的TopicName ALL_AGENT_TOPIC_NAME_SET
* <p>
* 2023年7月10日 此部分应该初始化全部为 False状态
* Agent状态信息的两个Map STATUS_AGENT_LIST_MAP ALL_AGENT_STATUS_MAP
* <p>
* 2023年7月10日 -- 此部分作为Redis中存储的 二级缓存部分 应该严格遵循
*/
@Service
@Slf4j
public class CommonAndStatusCache {
/**
* 存储所有的AgentTopicName的缓存
*/
public static final Set<String> ALL_AGENT_TOPIC_NAME_SET = new HashSet<>();
/**
* 存储所有的AgentTopicName的缓存
*/
public static final List<String> ALL_AGENT_TOPIC_NAME_LIST = new ArrayList<>();
/**
* 存储 状态对应Agent列表的Map
* Agent的状态描述为 AgentHealthyStatusEnum
* HEALTHY -> ["agentTopicName-1" "agentTopicName-2"]
* FAILED -> ["agentTopicName-1" "agentTopicName-2"]
*/
public static final Map<String, List<String>> STATUS_AGENT_LIST_MAP = new HashMap<>();
/**
* 存储所有Agent状态的Map
* <p>
* 内容为 agentTopicName- True代表健康 False代表不健康
*/
public static final Map<String, Boolean> ALL_AGENT_STATUS_MAP = new HashMap<>();
/**
* 保存所有健康运行的Agent Topic Name
*/
public static final List<String> ALL_HEALTHY_AGENT_TOPIC_NAME_LIST = new ArrayList<>();
/**
* 记录状态信息缓存的更新时间
*/
public static final String STATUS_UPDATE_TIME_KEY = "UPDATE_TIME";
/**
* 记录状态信息缓存的初始化时间
*/
public static final String STATUS_INIT_TIME_KEY = "INIT_TIME";
/**
* AgentTopicName 在Redis中緩存的Key
*/
private static final String ALL_AGENT_TOPIC_NAME_REDIS_KEY = "ALL_AGENT_TOPIC_NAME";
@Resource
CoreServerService coreServerService;
@Resource
RedisTemplate redisTemplate;
@PostConstruct
public void InitToGenerateAllStatusCache() {
//所有Agent的TopicName ALL_AGENT_TOPIC_NAME_SET
updateAllAgentTopicNameCache();
// Agent状态信息的两个Map
// 初始化 默认创建全部失败的Map
Map<String, Boolean> initAgentFalseStatusMap = ALL_AGENT_TOPIC_NAME_LIST
.stream()
.collect(Collectors.toMap(
topicName -> topicName,
topicName -> Boolean.FALSE
));
updateAgentStatusCache(initAgentFalseStatusMap);
}
/**
* 从数据库中获取所有注册过的Agent名称
* <p>
* 2023年7月10日 写入Redis中保存一份
*/
public void updateAllAgentTopicNameCache() {
//查询DB
List<ServerInfoVO> allAgentInfo = coreServerService.serverGetAll();
if (CollectionUtils.isEmpty(allAgentInfo)) {
log.warn("[Serer Boot Up] Octopus Serer First Boot Up ! No Agent Registered Ever!");
return;
}
ALL_AGENT_TOPIC_NAME_LIST.clear();
ALL_AGENT_TOPIC_NAME_SET.clear();
List<String> collect = allAgentInfo
.stream()
.map(ServerInfoVO::getTopicName)
.collect(Collectors.toList());
ALL_AGENT_TOPIC_NAME_LIST.addAll(collect);
ALL_AGENT_TOPIC_NAME_SET.addAll(collect);
String[] all_agent_topic_name_array = new String[ALL_AGENT_TOPIC_NAME_LIST.size()];
ALL_AGENT_TOPIC_NAME_LIST.toArray(all_agent_topic_name_array);
// 2023年7月10日 同步缓存至Redis中
redisTemplate
.opsForSet()
.add(
ALL_AGENT_TOPIC_NAME_REDIS_KEY,
all_agent_topic_name_array
);
}
/**
* 根据传入的状态Map更新二级缓存的两个状态Map和健康主机的列表
* ALL_AGENT_STATUS_MAP
* STATUS_AGENT_LIST_MAP
* <p>
* ALL_HEALTHY_AGENT_TOPIC_NAME_LIST
*/
public void updateAgentStatusCache(Map<String, Boolean> agentAliveStatusMap) {
// 检查,排除没有节点的情况
if (CollectionUtils.isEmpty(ALL_AGENT_TOPIC_NAME_LIST)) {
log.warn("[Agent Status Cache] No Agent Registered Ever! Return");
return;
}
// 2023年6月15日 更新状态缓存
ALL_AGENT_STATUS_MAP.clear();
ALL_AGENT_STATUS_MAP.putAll(agentAliveStatusMap);
// 2023-01-16
// 更新 状态-Agent容器 内容为
// HEALTHY -> ["agentTopicName-1" "agentTopicName-2"]
// FAILED -> ["agentTopicName-1" "agentTopicName-2"]
Map<String, List<String>> statusAgentListMap = agentAliveStatusMap
.entrySet()
.stream()
.collect(
Collectors.groupingBy(
Map.Entry::getValue
)
)
.entrySet()
.stream()
.collect(
Collectors.toMap(
entry -> entry.getKey() ? "HEALTHY" : "FAILED",
entry -> entry
.getValue()
.stream()
.map(
Map.Entry::getKey
)
.collect(Collectors.toList())
)
);
// 2023-2-3 bug fix
STATUS_AGENT_LIST_MAP.clear();
STATUS_AGENT_LIST_MAP.putAll(statusAgentListMap);
// 2023年2月21日更新时间
String timeString = TimeUtils.currentFormatTimeString();
STATUS_AGENT_LIST_MAP.put(
STATUS_UPDATE_TIME_KEY,
Collections.singletonList(timeString)
);
// 缓存相应的存活Agent
List<String> allHealthyAgentTopicNames = agentAliveStatusMap
.entrySet()
.stream()
.filter(
entry -> entry
.getValue()
.equals(Boolean.TRUE)
)
.map(
Map.Entry::getKey
)
.collect(Collectors.toList());
ALL_HEALTHY_AGENT_TOPIC_NAME_LIST.clear();
ALL_HEALTHY_AGENT_TOPIC_NAME_LIST.addAll(allHealthyAgentTopicNames);
log.debug(
"[状态二级缓存] - ALL_HEALTHY_AGENT_TOPIC_NAME_LIST 为=> {},\n STATUS_AGENT_LIST_MAP 为=> {},\n ALL_AGENT_STATUS_MAP 为=> {}\n",
ALL_HEALTHY_AGENT_TOPIC_NAME_LIST,
STATUS_AGENT_LIST_MAP,
ALL_AGENT_STATUS_MAP
);
// help gc
agentAliveStatusMap = null;
statusAgentListMap = null;
allHealthyAgentTopicNames = null;
}
private String uniformHealthyStatus(String agentStatus) {
switch (agentStatus) {
case "0":
return AgentHealthyStatusEnum.FAILED.getStatus();
case "1":
return AgentHealthyStatusEnum.HEALTHY.getStatus();
default:
return AgentHealthyStatusEnum.UNKNOWN.getStatus();
}
}
}