在国内目前最著名的两个开源分布式调度,一个是elastic-job,一个是xxl-job,前段时间一直在看xxl-job相关的实现原理,最近一直在研究elastic-job的实现原理,xxl-job是中心化的分布式调度,实现原理为基于quartz集群解决方案实现,elastic-job-Lite为去中心化,依赖于zookeeper做分布式协调实现,闲话少说,直接上图:
elasticJob作业结构图.png
我们能看到,在elastic-job中,实现quartz原生job的类为Lite-Job,在创建jobDetail对象的时候,jobDetail中的jobClass为LiteJob.class,(而在XXL-Job中,实现类为RemoteHttpJobBean.class),啥都不说了,直接上代码:
//elastic-job JobScheduler类private JobDetail createJobDetail(final String jobClass) { //初始化job为LiteJob.class JobDetail result = JobBuilder.newJob(LiteJob.class).withIdentity(liteJobConfig.getJobName()).build(); //......次数忽略其他代码 return result; }
// addJob 新增@SuppressWarnings("unchecked")public static boolean addJob(String jobName, String jobGroup, String cronExpression) throws SchedulerException { // JobDetail : jobClass 此处定义jobClass为RemoteHttpJobBean Class<? extends Job> jobClass_ = RemoteHttpJobBean.class; // Class.forName(jobInfo.getJobClass()); JobDetail jobDetail = JobBuilder.newJob(jobClass_).withIdentity(jobKey).build(); // ......此处忽略其他代码 return true; }
所以,最终作业的触发都是由LiteJob这个对象去触发的,该对象实现了原生quartz的job接口,quartz最终执行是执行这个对象的execute方法。
我们知道,在使用elasticJob的过程中,我们只需要实现elasticJob的simpleJob,DataFlowJob接口,按照上面所说,最终作业的执行是交由作业类LiteJob去执行的,那LiteJob类又是怎么与这两个接口相关联在一起的,simpleJob,DataFlowJob都是继承于接口ElasticJob,而LiteJob这个对象持有elasticJob接口的对象,然后LiteJob作业类就与simpleJob,DataFlowJob相关联在一起了。上liteJob的代码,一目了然。
public final class LiteJob implements Job { @Setter private ElasticJob elasticJob; @Setter private JobFacade jobFacade; @Override public void execute(final JobExecutionContext context) throws JobExecutionException { JobExecutorFactory.getJobExecutor(elasticJob, jobFacade).execute(); } }
在LiteJob的execute方法中,实际调用是通过JobExecutorFactory.getExecutor()方法具体去判断作业类型为simpleJob还是DataFlowJob,看下面代码:
public static AbstractElasticJobExecutor getJobExecutor(final ElasticJob elasticJob, final JobFacade jobFacade) { if (null == elasticJob) { return new ScriptJobExecutor(jobFacade); } if (elasticJob instanceof SimpleJob) { return new SimpleJobExecutor((SimpleJob) elasticJob, jobFacade); } if (elasticJob instanceof DataflowJob) { return new DataflowJobExecutor((DataflowJob) elasticJob, jobFacade); } throw new JobConfigurationException("Cannot support job type '%s'", elasticJob.getClass().getCanonicalName()); }
实际的作业执行是在LiteJob的excute()方法中按照作业配置的类型返回ElasticJob的真实类型,然后去执行。实际上的ElasticJob作业与quartz执行的job对象没有关系,而是在执行quartz的job(LiteJob)的过程中,去执行elasticJob的execute方法。没看代码以前还以为ElasticJob是直接实现的quartz的Job接口,xxl-Job是集中式,中心化的分布式调度系统,执行和这个又不一样,这里就暂时不分析。
作者:一滴水的坚持
链接:https://www.jianshu.com/p/d442390ac3d1