1、点击启动任务按钮会请求/jobInfo/start,执行XxlJobService#start()方法
@RequestMapping("/start") // TODO, resume >> start
@ResponseBody
public ReturnT<String> start(int id) {
return xxlJobService.start(id);
}
2、根据jobId查询XxlJobInfo信息,并添加到XxlJobDynamicSchheduler.addJob()
@Override
public ReturnT<String> start(int id) {
XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id);
String group = String.valueOf(xxlJobInfo.getJobGroup());
String name = String.valueOf(xxlJobInfo.getId());
String cronExpression = xxlJobInfo.getJobCron();
try {
boolean ret = XxlJobDynamicScheduler.addJob(name, group, cronExpression);
return ret?ReturnT.SUCCESS:ReturnT.FAIL;
} catch (SchedulerException e) {
logger.error(e.getMessage(), e);
return ReturnT.FAIL;
}
}
3、 把任务添加到quartz中,并由quartz根据cron表达式触发RemoteHttpJobBean#executeInternal(),再由任务id去执行
public static boolean addJob(String jobName, String jobGroup, String cronExpression) throws SchedulerException {
// 这里的jobName就是任务id
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
JobKey jobKey = new JobKey(jobName, jobGroup);
// 2、valid
if (scheduler.checkExists(triggerKey)) {
return true; // PASS
}
// 3、corn trigger
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing(); // withMisfireHandlingInstructionDoNothing 忽略掉调度终止过程中忽略的调度
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
// 4、由quartz触发的类
Class<? extends Job> jobClass_ = RemoteHttpJobBean.class; // Class.forName(jobInfo.getJobClass());
JobDetail jobDetail = JobBuilder.newJob(jobClass_).withIdentity(jobKey).build();
// 5、开始调度
Date date = scheduler.scheduleJob(jobDetail, cronTrigger);
logger.info(">>>>>>>>>>> addJob success, jobDetail:{}, cronTrigger:{}, date:{}", jobDetail, cronTrigger, date);
return true;
}
4、触发JobTriggerPoolHelper.trigger()进行任务的调度
/**
*这里会用一个自定义的线程池去执行XxlJobTrigger#trigger()
* 当启动的线程数量少于32的时候,会一直创建线程去处理,
* 当线程数量大于32个的时候,后续的线程会放入有界的队列中,并等待60秒
* 当放入队列中的线程数量大于1000个的时候,会继续创建线程
* 直到线程数达到256个
*/
private ThreadPoolExecutor triggerPool = new ThreadPoolExecutor(
32,
256,
60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(1000));
public void addTrigger(final int jobId, final TriggerTypeEnum triggerType, final int failRetryCount, final String executorShardingParam, final String executorParam) {
triggerPool.execute(new Runnable() {
@Override
public void run() {
XxlJobTrigger.trigger(jobId, triggerType, failRetryCount, executorShardingParam, executorParam);
}
});
}
5、load相关信息并执行processTrigger()
public static void trigger(int jobId, TriggerTypeEnum triggerType, int failRetryCount, String executorShardingParam, String executorParam) {
// 根据jobId获取对应的jobInfo
XxlJobInfo jobInfo = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(jobId);
if (jobInfo == null) {
logger.warn(">>>>>>>>>>>> trigger fail, jobId invalid,jobId={}", jobId