xxl-job触发时间问题

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版权协议,转载请附上原文出处链接和本声明。