原理篇-- 定时任务xxl-job-服务端(admin)项目启动过程--JobCompleteHelper初始化 (6)


前言

本文对JobCompleteHelper 工作内容进行介绍。


一、JobCompleteHelper 作用:

JobCompleteHelper是xxl-job-admin中的一个辅助类,主要用于处理任务执行完成后的相关操作。其作用包括:

  1. 标记任务执行完成:JobCompleteHelper负责在任务执行完成后对任务状态进行标记,通知xxl-job-admin任务执行成功,更新任务执行记录。

  2. 日志记录:记录任务执行完成的相关日志信息,包括执行结果、执行时间、消耗资源等,以便后续跟踪和分析。

  3. 处理任务回调:在任务执行完成后,JobCompleteHelper可能需要触发一些任务执行完成后的回调操作,比如发送通知、更新数据等。

  4. 监控任务执行状态:通过JobCompleteHelper,xxl-job-admin能够实时监控任务的执行情况,及时发现任务执行异常或超时等情况。

总的来说,JobCompleteHelper在xxl-job-admin中扮演着处理任务执行完成后相关操作的重要角色,确保任务执行成功并及时记录相关信息,提高任务执行的可靠性和监控能力。

二、JobCompleteHelper 源码内容:

2.1 start() 初始化方法:

2.1.1 任务执行日志回调线程池:

private static Logger logger = LoggerFactory.getLogger(JobCompleteHelper.class);
	
	private static JobCompleteHelper instance = new JobCompleteHelper();
	public static JobCompleteHelper getInstance(){
		return instance;
	}

	// ---------------------- monitor ----------------------

	private ThreadPoolExecutor callbackThreadPool = null;
	private Thread monitorThread;
	private volatile boolean toStop = false;
	public void start(){

	// for callback  初始化 日志回调线程池,后续用于执行 执行器项目执行任务返回的 任务状态
	callbackThreadPool = new ThreadPoolExecutor(
			2,
			20,
			30L,
			TimeUnit.SECONDS,
			new LinkedBlockingQueue<Runnable>(3000),
			new ThreadFactory() {
				@Override
				public Thread newThread(Runnable r) {
					return new Thread(r, "xxl-job, admin JobLosedMonitorHelper-callbackThreadPool-" + r.hashCode());
				}
			},
			new RejectedExecutionHandler() {
				@Override
				public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
					r.run();
					logger.warn(">>>>>>>>>>> xxl-job, callback too fast, match threadpool rejected handler(run now).");
				}
			});
		}

2.1.2 monitorThread线程标记失效的任务:

// for monitor
monitorThread = new Thread(new Runnable() {

	@Override
	public void run() {

		// wait for JobTriggerPoolHelper-init
		try {
			TimeUnit.MILLISECONDS.sleep(50);
		} catch (InterruptedException e) {
			if (!toStop) {
				logger.error(e.getMessage(), e);
			}
		}

		// monitor
		while (!toStop) {
			try {
				// 任务结果丢失处理:调度记录停留在 "运行中" 状态超过10min,
				// 且对应执行器心跳注册失败不在线,则将本地调度主动标记失败;
				Date losedTime = DateUtil.addMinutes(new Date(), -10);
				// 获取已经被触发器触发(正在执行中),并且触发已经超过了10分钟,任务还没有执行完毕的;
				// 并且任务没有触发器的 ;任务id 集合
				/**
				* SELECT
					t.id
				FROM
					xxl_job_log t
					LEFT JOIN xxl_job_registry t2 ON t.executor_address = t2.registry_value
				WHERE
					t.trigger_code = 200
						AND t.handle_code = 0
						AND t.trigger_time <![CDATA[ <= ]]> #{losedTime}
						AND t2.id IS NULL;
				**/
				List<Long> losedJobIds  = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().findLostJobIds(losedTime);

				if (losedJobIds!=null && losedJobIds.size()>0) {
					for (Long logId: losedJobIds) {
						
						XxlJobLog jobLog = new XxlJobLog();
						jobLog.setId(logId);

						jobLog.setHandleTime(new Date());
						jobLog.setHandleCode(ReturnT.FAIL_CODE);
						jobLog.setHandleMsg( I18nUtil.getString("joblog_lost_fail") );
						// 标记任务为失效状态
						XxlJobCompleter.updateHandleInfoAndFinish(jobLog);
					}

				}
			} catch (Exception e) {
				if (!toStop) {
					logger.error(">>>>>>>>>>> xxl-job, job fail monitor thread error:{}", e);
				}
			}

                  try {
                      TimeUnit.SECONDS.sleep(60);
                  } catch (Exception e) {
                      if (!toStop) {
                          logger.error(e.getMessage(), e);
                      }
                  }

              }

		logger.info(">>>>>>>>>>> xxl-job, JobLosedMonitorHelper stop");

	}
});
monitorThread.setDaemon(true);
monitorThread.setName("xxl-job, admin JobLosedMonitorHelper");
monitorThread.start();

