tbscheduler是个非常优秀的调度框架,虽然代码复杂,但是功能强大稳定。
今天主要分析一下里面的TBScheduleManager类。首先摘抄一段玄难大师在代码中的注释:
/**
* 1、任务调度分配器的目标: 让所有的任务不重复,不遗漏的被快速处理。
* 2、一个Manager只管理一种任务类型的一组工作线程。
* 3、在一个JVM里面可能存在多个处理相同任务类型的Manager,也可能存在处理不同任务类型的Manager。
* 4、在不同的JVM里面可以存在处理相同任务的Manager
* 5、调度的Manager可以动态的随意增加和停止
*
* 主要的职责:
* 1、定时向集中的数据配置中心更新当前调度服务器的心跳状态
* 2、向数据配置中心获取所有服务器的状态来重新计算任务的分配。这么做的目标是避免集中任务调度中心的单点问题。
* 3、在每个批次数据处理完毕后,检查是否有其它处理服务器申请自己把持的任务队列,如果有,则释放给相关处理服务器。
*
* 其它:
* 如果当前服务器在处理当前任务的时候超时,需要清除当前队列,并释放已经把持的任务。并向控制主动中心报警。
*
* @author xuannan
*
*/
1、类说明
该类叫做【任务调度分配器】,简单来说,就是用来分配一类任务的类;该分配器管理一组任务线程;
2、实现接口
该类实现了接口
package com.taobao.pamirs.schedule.strategy;
public interface IStrategyTask {
public void initialTaskParameter(String strategyName,String taskParameter) throws Exception;
public void stop(String strategyName) throws Exception;
}
实现两个接口也非常简单,initialTaskParameter用于初始化任务数据,stop用于停止该任务分配器下的一组线程;
2、实现
该类有两个具体的继承;
3、类图
4、构造方法
TBScheduleManager这个类比较重要的方法,就是构造方法,该任务分配器在初始化的时候,就开始进行任务分配和调度。
首先,会在spring的上下文中,获取和任务类型同名的bean。
Object dealBean = aFactory.getBean(this.taskTypeInfo.getDealBeanName());
然后会向zk注册当然机器的信息
this.currenScheduleServer = ScheduleServer.createScheduleServer(this.scheduleCenter,baseTaskType,ownSign,this.taskTypeInfo.getThreadNumber());
this.currenScheduleServer.setManagerFactoryUUID(this.factory.getUuid());
scheduleCenter.registerScheduleServer(this.currenScheduleServer);
继续会启动分配器的心跳线程
this.heartBeatTimer = new Timer(this.currenScheduleServer.getTaskType() +"-" + this.currentSerialNumber +"-HeartBeat");
this.heartBeatTimer.schedule(new HeartBeatTimerTask(this),
new java.util.Date(System.currentTimeMillis() + 500),
this.taskTypeInfo.getHeartBeatRate());
最后,调用模板方法initial();该方法由具体子类进行实现;
5、模板初始化方法
模板初始化方法中,创建一个内部线程,内部线程首先取出任务总量
taskItemCount = scheduleCenter.loadAllTaskItem(currenScheduleServer.getTaskType()).size();
最后启动任务处理器
computerStart();
6、任务处理
首先,会判断任务类型上面的开始时间this.taskTypeInfo.getPermitRunStartTime() == null
如果为空的话,就立即启动;如果不为空,就会按照crontab进行调度处理;
如果到了运行时间,则开始执行任务。
if(isRunNow == true){
this.resume("开启服务立即启动");
}
该方法会调用
this.processor = new TBScheduleProcessorSleep(this,
taskDealBean,this.statisticsInfo);
创建具体的任务处理器,任务处理器中会直接创建在任务类型配置里的线程数量。