TBSchedule源码学习笔记-启动过程
TBSchedule基本概念及原理
概念介绍
TBSchedule是一个支持分布式的调度框架,能让一种批量任务或者不断变化的任务,被动态的分配到多个主机的JVM中,不同的线程组中并行执行。基于ZooKeeper的纯Java实现,由Alibaba开源。
代码实现
起步配置
/* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
InputStream in = TaskCenter.class.getClassLoader().getResourceAsStream("schedule-conf.properties");
Properties p = new Properties();
p.load(in);
TBScheduleManagerFactory scheduleManagerFactory = new TBScheduleManagerFactory();
scheduleManagerFactory.setApplicationContext(applicationContext);
try {
scheduleManagerFactory.init(p);
} catch (Exception e) {
e.printStackTrace();
}
}
TBScheduleManagerFactory(com.taobao.pamirs.schedule.strategy.TBScheduleManagerFactory)是个什么?代码里对他的描述是“调度服务器构造器”,只关心他的启动过程
public void init(Properties p) throws Exception {
//这里initialThread是个什么,作用和意义?
if(this.initialThread != null){
this.initialThread.stopThread();
}
//lock是一个锁(ReentrantLock)使用默认的非公平锁
this.lock.lock();
try{
this.scheduleDataManager = null;
this.scheduleStrategyManager = null;
ConsoleManager.setScheduleManagerFactory(this);
if(this.zkManager != null){
this.zkManager.close();
}
this.zkManager = new ZKManager(p);
this.errorMessage = "Zookeeper connecting ......" + this.zkManager.getConnectStr();
initialThread = new InitialThread(this);
initialThread.setName("TBScheduleManagerFactory-initialThread");
initialThread.start();
}finally{
this.lock.unlock();
}
到这里需要知道,initalThread是个什么线程,该线程的作用?点开看一下run方法的实现
@Override
public void run() {
//factory就是这个调度服务器
facotry.lock.lock();
try {
int count =0;
while(facotry.zkManager.checkZookeeperState() == false){
count = count + 1;
if(count % 50 == 0){
facotry.errorMessage = "Zookeeper connecting ......" + facotry.zkManager.getConnectStr() + " spendTime:" + count * 20 +"(ms)";
log.error(facotry.errorMessage);
}
Thread.sleep(20);//貌似每20ms 检测一次zk的连接状态
if(this.isStop ==true){
return;
}
}
//如果连接成功则初始化数据
facotry.initialData();
} catch (Throwable e) {
log.error(e.getMessage(),e);
}finally{
facotry.lock.unlock();
}
}
这个initalThread内部会竞争factory的锁,所以如果zk一直检查失败,锁得不到释放,有可能一直阻塞线程,导致启动项目启动问题?while出口的isStop是什么?isStop莫非是一个取消状态?代表停止这个线程,这个线程可能更多的做一个zk状态的启动前自检。
多虑了,后边他的主线程会释放锁…..
scheduleDataManager是什么?具体作用是`com.taobao.pamirs.schedule.taskmanager.IScheduleDataManager
他是一个调度中心客户端,启动过程几乎没怎么参与。
scheduleStrategyManager是什么?类名`com.taobao.pamirs.schedule.zk.ScheduleStrategyDataManager4ZK
官方没有给出他的命名,暂且取名为调度策略管理器,提供了一些策略查询和更新的功能。
ConsoleManager.setScheduleManagerFactory(this);,貌似与管理控制台有关?
实际使用中,控制台和调度项目是不相关的,那么这个ConsoleManager是什么?
然后剩下的就是初始化一个zk的管理器,最后释放锁
问题是集成tbschedule只需这样就行,剩下的都是一些zk配置操作。如果和zk相关应该包含两个点:
1.在哪里添加监视点的?即tbschedule如何响应 rootPath 配置的节点路径下的相关变化的?
2.监视点的动作是怎样的
目前为止值得看下去的就两行,分别是com.taobao.pamirs.schedule.strategy.TBScheduleManagerFactory
类下的init(Properties p)方法。
public void init(Properties p) throws Exception {
//.......//
ConsoleManager.setScheduleManagerFactory(this);
//.......//
还有com.taobao.pamirs.schedule.strategy.InitialThread
类下的
public void run() {
//......//
facotry.initialData();
//......//
}
其中TBScheduleManagerFactory类的init方法里的代码行 更像一个setter方法,正常编码时会避免在setter中做赋值以外操作的。暂且不管
然后facotry.initialData(); 方法名告诉我该方法会初始化数据。
/**
* 在Zk状态正常后回调数据初始化
* @throws Exception
*/
public void initialData() throws Exception{
//初始化zk管理器
this.zkManager.initial();
//初始化调度中心客户端
this.scheduleDataManager = new ScheduleDataManager4ZK(this.zkManager);
//初始化调度策略管理器
this.scheduleStrategyManager = new ScheduleStrategyDataManager4ZK(this.zkManager);
if (this.start == true) {
// 注册调度管理器
this.scheduleStrategyManager.registerManagerFactory(this);
if(timer == null){
timer = new Timer("TBScheduleManagerFactory-Timer")