Elastic-Job是基于quartz的一款分布式任务调度器,利用zookeeper做分布式协调,保存配置信息,分片信息,服务器实例的信息,接下来几篇博客将从源码探究一下Elastic-Job是如何实现的。
这篇文章先从启动流程大体上看一下,之后会仔细分析启动过程中的具体工作。
上面就是我们要使用Elastic-Job所需要配置的内容。
首先需要解析
/**
* 注册中心的命名空间处理器.
*
* @author zhangliang
*/
public final class RegNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("zookeeper", new ZookeeperBeanDefinitionParser());
}
}
ZookeeperBeanDefinitionParser解析类就是用来解析
在这个解析器里面,我们可以发现解析完标签后最终会生成ZookeeperRegistryCenter这个类,并调用它的init方法,这个类就是操作Zookeeper的核心类,内部使用curator来做具体的工作,init方法会初始化和zookeeper的连接。
/**
* 简单作业的命名空间解析器.
*
* @author caohao
*/
public final class SimpleJobBeanDefinitionParser extends AbstractJobBeanDefinitionParser {
@Override
protected BeanDefinition getJobTypeConfigurationBeanDefinition(final ParserContext parserContext, final BeanDefinition jobCoreConfigurationBeanDefinition, final Element element) {
BeanDefinitionBuilder result = BeanDefinitionBuilder.rootBeanDefinition(SimpleJobConfiguration.class);
result.addConstructorArgValue(jobCoreConfigurationBeanDefinition);
if (Strings.isNullOrEmpty(element.getAttribute(CLASS_ATTRIBUTE))) {
result.addConstructorArgValue(parserContext.getRegistry().getBeanDefinition(element.getAttribute(JOB_REF_ATTRIBUTE)).getBeanClassName());
} else {
result.addConstructorArgValue(element.getAttribute(CLASS_ATTRIBUTE));
}
return result.getBeanDefinition();
}
}
SimpleJobBeanDefinitionParser是简单作业的解析类,它继承自AbstractJobBeanDefinitionParser,实现了getJobTypeConfigurationBeanDefinition方法用来解析SimpleJobConfiguration类的属性,而AbstractJobBeanDefinitionParser的parseInternal才最终创建了工作类SpringJobScheduler
public SpringJobScheduler(final ElasticJob elasticJob, final CoordinatorRegistryCenter regCenter, final LiteJobConfiguration jobConfig, final ElasticJobListener... elasticJobListeners) {
super(regCenter, jobConfig, getTargetElasticJobListeners(elasticJobListeners));
this.elasticJob = elasticJob;
}
elasticJob 是用户自己实现的job,SpringJobScheduler继承了JobScheduler,在实例化结束后会调用它的init方法来初始化作业
public void init() {
//在zookeeper上更新job的配置信息
LiteJobConfiguration liteJobConfigFromRegCenter = schedulerFacade.updateJobConfiguration(liteJobConfig);
//在内存中更新当前job的分片的数目
JobRegistry.getInstance().setCurrentShardingTotalCount(liteJobConfigFromRegCenter.getJobName(), liteJobConfigFromRegCenter.getTypeConfig().getCoreConfig().getShardingTotalCount());
//创建任务调度器
JobScheduleController jobScheduleController = new JobScheduleController(
createScheduler(), createJobDetail(liteJobConfigFromRegCenter.getTypeConfig().getJobClass()), liteJobConfigFromRegCenter.getJobName());
//在内存中保存当前任务的任务调度器和注册中心
JobRegistry.getInstance().registerJob(liteJobConfigFromRegCenter.getJobName(), jobScheduleController, regCenter);
//注册作业启动信息
schedulerFacade.registerStartUpInfo(!liteJobConfigFromRegCenter.isDisabled());
//启动定时任务
jobScheduleController.scheduleJob(liteJobConfigFromRegCenter.getTypeConfig().getCoreConfig().getCron());
}
JobRegistry相当于当前服务器的服务注册表,当前服务器可以执行的job的信息都会注册到JobRegistry中。jobScheduleController是任务调度控制器,之后我们会详细看一下它是如何工作的。schedulerFacade调度器的服务类,Elastic-Job主要通过它和zookeeper打交道。
public void scheduleJob(final String cron) {
try {
if (!scheduler.checkExists(jobDetail.getKey())) {
scheduler.scheduleJob(jobDetail, createTrigger(cron));
}
scheduler.start();
} catch (final SchedulerException ex) {
throw new JobSystemException(ex);
}
}
init方法的最后一步就是启动定时器,就是quartz,在里面我们发现有一个jobDetail是在创建jobScheduleController的时候创建的,在下一篇文章中,我们将看一下jobScheduleController的创建过程,和Elastic-Job是如何与quartz联系在一起的。