xxl-job触发时间问题
xxl-job是一个轻量级分布式定时任务框架,既然是分布式框架,所以一般生产环境会把xxl-job与系统部署在不同服务器上,定时任务的触发是以部署xxl-job的服务器的时间为准的,那么当xxl-job的服务器与系统的服务器的时间不同步时,可能会对系统功能有影响。
这里我引入的是2.2.0版本,系统有一个定时任务,需要每分钟触发一次,并且需要记录是那个时间点的任务,当xxl-job的服务器与系统的服务器的时间不同步时,根据系统服务器获取的时间肯定是不对的,但是要怎样拿到触发任务的时间点呢,根据xxl-job的源码,发现我们获取不到一切有关xxl-job服务的一切信息
if (triggerParam.getExecutorTimeout() > 0) {
// limit timeout
Thread futureThread = null;
try {
//触发任务的一下信息,触发参数、任务信息入库的记录id等
final TriggerParam triggerParamTmp = triggerParam;
FutureTask<ReturnT<String>> futureTask = new FutureTask<ReturnT<String>>(new Callable<ReturnT<String>>() {
@Override
public ReturnT<String> call() throws Exception {
//调用定时任务程序
return handler.execute(triggerParamTmp.getExecutorParams());
}
});
futureThread = new Thread(futureTask);
futureThread.start();
executeResult = futureTask.get(triggerParam.getExecutorTimeout(), TimeUnit.SECONDS);
} catch (TimeoutException e) {
XxlJobLogger.log("<br>----------- xxl-job job execute timeout");
XxlJobLogger.log(e);
executeResult = new ReturnT<String>(IJobHandler.FAIL_TIMEOUT.getCode(), "job execute timeout ");
} finally {
futureThread.interrupt();
}
} else {
// just execute
//调用定时任务程序
executeResult = handler.execute(triggerParam.getExecutorParams());
}
根据源码可以看到,在调用定时任务程序的时候,只将触发定时任务的参数传入,所以我们拿不到有关任务触发的一切信息。
解决办法
xxl-job官方文档提供了每个版本更新迭代的内容,看到在2.3.0版本中新增这样一项内容
【新增】新增任务辅助工具 “XxlJobHelper”:提供统一任务辅助能力,包括:任务上下文信息维护获取(任务参数、任务ID、分片参数)、日志输出、任务结果设置……等;
我们将xxl-job版本升级到2.3.0试试能不能解决时间不统一的问题。将版本升级到2.3.0之后,可以看到源码新加一些东西
//2.3.0版本将定时任务触发的信息放到了上下文中
XxlJobContext xxlJobContext = new XxlJobContext(
triggerParam.getJobId(),
triggerParam.getExecutorParams(),
logFileName,
triggerParam.getBroadcastIndex(),
triggerParam.getBroadcastTotal());
// init job context
XxlJobContext.setXxlJobContext(xxlJobContext);
// execute
XxlJobHelper.log("<br>----------- xxl-job job execute start -----------<br>----------- Param:" + xxlJobContext.getJobParam());
if (triggerParam.getExecutorTimeout() > 0) {
// limit timeout
Thread futureThread = null;
try {
FutureTask<Boolean> futureTask = new FutureTask<Boolean>(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
// init job context
XxlJobContext.setXxlJobContext(xxlJobContext);
handler.execute();
return true;
}
});
futureThread = new Thread(futureTask);
futureThread.start();
Boolean tempResult = futureTask.get(triggerParam.getExecutorTimeout(), TimeUnit.SECONDS);
} catch (TimeoutException e) {
XxlJobHelper.log("<br>----------- xxl-job job execute timeout");
XxlJobHelper.log(e);
// handle result
XxlJobHelper.handleTimeout("job execute timeout ");
} finally {
futureThread.interrupt();
}
} else {
// just execute
handler.execute();
}
根据上面的源码可以看到xxl在调用任务程序之前将定时任务触发的信息放到了上下文中,那么我们就可以在任务程序中从上下文中获取任务的一切信息,首先通过XxlJobHelper.getJobId()静态方法可以拿到任务id,在数据库xxl_job库中存储了xxl的所有信息,我们就可以根据jobId查询到我们想要的信息,包括触发时间。
版权声明:本文为fy2862370237原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。