feat:IDC数据源定时check

This commit is contained in:
nieziyan 2024-01-02 19:54:53 +08:00
parent a8215234e3
commit a73196d814
4 changed files with 149 additions and 67 deletions

View File

@ -12,6 +12,10 @@ public class TokenContext implements AutoCloseable{
userToken.set(TokenUtils.threadToken());
}
public void refreshToken(){
userToken.set(TokenUtils.refreshThreadToken());
}
@Override
public void close() throws Exception {
userToken.remove();

View File

@ -178,8 +178,20 @@ public class TokenUtils {
String secret = CommonConstant.TEMP_TOKEN_SECRET;
// 模拟登录生成Token
String token = JwtUtil.sign(username, secret);
// 设置Token缓存有效时间为 5 分钟
redisUtil.set(RedisConstant.THREAD_TOKEN, token, 5 * 60);
// 设置Token缓存有效时间为 6h
redisUtil.set(RedisConstant.THREAD_TOKEN, token, 6 * 60 * 60);
return token;
}
public static String refreshThreadToken(){
RedisUtil redisUtil = SpringContextUtils.getBean(RedisUtil.class);
String username = CommonConstant.TEMP_TOKEN_USERNAME;
String secret = CommonConstant.TEMP_TOKEN_SECRET;
// 模拟登录生成Token
String token = JwtUtil.sign(username, secret);
// 设置Token缓存有效时间为 6h
redisUtil.set(RedisConstant.THREAD_TOKEN, token, 6 * 60 * 60);
return token;
}
}

View File

@ -1,6 +1,7 @@
package org.jeecg.modules.idc;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@ -26,80 +27,26 @@ import java.util.concurrent.TimeUnit;
import static org.jeecg.common.util.TokenUtils.getTempToken;
import static org.jeecg.modules.base.enums.Template.IDC_DATASOURCE_STATUS;
@Component
@Slf4j
@Component
public class IDCDataFetch {
@Value("${inland.url}")
private String urlM; // 本地数据源url即为主数据源
@Value("${inland.username}")
private String usernameM;
@Value("${inland.password}")
private String passwordM;
@Value("${oversea.url}")
private String urlS; // 国外数据源url即为从数据源
@Value("${oversea.username}")
private String usernameS;
@Value("${oversea.password}")
private String passwordS;
@Autowired
private SystemClient systemClient;
private TemplateManager templateManager;
// 定时拾取IDC数据
@Scheduled(fixedDelayString = "${request-interval}", timeUnit = TimeUnit.SECONDS)
@Scheduled(initialDelay = 5, fixedDelay = 10, timeUnit = TimeUnit.SECONDS)
public void fetch() {
JdbcTemplate template;
MessageDTO messageDTO = new MessageDTO(null, IDC_DATASOURCE_STATUS.getCode(), "admin");
messageDTO.setType(MessageTypeEnum.XT.getType());
ConnR connR = JDBCUtil.isConnection(urlM, usernameM, passwordM);
if (connR.isConn()) {
try {
template = JDBCUtil.template(urlM, usernameM, passwordM);
// 查询IDC Data
} catch (Exception e) {
log.error("[inland数据源]IDC数据处理异常: {}", e.getMessage());
}
return;
}
UserTokenContext.setToken(getTempToken());
// 对发送警告消息时可能出现的异常进行捕获(503) 防止影响后续代码执行
try {
// 给管理员发送预警信息
Map<String, Object> data = new HashMap<>();
data.put("param1", "inland");
data.put("param2", connR.getInfo());
messageDTO.setData(data);
systemClient.sendTo(messageDTO);
JdbcTemplate template = templateManager.getTemplate();
if (ObjectUtil.isNull(template))
return;
// 查询...
String sql = "select count(1) from gards_stations";
Integer integer = template.queryForObject(sql, Integer.class);
System.out.println("========count========>" + integer);
}catch (Exception e){
log.error("发送inland数据源异常信息失败: {}", e.getMessage());
log.error("{}", e.getMessage());
}
// 使用备用数据源
connR = JDBCUtil.isConnection(urlS, usernameS, passwordS);
if (connR.isConn()) {
try {
template = JDBCUtil.template(urlS, usernameS, passwordS);
// 查询IDC Data
} catch (Exception e) {
log.error("[oversea数据源]IDC数据处理异常: {}", e.getMessage());
}
return;
}
try {
// 给管理员发送预警信息
Map<String, Object> data = ParamUtil.set("oversea", connR.getInfo());
messageDTO.setData(data);
systemClient.sendTo(messageDTO);
}catch (Exception e){
log.error("发送oversea数据源异常信息失败: {}", e.getMessage());
}
UserTokenContext.remove();
}
}

