tbschedule使用 在线计算器在线使用
yuyutoo 2024-10-26 16:09 13 浏览 0 评论
一、简介
tbschedule是淘宝开源的,能够让批量任务或变化的任务,被动态的分配到不同主机(可分布式)的jvm,不同的线程组中并行执行。所有任务能够不重复,不遗漏的执行。
二、tbschedule知识点
2.1 tbschedule特点
tbschedule特点如下:
能够让批量任务或变化的任务,被动态的分配到不同主机(可分布式)的jvm,不同的线程组中并行执行。
所有任务能够不重复,不遗漏的执行。
2.2 tbschedule实现
tbschedule的任务、策略等调度数据是存储在zookeeper中的。
tbschedule的执行是基于jdk的Timer和TimerTask实现的。
tbschedule中的任务,是依附于策略而运行的。也就是说,任务定义了要执行的行为,包括任务名称、取数据和数据处理的bean、每次取数的数量、执行的开始与结束时间、任务项等信息,而策略定义了要执行的任务、在哪台机器上执行、所有机器最大线程组,单个机器线程组数等,并控制任务的执行与停止。
三、tbschedule关键类
3.1 ZKManager
ZKManager就是最基本的zookeeper会话管理类,内容包括zookeeper的创建、会话的连接或重连接、关闭会话等。
3.2 TBScheduleManagerFactory
TBScheduleManagerFactory是tbschedule管理类,包含的功能有:
3.2.1 配置zookeeper
配置zookeeper,并创建zookeeper会话,zookeeper的配置信息有:zkConnectString, rootPath, userName, password, zkSessionTimeout, isCheckParentPath
3.2.2 调度任务和调度策略的管理器生成
ScheduleDataManager4ZK,调度任务管理器(对应在zookeeper中的数据),在此进行初始化和生成。
ScheduleStrategyDataManager4ZK,调度策略管理器(对应在zookeeper中的数据),在此进行初始化和生成。
3.2.3 调度服务的重启、停止等
如stopServer(String strategyName)、stopAll()、reStart()等。
3.3 ScheduleServer
任务处理器(可以理解为线程组),由一组线程(n个线程)组成,每个任务处理器有全局唯一的标识符,一般以IP$UUID[例如192.168.1.100$0C78F0C0FA084E54B6665F4D00FA73DC]的形式出现,一个任务类型的数据可以n个任务处理器处理。内分为Sleep模式和NotSleep模式:
3.3.1 sleep模式
sleep模式,当一线程处理完任务,同时从任务池取不到任务时,若其它线程仍工作,则自己休眠,若其它线程已休眠,则新调取需要处理的数据,同时唤醒其它休眠线程处理数据;
3.3.2 NotSleep模式
NotSleep模式,当一线程处理完任务,同时从任务池取不到任务时,则新调取需要处理的数据,同时唤醒其它休眠线程处理数据;
3.4 TaskItem
任务项,也就是将待处理的任务(数据),进行分片划分,
如:可以按数据的id按10取模,这样就将数年数据划分成了0、1、2、3、4、5、6、7、8、9共10个任务项;
也可按数据的首字母分成了A、B、C、D、E、F、G、H、I、J、K、L、M、N、O、P、Q、R、S、T、U、V、W、X、Y、Z供26个任务项。
这个可以根据需要自行定义的。
3.5 TaskDealBean
自定义的任务处理类,需要实现Schedule的接口IScheduleTaskDealMulti(批处理)或者IScheduleTaskDealSingle(单任务处理),内部主要有两个方法,一个是筛选需当前任务处理器处理的数据,另一个是处理已筛选好的数据。
3.6 OwnSign
环境,指定运行环境,如:开发环境、测试环境、预发环境、生产环境。在筛选当前任务处理器需处理的数据时,会传入该参数。
3.7 ScheduleTaskType
任务的配置类,包括运行的线程数(threadNumber)、运行时间,任务项分组、没数据时的休眠时间、每次取数的量等
3.8 ScheduleStrategy
策略的配置类,所有机器的最大线程组数(assignNum),单个jvm的线程数(numOfSingleServer),运行机器(IPList)等信息。
四、tbschedule使用
这里以tbschedule与spring结合为例,介绍使用的开发步骤。其中尽可能多的理解tbschedule和spring后,能理解tbschedule与spring整合的方式其实有多种形式的,在此介绍一种方式 ,任务和策略在spring启动时进行自动注册。
4.1 添加maven依赖
另一种方式是直接下载源码,这种方式更好,因为目前版本的tbschedule是有bug的,如查看zookeeper连接信息时,tbschedule源码是新建已在代码写死的属性,或者读取tomcat中未有的tbschedule配置类,这是不对,应直接读取已有的zookeeper属性,当然直接maven依赖也不影响使用),spring依赖包在此略过。
<dependency>
<groupId>com.taobao.pamirs.schedule</groupId>
<artifactId>tbschedule</artifactId>
<version>3.2.18</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
</dependency>
4.2 下载tbschedule源码
下载地址:http://code.taobao.org/p/tbschedule, 将路径下的tbschedule/branches /3.1.0/src/WebRoot/schedule文件夹复制到工程webapp下,里面tbschdule的jsp文件,便于页面查看与控制任务执行。
4.3 编写自定义抽象任务类
编写自定义抽象任务类,内包含调度任务配置类scheduleTaskType和调度策略配置类scheduleStrategy,便于过会对任务进行自动注册任务和策略信息,该类同时可实现接口IScheduleTaskDealSingle,继承该抽象类的任务类实现其中的方法,如AbstractBaseScheduleTask.java:
public abstract class AbstractBaseScheduleTask<T> implements IScheduleTaskDealSingle<T> {
/**
* 调度任务的配置
*/
private ScheduleTaskType scheduleTaskType;
/**
* 调度策略的配置
*/
private ScheduleStrategy scheduleStrategy;
public ScheduleTaskType getScheduleTaskType() {
return scheduleTaskType;
}
public void setScheduleTaskType(ScheduleTaskType scheduleTaskType) {
this.scheduleTaskType = scheduleTaskType;
}
public ScheduleStrategy getScheduleStrategy() {
return scheduleStrategy;
}
public void setScheduleStrategy(ScheduleStrategy scheduleStrategy) {
this.scheduleStrategy = scheduleStrategy;
}
}
4.4 编写启动类
编写启动类,继承TBScheduleManagerFactory类,用于配置zookeeper信息,实现ApplicationListener接口,并实现其内部方法,用于在spring容器启动后,加载调度任务和调度策略的配置信息到zookeeper中,如类SystemTBScheduleManagerFactory.java :
public class SystemTBScheduleManagerFactory extends TBScheduleManagerFactory implements ApplicationListener<ContextRefreshedEvent>{
@Override
public void onApplicationEvent(ContextRefreshedEvent event) { //注册调度任务和调度策略
try {
super.init(); //默认初始化信息
IScheduleDataManager iScheduleDataManager = null;
ScheduleStrategyDataManager4ZK scheduleStrategyDataManager4ZK = null;
int waitSecond = 120; //默认初始化等待时间,最长120秒
while((null == iScheduleDataManager || null == scheduleStrategyDataManager4ZK) && waitSecond>0){
waitSecond--;
TimeUnit.SECONDS.sleep(1); //等待1秒
try{
iScheduleDataManager = super.getScheduleDataManager();//获取调度任务管理器
scheduleStrategyDataManager4ZK = super.getScheduleStrategyManager();//获取调度策略管理器
}catch (Exception e){
}
}
Assert.notNull(iScheduleDataManager,"初始化tbschedule配置信息失败"); //若仍初始化失败,则抛异常
Assert.notNull(scheduleStrategyDataManager4ZK,"初始化tbschedule配置信息失败"); //若仍初始化失败,则抛异常
Map<String,AbstractBaseScheduleTask> taskMap = event.getApplicationContext().getBeansOfType(AbstractBaseScheduleTask.class);
for(Map.Entry<String,AbstractBaseScheduleTask> m : taskMap.entrySet()){
String key = m.getKey();
AbstractBaseScheduleTask task = m.getValue();
ScheduleTaskType taskType = task.getScheduleTaskType();
taskType.setBaseTaskType("task_"+key); //任务类型(任务名称)
taskType.setDealBeanName(key);
ScheduleStrategy scheduleStrategy = task.getScheduleStrategy();
scheduleStrategy.setStrategyName("strategy_"+key); //策略名称
scheduleStrategy.setTaskName(taskType.getBaseTaskType()); //任务名称
scheduleStrategy.setKind(ScheduleStrategy.Kind.Schedule);
iScheduleDataManager.updateBaseTaskType(taskType);
scheduleStrategyDataManager4ZK.updateScheduleStrategy(scheduleStrategy);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
4.5 编写任务类
编写任务类,继承前面自定义的抽象类AbstractBaseScheduleTask.java,如:
public class SimpleTask extends AbstractBaseScheduleTask<Date> {
/**
* 执行单个任务
* @param task Object
* @param ownSign 当前环境名称
* @throws Exception
*/
public boolean execute(Date task, String ownSign) throws Exception{
System.out.println("dispose task : "+task.getTime()); //当前任务处理器内的线程处理数据
return true;
}
/**
* 根据条件,查询当前调度服务器可处理的任务
* @param taskParameter 任务的自定义参数
* @param ownSign 当前环境名称
* @param taskItemNum 当前任务类型的任务队列数量
* @param taskItemList 当前调度服务器,分配到的可处理队列
* @param eachFetchDataNum 每次获取数据的数量
* @return
* @throws Exception
*/
public List<Date> selectTasks(String taskParameter, String ownSign, int taskItemNum, List<TaskItemDefine> taskItemList, int eachFetchDataNum) throws Exception {
List<Date> dateList = new ArrayList<>();
List<Long> taskIdList = new ArrayList<>();
for(TaskItemDefine t : taskItemList){ //确定当前任务处理器需处理的任务项id
taskIdList.add(Long.valueOf(t.getTaskItemId()));
}
for(int i=0;i<eachFetchDataNum;i++){ // 添加最多指定数量的待处理数据
Date date = new Date(); //生成待处理数据
Long remainder = date.getTime() % taskItemNum ;
if(taskIdList.contains(remainder)){ //根据数据取模,判断当前待处理数据,是否应由当前任务处理器处理
dateList.add(date);
}
TimeUnit.SECONDS.sleep(1);
}
return dateList; //返回当前任务处理器需要处理的数据
}
/**
* 获取任务的比较器,主要在NotSleep模式下需要用到
* @return
*/
public Comparator<Date> getComparator() {
return null;
}
}
6、配置spring文件spring-tbschedule.xml
配置spring文件spring-tbschedule.xml,包含启动类和任务类配置。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!--tbschedule管理器初始化(配置zookeeper,注册调度任务和调度策略)-->
<bean id="systemTBScheduleManagerFactory" class="com.dragon.tbscheduleStudy.system.SystemTBScheduleManagerFactory">
<property name="zkConfig">
<map>
<entry key="zkConnectString" value="127.0.0.1:2181" />
<entry key="rootPath" value="/myself/tbscheduleStudy" />
<entry key="userName" value="root" />
<entry key="password" value="123456" />
<entry key="zkSessionTimeout" value="8000" />
<entry key="isCheckParentPath" value="true" />
</map>
</property>
</bean>
<!--任务simpleTask-->
<bean id="simpleTask" class="com.dragon.tbscheduleStudy.task.SimpleTask" >
<property name="scheduleTaskType">
<bean class="com.taobao.pamirs.schedule.taskmanager.ScheduleTaskType">
<!--允许执行的开始时间-->
<property name="permitRunStartTime" value="0 0 0 * * ?" />
<!--允许执行的结束时间-->
<property name="permitRunEndTime" value="59 59 23 * * ?" />
<!--当没有数据的时候,休眠的时间-->
<property name="sleepTimeNoData" value="3000" />
<!--在每次数据处理晚后休眠的时间-->
<property name="sleepTimeInterval" value="1000" />
<!--每次获取数据的数量-->
<property name="fetchDataNumber" value="10" />
<!--任务项数组-->
<property name="taskItems">
<list>
<value>0:{TYPE=A,KIND=1}</value>
<value>1:{TYPE=B,KIND=2}</value>
<value>2:{TYPE=C,KIND=3}</value>
</list>
</property>
</bean>
</property>
<property name="scheduleStrategy">
<bean class="com.taobao.pamirs.schedule.strategy.ScheduleStrategy">
<!--最大线程组数量-->
<property name="assignNum" value="9" />
<!--单个机器的线程组数量-->
<property name="numOfSingleServer" value="3" />
<!--策略运行的机器-->
<property name="IPList">
<list>
<value>127.0.0.1</value>
</list>
</property>
</bean>
</property>
</bean>
</beans>
4.7 配置web.xml文件
配置web.xml文件,如:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-tbschedule.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
4.8 修改项目index.jsp页面
修改项目的index.jsp页面,重定向到tbschedule首页,如:
<%
response.sendRedirect("schedule/index.jsp");
%>
至此,开发流程结束,
启动项目,在浏览器输入http://localhost:8080/schedule/index.jsp,可查看任务情况,
若想修改配置,则输入地址http://localhost:8080/schedule/index.jsp?manager=true即可
相关推荐
- Python操作Word文档神器:python-docx库从入门到精通
-
Python操作Word文档神器:python-docx库从入门到精通动动小手,点击关注...
- Python 函数调用从入门到精通:超详细定义解析与实战指南 附案例
-
一、函数基础:定义与调用的核心逻辑定义:函数是将重复或相关的代码块封装成可复用的单元,通过函数名和参数实现特定功能。它是Python模块化编程的基础,能提高代码复用性和可读性。定义语法:...
- 等这么长时间Python背记手册终于来了,入门到精通(视频400集)
-
本文毫无套路!真诚分享!前言:无论是学习任何一门语言,基础知识一定要扎实,基础功非常的重要,找一个有丰富编程经验的老师或者师兄带着你会少走很多弯路,你的进步速度也会快很多,无论我们学习的目的是什么,...
- 图解Python编程:从入门到精通系列教程(附全套速查表)
-
引言本系列教程展开讲解Python编程语言,Python是一门开源免费、通用型的脚本编程语言,它上手简单,功能强大,它也是互联网最热门的编程语言之一。Python生态丰富,库(模块)极其丰富,这使...
- Python入门教程(非常详细)从零基础入门到精通,看完这一篇就够
-
本书是Python经典实例解析,采用基于实例的方法编写,每个实例都会解决具体的问题和难题。主要内容有:数字、字符串和元组,语句与语法,函数定义,列表、集、字典,用户输入和输出等内置数据结构,类和对象,...
- Python函数全解析:从入门到精通,一文搞定!
-
1.为什么要用函数?函数的作用:封装代码,提高复用性,减少重复,提高可读性。...
- Python中的单例模式:从入门到精通
-
Python中的单例模式:从入门到精通引言单例模式是一种常用的软件设计模式,它保证了一个类只有一个实例,并提供一个全局访问点。这种模式通常用于那些需要频繁创建和销毁的对象,比如日志对象、线程池、缓存等...
- 【Python王者归来】手把手教你,Python从入门到精通!
-
用800个程序实例、5万行代码手把手教你,Python从入门到精通!...
- Python从零基础入门到精通:一个月就够了
-
如果想从零基础到入门,能够全职学习(自学),那么一个月足够了。...
- Python 从入门到精通:一个月就够了
-
要知道,一个月是一段很长的时间。如果每天坚持用6-7小时来做一件事,你会有意想不到的收获。作为初学者,第一个月的月目标应该是这样的:熟悉基本概念(变量,条件,列表,循环,函数)练习超过30个编...
- Python零基础到精通,这8个入门技巧让你少走弯路,7天速通编程!
-
Python学习就像玩积木,从最基础的块开始,一步步搭建出复杂的作品。我记得刚开始学Python时也是一头雾水,走了不少弯路。现在回头看,其实掌握几个核心概念,就能快速入门这门编程语言。来聊聊怎么用最...
- 神仙级python入门教程(非常详细),从0到精通,从看这篇开始!
-
python入门虽然简单,很多新手依然卡在基础安装阶段,大部分教程对一些基础内容都是一带而过,好多新手朋友,对一些基础知识常常一知半解,需要在网上查询很久。...
- Python类从入门到精通,一篇就够!
-
一、Python类是什么?大家在生活中应该都见过汽车吧,每一辆真实存在、能在路上跑的汽车,都可以看作是一个“对象”。那这些汽车是怎么生产出来的呢?其实,在生产之前,汽车公司都会先设计一个详细的蓝图...
- 学习Python从入门到精通:30天足够了,这才是python基础的天花板
-
当年2w买的全套python教程用不着了,现在送给有缘人,不要钱,一个月教你从入门到精通1、本套视频共487集,本套视频共分4季...
- 30天Python 入门到精通(3天学会python)
-
以下是一个为期30天的Python入门到精通学习课程,专为零基础新手设计。课程从基础语法开始,逐步深入到面向对象编程、数据处理,最后实现运行简单的大语言模型(如基于HuggingFace...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)