LTS(light-task-scheduler)主要用于解决分布式任务调度问题,支持实时任务,定时任务和Cron任务。有较好的伸缩性,扩展性,健壮稳定性而被多家公司使用。
项目主页 https://github.com/ltsopensource/light-task-scheduler
原来项目使用Quartz作为定时器解决方案,但是Quartz没有可视化的任务运行时调度和监控(有数据库,但是需要自己开发界面),每次想要修改定时器配置都比较麻烦,所以引入了LTS
该框架主要有四个节点:
- JobClient:主要负责提交任务, 并接收任务执行反馈结果。
- JobTracker:负责接收并分配任务,任务调度。
- TaskTracker:负责执行任务,执行完反馈给JobTracker。
- Monitor:(管理后台)主要负责节点管理,任务队列管理,监控管理等。
由于目前系统所需要的任务都是固定任务,所已其中JobClient全部在页面中进行提交,所以不部署
Monitor使用官方提供页面(war),直接部署到tomcat,默认用户名密码均为admin
JobTracker部署
clone项目的源码,运行根目录下的sh build.sh或build.cmd脚本,会在dist目录下生成lts-{version}-bin文件夹。
或者直接解压dist下面原有的lts-1.6.8-beta1-bin.zip,也能实现同样效果,本人使用了第二种方法。
修改生成的或解压的文件夹中conf/zoo文件夹下的配置文件,修改为实际使用ZooKeeper和MySQL的配置
在生成的或解压的文件夹中执行 sh jobtracker.sh zoo start 即可启动JobTracker
TaskTracker使用
tasktracker需要在业务中实现代码,简单说是自己编写一个任务执行类,实现JobRunner接口,在run方法中实现自己的逻辑即可。
贴一个官方提供的TaskTracker例子
public class MyJobRunner implements JobRunner {
@Override
public Result run(JobContext jobContext) throws Throwable {
try {
// TODO 业务逻辑
// 会发送到 LTS (JobTracker上)
jobContext.getBizLogger().info("测试,业务日志啊啊啊啊啊");
} catch (Exception e) {
return new Result(Action.EXECUTE_FAILED, e.getMessage());
}
return new Result(Action.EXECUTE_SUCCESS, "执行成功了,哈哈");
}
}
由于原来的项目使用的了Spring,所以直接写配置文件即可暴露节点,同样贴上官方例子:
<bean id="taskTracker" class="com.github.ltsopensource.spring.TaskTrackerAnnotationFactoryBean" init-method="start">
<property name="jobRunnerClass" value="com.github.ltsopensource.example.support.MyJobRunner"/>
<property name="bizLoggerLevel" value="INFO"/>
<property name="clusterName" value="test_cluster"/>
<property name="registryAddress" value="zookeeper://127.0.0.1:2181"/>
<property name="nodeGroup" value="test_trade_TaskTracker"/>
<property name="workThreads" value="20"/>
<property name="configs">
<props>
<prop key="job.fail.store">leveldb</prop>
</props>
</property>
</bean>
启动项目,节点就暴露成功了。
一个TaskTracker执行多种任务
一般一个系统中往往不止一个任务,需要使用LTS对多个任务进行调度,一开始本人的想法是在一个项目中启动多个任务节点来接受任务调度。后来发现一个JVM中使用多个TaskTracker实例比较浪费资源,在正式项目运行过程中出现了文件句柄过多导致任务大量失败的情况,所以已经弃用。参考了LTS作者提供的文档以后,对任务进行了简单封装,以满足这种需求。
- 创建一个集中的任务调度器,该bean在启动时将IOC容器中所有JobRunner取出放入一个MAP中,当该JOB被LTS调用时根据参数判断具体调度那个任务
* @author ElinZhou
* @version $Id: JobRunnerDispatcher.java , v 0.1 2016/6/24 16:39 ElinZhou Exp $
*/
public class JobRunnerDispatcher implements JobRunner, ApplicationContextAware {
private static final ConcurrentHashMap<String/*type*/, JobRunner> JOB_RUNNER_MAP = new ConcurrentHashMap<String, JobRunner>();
@Override
public Result run(JobContext jo