程序探活
2020-07-05 本文已影响0人
不存在的bug
背景:xxl-job定时跑批,本地创建专门线程监测定时任务是否执行了,防止xxl-job挂了,及时通知。
@Slf4j
@Component
public final class DetectSubcriber implements DisposableBean,Runnable {
private static final SimpleDateFormat formatdate = new SimpleDateFormat("YYYY-MM-dd");
private static final SimpleDateFormat formatTime = new SimpleDateFormat("HH:mm");
private final Thread thread;
public static volatile Date jobExecDate; //由xxl-job任务线程修改,执行过了的设置当前时间
public static Boolean detectSelfExecFalg = true; //控制当前探测只发送一次提醒
private String specifiedFinishTime; //指定一个定时任务完成之后的时间点
private Long detectIntervalTime; //探测间隔时间,没必要一直跑,合理即可
private DetectSubcriber(@Value("${specified.finish.time}")String specifiedFinishTime,
@Value("${detect.interval.time}")Long detectIntervalTime,
@Autowired TeacherLiveJobHandler teacherLiveJobHandler){
this.specifiedFinishTime = specifiedFinishTime;
this.detectIntervalTime = detectIntervalTime;
this.teacherLiveJobHandler = teacherLiveJobHandler;
this.thread = new Thread(this);
this.thread.setDaemon(true);
this.thread.start();
}
@Override
public void run() {
try {
final Date finishTime = formatTime.parse(specifiedFinishTime);
while(true){
Thread.sleep(detectIntervalTime); //应该先执行,防止系统启动之后就会触发探测报警
final boolean jobNotExec = jobExecDate == null || !formatdate.format(jobExecDate).equals(formatdate.format(new Date()));
final Date currentTime = formatTime.parse(formatTime.format(new Date()));
if (currentTime.before(finishTime)) {
detectSelfExecFalg = true; //在该时间段开启
}
if (jobNotExec && detectSelfExecFalg && currentTime.after(finishTime)) {
detectSelfExecFalg = false; //在currentTime.after(finishTime)内执行一次就行
log.info("xxl-job未执行,触发探活执行。");
//xxl-job挂了,由当前线程触发
try {
//todo 触发定时
}catch (Exception e){
log.error("",e);
}
//todo 发送报警
}
}
}catch (Exception e){
if (specifiedFinishTime == null) {
log.error("启动探活必须指定开始时间(探活开始时间的时间点)【specified.finish.time】。");
}
log.error("探活程序报错:",e);
}
}
@Override
public void destroy() throws Exception {
jobExecDate = null;
}
}
另一个线程:
DetectSubcriber.jobExecDate = new Date(); //应该先执行,下面任务的成功失败和探活无关。不能因为下面任务失败而导致触发探活报警。任务应该有自己的报警
//todo 跑批核心任务
写在后面
这个有必要吗?个人觉得没必要,本身xxl-job肯定是集群部署,故障率很低,万一要是发生了,那应该也是由运维人员及时修复。另一个发生故障的可能就是物理故障,如果都部署在同一台机器那也没啥毛用,不过一般是不会这么部署。同意这么做只是不想费口舌,再者是觉得这挺好玩。一些补偿措施不能为了甩锅而补偿。这程序可能几年也不会触发......