【引言】
上篇博客简单分析了xxl-job项目的启动流程,本篇博客分析的内容是调度任务的触发。在之前的博客中,也了解到xxl-job是基于quartz实现的,下面就从源码学习下是如何实现的。
【实现】
任务调度的核心类是RemoteHttpJobBean,它继承了QuartzJobBean,默认是允许并行机制的,代码如下:
/**
* http job bean
* “@DisallowConcurrentExecution” diable concurrent, thread size can not be only one, better given more
* @author xuxueli 2015-12-17 18:20:34
*/
//@DisallowConcurrentExecution
public class RemoteHttpJobBean extends QuartzJobBean {
private static Logger logger = LoggerFactory.getLogger(RemoteHttpJobBean.class);
@Override
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
// load jobId
JobKey jobKey = context.getTrigger().getJobKey();
Integer jobId = Integer.valueOf(jobKey.getName());
// trigger
//XxlJobTrigger.trigger(jobId);
JobTriggerPoolHelper.trigger(jobId, -1, TriggerTypeEnum.CRON);
}
}
以上核心方法是JobTriggerPoolHelper.trigger(),在此方法中,根据路由策略区分,分片广播策略是一种处理方法,其他策略归并为另一种处理方法,策略不同,调用不同的实现。
总结一下,处理动作分为五步,1、save log-id - > 2、prepare trigger-info - > 3.1、trigger-param - > 3.2、trigger-run (route run / trigger remote executor) - > 4、save trigger-info - > 5、monitor trigger 。核心是3.2中的runExecutor(),向执行器中发送指令,源码如下:
/**
* run executor
* @param triggerParam
* @param address
* @return ReturnT.content: final address
*/
public static ReturnT runExecutor(TriggerParam triggerParam, String address){
ReturnT runResult = null;
try {
//创建一个ExcutorBiz 的对象,重点在这个方法里面
ExecutorBiz executorBiz = XxlJobDynamicScheduler.getExecutorBiz(address);
// 这个run 方法不会最终执行,仅仅只是为了触发 proxy object 的 invoke方法,同时将目标的类型传送给服务端, 因为在代理对象的invoke的方法里面没有执行目标对象的方法
runResult = executorBiz.run(triggerParam);
} catch (Exception e) {
logger.error(">>>>>>>>>>> xxl-job trigger error, please check if the executor[{}] is running.", address, e);
runResult = new ReturnT(ReturnT.FAIL_CODE, ""+e );
}
StringBuffer runResultSB = new StringBuffer(I18nUtil.getString("jobconf_trigger_run") + ":");
runResultSB.append("
address:").append(address);
runResultSB.append("
code:").append(runResult.getCode());
runResultSB.append("
msg:").append(runResult.getMsg());
runResult.setMsg(runResultSB.toString());
runResult.setContent(address);
return runResult;
}
XxlJobDynamicScheduler.getExecutorBiz (address) , 通过机器地址,获取一个executor , 从缓存中查是否存在,缓存中没有的话,创建代理对象,(ExecutorBiz) new NetComClientProxy(ExecutorBiz.class, address, accessToken).getObject(),源码如下:
/**
* rpc proxy
* @author xuxueli 2015-10-29 20:18:32
*/
public class NetComClientProxy implements FactoryBean
【总结】
以上就是调度中心,触发任务之后执行的核心代码,重点就是最后的发送http请求给执行器,由执行器去执行代码,下篇博客将分析执行器接受到任务的处理过程。