feat: ASW-73 新增 environment 状态检查定时任务
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
package net.geedge.asw.common.config.job;
|
||||
|
||||
import cn.hutool.log.Log;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import net.geedge.asw.common.util.T;
|
||||
import net.geedge.asw.module.environment.job.JobEnvironmentStatusChecker;
|
||||
import net.geedge.asw.module.sys.service.ISysConfigService;
|
||||
import org.quartz.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.util.TimeZone;
|
||||
|
||||
@Configuration
|
||||
public class JobConfig {
|
||||
|
||||
private static final Log log = Log.get();
|
||||
|
||||
private static final String JOB_NAME_PREFIX = "ASW_JOB";
|
||||
private static final String JOB_DEFAULT_GROUP = "SYSTEM";
|
||||
|
||||
/**
|
||||
* get job key
|
||||
* job_name=ASW_JOB_{name}
|
||||
* group_name=SYSTEM
|
||||
*/
|
||||
private static JobKey getJobKey(String name) {
|
||||
String jobName = T.StrUtil.concat(true, JOB_NAME_PREFIX, "_", name);
|
||||
return new JobKey(jobName, JOB_DEFAULT_GROUP);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private Scheduler scheduler;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
@Autowired
|
||||
private ISysConfigService sysConfigService;
|
||||
|
||||
@Bean
|
||||
public JobDetail JobEnvironmentStatusChecker() {
|
||||
return JobBuilder.newJob(JobEnvironmentStatusChecker.class)
|
||||
.withIdentity(getJobKey(JobEnvironmentStatusChecker.class.getSimpleName()))
|
||||
.storeDurably()
|
||||
.build();
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() throws SchedulerException {
|
||||
// JobEnvironmentStatusChecker
|
||||
createCronScheduleJob(JobEnvironmentStatusChecker(), environment.getProperty("asw.cron.JobEnvironmentStatusChecker", "0 0/1 * * * ? *"));
|
||||
}
|
||||
|
||||
/**
|
||||
* create cron schedule job
|
||||
* 先删后增
|
||||
*/
|
||||
private void createCronScheduleJob(JobDetail jobDetail, String cronExpression) throws SchedulerException {
|
||||
JobKey key = jobDetail.getKey();
|
||||
|
||||
boolean jobExists = scheduler.checkExists(key);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("[createCronScheduleJob] [key: {}] [exists: {}]", key.toString(), jobExists);
|
||||
}
|
||||
if (jobExists) {
|
||||
scheduler.deleteJob(key);
|
||||
log.debug("[createCronScheduleJob] [key: {}] [deleted]", key.toString());
|
||||
}
|
||||
|
||||
String timezone = sysConfigService.getValue("timezone");
|
||||
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).inTimeZone(TimeZone.getTimeZone(timezone));
|
||||
|
||||
CronTrigger cronTrigger = TriggerBuilder.newTrigger()
|
||||
.forJob(jobDetail)
|
||||
.withSchedule(cronScheduleBuilder)
|
||||
.build();
|
||||
scheduler.scheduleJob(jobDetail, cronTrigger);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package net.geedge.asw.module.environment.job;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.log.Log;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import net.geedge.asw.common.util.RCode;
|
||||
import net.geedge.asw.common.util.T;
|
||||
import net.geedge.asw.module.environment.entity.EnvironmentEntity;
|
||||
import net.geedge.asw.module.environment.entity.EnvironmentSessionEntity;
|
||||
import net.geedge.asw.module.environment.service.IEnvironmentService;
|
||||
import net.geedge.asw.module.environment.service.IEnvironmentSessionService;
|
||||
import org.apache.commons.lang3.time.StopWatch;
|
||||
import org.quartz.DisallowConcurrentExecution;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@DisallowConcurrentExecution
|
||||
public class JobEnvironmentStatusChecker extends QuartzJobBean {
|
||||
|
||||
private static final Log log = Log.get();
|
||||
|
||||
@Autowired
|
||||
private IEnvironmentService envService;
|
||||
|
||||
@Autowired
|
||||
private IEnvironmentSessionService envSessionService;
|
||||
|
||||
@Override
|
||||
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
|
||||
Thread.currentThread().setName("JobEnvironmentStatusChecker");
|
||||
|
||||
log.info("[JobEnvironmentStatusChecker] [begin]");
|
||||
StopWatch sw = new StopWatch();
|
||||
sw.start();
|
||||
try {
|
||||
this.environmentStatusChecker();
|
||||
} catch (Exception e) {
|
||||
log.error(e, "[JobEnvironmentStatusChecker] [error]");
|
||||
} finally {
|
||||
sw.stop();
|
||||
}
|
||||
log.info("[JobEnvironmentStatusChecker] [finshed] [Run Time: {}]", sw.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* environment status checker
|
||||
* <p>
|
||||
* 1. update entity status、lastHealthCheck
|
||||
* 2. close the offline env session
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void environmentStatusChecker() {
|
||||
List<EnvironmentEntity> list = envService.list();
|
||||
for (EnvironmentEntity entity : list) {
|
||||
Thread.ofVirtual().start(() -> {
|
||||
String result = null;
|
||||
try {
|
||||
JSONObject paramJSONObject = entity.getParamJSONObject();
|
||||
String url = paramJSONObject.getStr("url");
|
||||
String token = paramJSONObject.getStr("token");
|
||||
|
||||
HttpRequest request = T.HttpUtil.createGet(String.format("%s/api/v1/env/status", url));
|
||||
request.header("Authorization", token);
|
||||
|
||||
HttpResponse response = request.execute();
|
||||
log.info("[environmentStatusChecker] [env: {}] [status: {}]", entity.getId(), response.getStatus());
|
||||
|
||||
if (response.isOk()) {
|
||||
result = response.body();
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
log.error(e, "[environmentStatusChecker] [request api error] [env: {}]", entity.getId());
|
||||
}
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("[environmentStatusChecker] [env: {}] [result: {}]", entity.getId(), result);
|
||||
}
|
||||
|
||||
entity.setStatus(0);
|
||||
entity.setLastHealthCheck(System.currentTimeMillis());
|
||||
|
||||
if (T.StrUtil.isNotEmpty(result)) {
|
||||
try {
|
||||
JSONObject jsonObject = T.JSONUtil.parseObj(result);
|
||||
if (T.ObjectUtil.equal(RCode.SUCCESS.getCode(), jsonObject.getInt("code"))) {
|
||||
JSONObject data = jsonObject.getJSONObject("data");
|
||||
String status = data.getStr("status");
|
||||
if (T.StrUtil.equals("online", status)) {
|
||||
entity.setStatus(1);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e, "[environmentStatusChecker] [parse result error] [env: {}]", entity.getId());
|
||||
}
|
||||
}
|
||||
|
||||
// update entity status、lastHealthCheck
|
||||
envService.update(new LambdaUpdateWrapper<EnvironmentEntity>()
|
||||
.set(EnvironmentEntity::getStatus, entity.getStatus())
|
||||
.set(EnvironmentEntity::getLastHealthCheck, entity.getLastHealthCheck())
|
||||
.eq(EnvironmentEntity::getId, entity.getId())
|
||||
);
|
||||
|
||||
// close the offline env session
|
||||
if (0 == entity.getStatus()) {
|
||||
envSessionService.update(new LambdaUpdateWrapper<EnvironmentSessionEntity>()
|
||||
.set(EnvironmentSessionEntity::getStatus, 2)
|
||||
.set(EnvironmentSessionEntity::getEndTimestamp, System.currentTimeMillis())
|
||||
.eq(EnvironmentSessionEntity::getStatus, 1)
|
||||
.eq(EnvironmentSessionEntity::getEnvId, entity.getId())
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,4 +6,8 @@ import net.geedge.asw.module.sys.entity.SysConfigEntity;
|
||||
|
||||
public interface ISysConfigService extends IService<SysConfigEntity> {
|
||||
|
||||
String getValue(String key);
|
||||
|
||||
String getValueOrDefault(String key, String defaultValue);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,26 @@
|
||||
package net.geedge.asw.module.sys.service.impl;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
import net.geedge.asw.common.util.T;
|
||||
import net.geedge.asw.module.sys.dao.SysConfigDao;
|
||||
import net.geedge.asw.module.sys.entity.SysConfigEntity;
|
||||
import net.geedge.asw.module.sys.service.ISysConfigService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class SysConfigServiceImpl extends ServiceImpl<SysConfigDao, SysConfigEntity> implements ISysConfigService {
|
||||
|
||||
@Override
|
||||
public String getValue(String key) {
|
||||
SysConfigEntity config = this.getOne(new LambdaQueryWrapper<SysConfigEntity>().eq(SysConfigEntity::getParamKey, key));
|
||||
return config == null ? "" : config.getParamValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValueOrDefault(String key, String defaultValue) {
|
||||
String value = this.getValue(key);
|
||||
return T.StrUtil.isEmpty(value) ? defaultValue : value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user