简介
概述
XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。
特性
- 弹性扩容缩容:一旦有新执行器机器上线或者下线,下次调度时将会重新分配任务;
- 注册中心:执行器会周期性自动注册任务, 调度中心将会自动发现注册的任务并触发执行。同时,也支持手动录入执行器地址;
- 任务状态:支持动态开启、关闭任务,支持及时终止运行中的任务;
- 一致性:“调度中心”通过DB锁保证集群分布式调度的一致性, 一次任务调度只会触发一次执行
- 触发策略:Cron触发、固定间隔触发、固定延时触发、API(事件)触发、人工触发、父子任务触发;
- 路由策略:第一个、最后一个、轮询、随机、一致性HASH、最不经常使用、最近最久未使用、故障转移、忙碌转移等;
- 实时日志:支持在线查看调度结果,并且支持以Rolling方式实时查看执行器输出的完整的执行日志;
- 调度过期策略:调度中心错过调度时间的补偿处理策略,包括:忽略、立即补偿触发一次等;
- 阻塞处理策略:调度过于密集执行器来不及处理时的处理策略,策略包括:单机串行(默认)、丢弃后续调度、覆盖之前调度;
- 任务超时控制:支持自定义任务超时时间,任务运行超时将会主动中断任务;
- 任务失败重试:支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;其中分片任务支持分片粒度的失败重试;
- 任务进度监控:支持实时监控任务进度;
- 运行报表:支持实时查看运行数据,如任务数量、调度次数、执行器数量等;以及调度报表,如调度日期分布图,调度成功分布图等;
- 线程池隔离:调度线程池进行隔离拆分,慢任务自动降级进入”Slow”线程池,避免耗尽调度线程,提高系统稳
xxl-job的使用
客户端配置
使用tips
-
任务处理器必须注入spring容器才能生效
-
同一个执行器下,不能存在同名的任务处理器
-
在服务端定义任务时,通过JobHandler输入框指定任务处理器
-
使用XxlJobHelper.log()打印的日志才能在查看日志时被读取。
-
使用XxlJobHelper.getJobParam()在任务处理器获取任务参数
-
使用XxlJobHelper.handleFail()、XxlJobHelper.handleSuccess()设置任务处理器的执行结果
-
使用下列方法获取分片参数
int shardIndex = XxlJobHelper.getShardIndex(); int shardTotal = XxlJobHelper.getShardTotal();
xxl-job客户端
客户端的启动流程
定义xxl-job客户端,其中一个步骤是将XxlJobSpringExecutor注入spring容器,可见XxlJobSpringExecutor就是xxl-job客户端的启动入口。
XxlJobSpringExecutor继承了XxlJobExecutor,实现了AppliactionAware、SmartInitializingSingleton、DisposableBean接口。它们的作用依次是:
- 父类XxlJobExecutor定义了启动客户端的主要步骤。
- 通过实现AppliactionAware接口,可以通过setApplicationContext方法得到spring中ApplicationContext对象。
- 通过实现SmartInitializingSingleton接口,当所有单例bean被实例化之后,XxlJobSpringExecutor实现的afterSingletonsInstantiated方法会被调用。
- 通过实现DisposableBean接口,当XxlJobSpringExecutor的bean被销户时,XxlJobSpringExecutor实现的destroy方法会被调用。
重点关注SmartInitializingSingleton的afterSingletonsInstantiated方法,XxlJobSpringExecutor对它的实现是:
@Override
public void afterSingletonsInstantiated() {
// init JobHandler Repository
/*initJobHandlerRepository(applicationContext);*/
// init JobHandler Repository (for method)
initJobHandlerMethodRepository(applicationContext);
// refresh GlueFactory
GlueFactory.refreshInstance(1);
// super start
try {
super.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
可以看到最后调用XxlJobSpringExecutor的父类的start(),XxlJobExecutor的start()的逻辑是:
// ---------------------- start + stop ----------------------
public void start() throws Exception {
// init logpath
XxlJobFileAppender.initLogPath(logPath);
// init invoker, admin-client
initAdminBizList(adminAddresses, accessToken);
// init JobLogFileCleanThread
JobLogFileCleanThread.getInstance().start(logRetentionDays);
// init TriggerCallbackThread
TriggerCallbackThread.getInstance().start();
// init executor-server
initEmbedServer(address, ip, port, appname, accessToken);
}
从注释中可以看出xxl-job的启动流程:
- init JobHandler Repository:初始化任务处理器。
- refresh GlueFactory:刷新GlueFactory工厂
- init logpath:初始化日志文件夹。
- init invoker, admin-client:初始化xxl-job服务端的client。
- init JobLogFileCleanThread:初始化日志文件清理线程
- init TriggerCallbackThread:创建触发器回调线程
- init executor-server:初始化任务执行器内置服务
- 在第七步,还初始化了任务执行器注册线程
任务执行器和任务处理器的关系
@XxlJob和任务处理器的关系
任务处理器和任务线程的关系
xxl-jo的一次调度过程
xxl-job的日志查看
xxl-job服务端
时间轮调度
快慢线程池