View File

@ -0,0 +1,119 @@
package org.jeecg.modules.idc;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import feign.FeignException;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.TokenContext;
import org.jeecg.common.api.dto.message.MessageDTO;
import org.jeecg.common.constant.enums.MessageTypeEnum;
import org.jeecg.common.util.JDBCUtil;
import org.jeecg.modules.base.dto.ConnR;
import org.jeecg.modules.feignclient.SystemClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import static org.jeecg.modules.base.enums.Template.IDC_DATASOURCE_STATUS;
@Slf4j
@Component
@RefreshScope
public class TemplateManager {
@Value("${inland.url}")
private String urlM; // 本地数据源url即为主数据源
@Value("${inland.username}")
private String usernameM;
@Value("${inland.password}")
private String passwordM;
@Value("${oversea.url}")
private String urlS; // 国外数据源url即为从数据源
@Value("${oversea.username}")
private String usernameS;
@Value("${oversea.password}")
private String passwordS;
@Autowired
private SystemClient systemClient;
private final String templateKey = "template";
private final ConcurrentMap<String, JdbcTemplate> templateMap = new ConcurrentHashMap<>();
private TemplateManager(){}
private void setTemplate(JdbcTemplate template){
templateMap.put(templateKey, template);
}
public JdbcTemplate getTemplate(){
return templateMap.get(templateKey);
}
/*
* 定时检查inland/oversea数据源的的连接状态
* */
@Scheduled(fixedDelay = 10, timeUnit = TimeUnit.SECONDS)
private void checkTemplate(){
try (TokenContext tokenContext = new TokenContext()){
MessageDTO messageDTO = new MessageDTO(null, IDC_DATASOURCE_STATUS.getCode(), "admin");
messageDTO.setType(MessageTypeEnum.XT.getType());
ConnR connR = JDBCUtil.isConnection(urlM, usernameM, passwordM);
// 如果inland数据源不可用 尝试oversea数据源
JdbcTemplate template;
if (connR.isConn()){
template = JDBCUtil.template(urlM, usernameM, passwordM);
this.setTemplate(template);
} else {
// 为当前线程设置临时Token 避免OpenFeign调用其它服务接口时403
tokenContext.setToken();
// 给admin发送数据源异常消息
Map<String, Object> data = new HashMap<>();
data.put("param1", "inland");
data.put("param2", connR.getInfo());
messageDTO.setData(data);
try { systemClient.sendTo(messageDTO); }
catch (FeignException.Unauthorized e) {
// 刷新临时Token 重新发送信息
tokenContext.refreshToken();
systemClient.sendTo(messageDTO);
}
catch(Exception e) {log.error("发送inland数据源异常信息失败: {}" , e.getMessage());}
connR = JDBCUtil.isConnection(urlS, usernameS, passwordS);
if (connR.isConn()){
template = JDBCUtil.template(urlS, usernameS, passwordS);
this.setTemplate(template);
return;
}
// 给admin发送数据源异常消息
data.put("param1", "oversea");
data.put("param2", connR.getInfo());
messageDTO.setData(data);
try { systemClient.sendTo(messageDTO); }
catch (FeignException.Unauthorized e) {
// 刷新临时Token 重新发送信息
tokenContext.refreshToken();
systemClient.sendTo(messageDTO);
}
catch(Exception e) {log.error("发送oversea数据源异常信息失败: {}" , e.getMessage());}
}
}catch (Exception e){
log.error("定时检查inland/oversea数据源状态异常: {}", e.getMessage());
}
}
}