|
|
@ -14,11 +14,20 @@ import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
|
|
|
import java.util.UUID;
|
|
|
|
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
|
|
|
|
@Service
|
|
|
|
@Service
|
|
|
|
public class HeartTaskService {
|
|
|
|
public class HeartTaskService {
|
|
|
|
|
|
|
|
|
|
|
|
final Logger logger = LoggerFactory.getLogger(HeartTask.class);
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(HeartTaskService.class);
|
|
|
|
|
|
|
|
// 确保常量命名与HeartTask保持一致
|
|
|
|
|
|
|
|
private static final String REDIS_DOWNLOAD_STATUS_KEY = "SC_UDIINFO_DOWNLOAD_STATUS";
|
|
|
|
|
|
|
|
private static final String REDIS_UPLOAD_STATUS_KEY = "UPLOAD_UDIINFO_STATUS";
|
|
|
|
|
|
|
|
private static final String DOWNLOAD_LOCK_KEY = "is_doing_download";
|
|
|
|
|
|
|
|
// Redis锁过期时间(秒):设置合理的超时时间,避免任务卡死导致锁无法释放
|
|
|
|
|
|
|
|
private static final int LOCK_EXPIRY_SECONDS = 30 * 60; // 30分钟
|
|
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
@Resource
|
|
|
|
SystemParamConfigService systemParamConfigService;
|
|
|
|
SystemParamConfigService systemParamConfigService;
|
|
|
|
@Resource
|
|
|
|
@Resource
|
|
|
@ -34,91 +43,85 @@ public class HeartTaskService {
|
|
|
|
@Value("${SPMS_WEBSOCKET_TOKEN}")
|
|
|
|
@Value("${SPMS_WEBSOCKET_TOKEN}")
|
|
|
|
private String socketToken;
|
|
|
|
private String socketToken;
|
|
|
|
|
|
|
|
|
|
|
|
//定时从上游下载数据
|
|
|
|
|
|
|
|
public void dlData() {
|
|
|
|
|
|
|
|
SystemParamConfigEntity upConnect = systemParamConfigService.selectByParamKey("sync_upstream_enable");
|
|
|
|
|
|
|
|
if (upConnect != null && upConnect.getParamValue().equals("1")) {
|
|
|
|
|
|
|
|
dlAllData();
|
|
|
|
|
|
|
|
scanUpload();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
SystemParamConfigEntity donwConnect = systemParamConfigService.selectByParamKey("sync_downstream_enable");
|
|
|
|
|
|
|
|
if (donwConnect != null && donwConnect.getParamValue().equals("1")) {
|
|
|
|
|
|
|
|
scanDonwload();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void scanUpload() {
|
|
|
|
/**
|
|
|
|
SystemParamConfigEntity systemParamConfigEntity = systemParamConfigService.selectByParamKey("sc_udiinfo_upload");
|
|
|
|
* 从上游下载全部数据
|
|
|
|
long timeInterval = Long.parseLong(systemParamConfigEntity.getParamValue()) * 60 * 1000;
|
|
|
|
* 该方法支持被HeartTask或其他服务直接调用
|
|
|
|
long curTime = System.currentTimeMillis();
|
|
|
|
* 内部实现了基于Redis的分布式锁,确保在分布式环境下也只有一个实例执行
|
|
|
|
//定时扫描
|
|
|
|
*/
|
|
|
|
Long lastTime = (Long) redisUtil.get("UPLOAD_UDIINFO_STATUS");
|
|
|
|
public void dlAllData() {
|
|
|
|
if (lastTime == null) {
|
|
|
|
logger.info("定时从上游下载全部据-----开始");
|
|
|
|
lastTime = System.currentTimeMillis();
|
|
|
|
// 先更新时间戳,防止其他实例重复执行
|
|
|
|
redisUtil.set("UPLOAD_UDIINFO_STATUS", lastTime, 30 * 60);
|
|
|
|
// 此处的时间戳更新会被HeartTask及其他服务读取用于判断是否执行
|
|
|
|
}
|
|
|
|
redisUtil.set(REDIS_DOWNLOAD_STATUS_KEY, System.currentTimeMillis());
|
|
|
|
if (curTime - lastTime > timeInterval) {
|
|
|
|
|
|
|
|
redisUtil.set("UPLOAD_UDIINFO_STATUS", curTime);
|
|
|
|
|
|
|
|
scanUploadService.scanAllDatas();
|
|
|
|
|
|
|
|
scanUploadService.scanAllBus();
|
|
|
|
|
|
|
|
scanUploadService.scanAllOrders();
|
|
|
|
|
|
|
|
scanUploadService.scanAllSchedule();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void scanDonwload() {
|
|
|
|
|
|
|
|
SystemParamConfigEntity upConnect = systemParamConfigService.selectByParamKey("sync_downstream_enable");
|
|
|
|
|
|
|
|
if (upConnect.getParamValue().equals("1")) {
|
|
|
|
|
|
|
|
SystemParamConfigEntity systemParamConfigEntity = systemParamConfigService.selectByParamKey("sc_udiinfo_status");
|
|
|
|
|
|
|
|
long timeInterval = Long.parseLong(systemParamConfigEntity.getParamValue()) * 60 * 1000;
|
|
|
|
|
|
|
|
long curTime = System.currentTimeMillis();
|
|
|
|
|
|
|
|
Long lastTime = (Long) redisUtil.get("SC_UDIINFO_DOWNLOAD_STATUS");
|
|
|
|
|
|
|
|
if (lastTime == null) {
|
|
|
|
|
|
|
|
lastTime = System.currentTimeMillis();
|
|
|
|
|
|
|
|
redisUtil.set("SC_UDIINFO_DOWNLOAD_STATUS", lastTime);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (curTime - lastTime > timeInterval) {
|
|
|
|
|
|
|
|
redisUtil.set("SC_UDIINFO_DOWNLOAD_STATUS", curTime);
|
|
|
|
|
|
|
|
scanDownloadService.scanAllData();
|
|
|
|
|
|
|
|
scanDownloadService.scanAllBus();
|
|
|
|
|
|
|
|
scanDownloadService.scanAllOrder();
|
|
|
|
|
|
|
|
scanDownloadService.scanScheduleList();
|
|
|
|
|
|
|
|
scanDownloadService.scanUdis();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void dlUpAllData() {
|
|
|
|
|
|
|
|
SystemParamConfigEntity upConnect = systemParamConfigService.selectByParamKey("sync_upstream_enable");
|
|
|
|
|
|
|
|
if (upConnect != null && upConnect.getParamValue().equals("1")) {
|
|
|
|
|
|
|
|
dlAllData();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 生成唯一的锁标识,用于安全释放锁(避免释放其他实例的锁)
|
|
|
|
|
|
|
|
String lockValue = UUID.randomUUID().toString();
|
|
|
|
|
|
|
|
boolean lockAcquired = false;
|
|
|
|
|
|
|
|
|
|
|
|
public void dlAllData() {
|
|
|
|
try {
|
|
|
|
logger.info("定时从上游下载全部据-----");
|
|
|
|
// 检查是否已有下载任务在进行
|
|
|
|
redisUtil.set("SC_UDIINFO_DOWNLOAD_STATUS", System.currentTimeMillis());
|
|
|
|
String existingLock = (String) redisUtil.get(DOWNLOAD_LOCK_KEY);
|
|
|
|
String doing = (String) redisUtil.get("is_doing_download");
|
|
|
|
if (existingLock != null && !existingLock.equals("false")) {
|
|
|
|
if (doing == null || doing.equals("false")) {
|
|
|
|
logger.info("已有下载任务正在执行中,跳过本次执行");
|
|
|
|
redisUtil.set("is_doing_download", "true", 60);
|
|
|
|
return;
|
|
|
|
dlAllDataService.dllNewAllOrder();
|
|
|
|
}
|
|
|
|
Arrays.stream(BasicExportTypeEnum.values()).forEach(i -> {
|
|
|
|
|
|
|
|
dlAllDataService.pullData(i);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
dlAllDataService.dlAllDi();
|
|
|
|
|
|
|
|
redisUtil.set("is_doing_download", "false");
|
|
|
|
|
|
|
|
spsSyncWebSocket.sendMessage(SocketMsgEntity.builder().type(SocketMsgType.DL_ALL_DATA).content("").remark("下载基础信息").build(), "2:" + socketToken);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 尝试获取锁,使用唯一值标识锁的拥有者
|
|
|
|
|
|
|
|
lockAcquired = redisUtil.set(DOWNLOAD_LOCK_KEY, lockValue, LOCK_EXPIRY_SECONDS);
|
|
|
|
|
|
|
|
if (!lockAcquired) {
|
|
|
|
|
|
|
|
logger.warn("无法获取下载任务锁,可能有其他进程正在执行");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.info("成功获取下载锁,开始执行数据下载任务,锁ID: {}", lockValue);
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
// 执行订单数据下载
|
|
|
|
|
|
|
|
dlAllDataService.dllNewAllOrder();
|
|
|
|
|
|
|
|
// 执行其他类型数据下载
|
|
|
|
|
|
|
|
Arrays.stream(BasicExportTypeEnum.values()).forEach(i -> {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
dlAllDataService.pullData(i);
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
logger.error("下载数据类型[{}]时发生异常", i, e);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
// 注释掉的DI下载,保留注释
|
|
|
|
|
|
|
|
// dlAllDataService.dlAllDi();
|
|
|
|
|
|
|
|
// 发送WebSocket消息通知
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
spsSyncWebSocket.sendMessage(
|
|
|
|
|
|
|
|
SocketMsgEntity.builder()
|
|
|
|
|
|
|
|
.type(SocketMsgType.DL_ALL_DATA)
|
|
|
|
|
|
|
|
.content("")
|
|
|
|
|
|
|
|
.remark("下载基础信息")
|
|
|
|
|
|
|
|
.build(),
|
|
|
|
|
|
|
|
"2:" + socketToken
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
logger.error("发送WebSocket消息失败", e);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.info("数据下载任务执行完成");
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
logger.error("执行数据下载任务过程中发生异常", e);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
// 确保无论如何都释放锁,但只释放自己的锁
|
|
|
|
|
|
|
|
if (lockAcquired) {
|
|
|
|
|
|
|
|
// 检查锁是否仍然是我们设置的值,避免释放他人的锁
|
|
|
|
|
|
|
|
String currentLock = (String) redisUtil.get(DOWNLOAD_LOCK_KEY);
|
|
|
|
|
|
|
|
if (lockValue.equals(currentLock)) {
|
|
|
|
|
|
|
|
boolean released = redisUtil.set(DOWNLOAD_LOCK_KEY, "false");
|
|
|
|
|
|
|
|
if (!released) {
|
|
|
|
|
|
|
|
logger.error("释放下载任务锁失败");
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
logger.info("成功释放下载锁,锁ID: {}", lockValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
logger.warn("锁已被其他进程修改,不进行释放,当前锁值: {}, 期望锁值: {}", currentLock, lockValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.info("定时从上游下载全部据-----结束");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
logger.info("定时从上游下载全部据-----结束");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void getData(String message){
|
|
|
|
|
|
|
|
logger.error("jiehsou 要发送的数据");
|
|
|
|
|
|
|
|
spsSyncWebSocket.sendMessage(SocketMsgEntity.builder().content(message).type(SocketMsgType.STAT_DATA).remark("我瞎说的数据").build(), "2:" + socketToken);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|