2.2 callback 执行器执行任务后的回调:

public ReturnT<String> callback(List<HandleCallbackParam> callbackParamList) {
	// 交由 callbackThreadPool线程池执行任务
	callbackThreadPool.execute(new Runnable() {
		@Override
		public void run() {
			for (HandleCallbackParam handleCallbackParam: callbackParamList) {
				// 执行任务
				ReturnT<String> callbackResult = callback(handleCallbackParam);
				logger.debug(">>>>>>>>> JobApiController.callback {}, handleCallbackParam={}, callbackResult={}",
						(callbackResult.getCode()== ReturnT.SUCCESS_CODE?"success":"fail"), handleCallbackParam, callbackResult);
			}
		}
	});

	return ReturnT.SUCCESS;
}

private ReturnT<String> callback(HandleCallbackParam handleCallbackParam) {
	// valid log item 获取任务执行的日志
	XxlJobLog log = XxlJobAdminConfig.getAdminConfig().getXxlJobLogDao().load(handleCallbackParam.getLogId());
	if (log == null) {
		return new ReturnT<String>(ReturnT.FAIL_CODE, "log item not found.");
	}
	// 任务是否已经被回调处理过了 
	if (log.getHandleCode() > 0) {
		return new ReturnT<String>(ReturnT.FAIL_CODE, "log repeate callback.");     // avoid repeat callback, trigger child job etc
	}

	// handle msg
	// 填充回调结果状态和信息 并更新日志对象
	StringBuffer handleMsg = new StringBuffer();
	if (log.getHandleMsg()!=null) {
		handleMsg.append(log.getHandleMsg()).append("<br>");
	}
	if (handleCallbackParam.getHandleMsg() != null) {
		handleMsg.append(handleCallbackParam.getHandleMsg());
	}

	// success, save log
	log.setHandleTime(new Date());
	log.setHandleCode(handleCallbackParam.getHandleCode());
	log.setHandleMsg(handleMsg.toString());
	XxlJobCompleter.updateHandleInfoAndFinish(log);

	return ReturnT.SUCCESS;
}

2.3 toStop() 释放资源:

容器关闭是触发toStop() 方法,释放资源。

public void toStop(){
	//  重置toStop 标识  使monitorThread 线程结束while 循环
	toStop = true;

	// stop registryOrRemoveThreadPool
	// 日志回调线程 停止
	callbackThreadPool.shutdownNow();

	// stop monitorThread (interrupt and wait)
	monitorThread.interrupt();
	try {
		// 等待monitorThread  线程任务结束
		monitorThread.join();
	} catch (InterruptedException e) {
		logger.error(e.getMessage(), e);
	}
}

总结

本文对JobCompleteHelper 工作内容进行介绍;

  • 15
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
xxl-job是一个分布式任务调度框架,可以用于实现定时任务的调度和执行。在xxl-job中,定时任务的配置和管理主要涉及到三个部分:xxl-job-admin、执行器组件和定时任务的数据处理。 1. xxl-job-adminxxl-job的管理后台,可以通过调用com.xxl.job.admin.controller.JobApiController.callback接口来设置定时任务。这个接口可以用于添加、修改、删除定时任务,以及启动、停止定时任务的执行。 2. 执行器组件是用于执行定时任务的组件,其中的配置文件地址为/xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/java/com/xxl/job/executor/core/config/XxlJobConfig.java。在这个配置文件中,你可以设置定时任务的一些参数,比如调度线程池大小、任务执行器等。 3. 定时任务的数据处理需要在xxl-job-executor-sample-springboot项目中进行,这是业务代码所在的项目。在这个项目中,你可以使用BEAN模式来设置定时任务。BEAN模式是指通过在类中定义方法并使用@XxlJob注解来标识定时任务,然后在XxlJobConfig.java配置文件中将这个类注册为定时任务。这种方式比较简单,但在官网上没有提供具体的示例。 所以,如果你想使用xxl-job来实现定时任务,你可以先在xxl-job-admin中设置定时任务,然后在执行器组件中配置定时任务的相关参数,最后在xxl-job-executor-sample-springboot项目中使用BEAN模式设置定时任务。这样就能够实现定时任务的调度和执行了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值