一个分布式定时任务,需要具备有以下几点功能:
1)核心功能:定时调度、任务管理、可观测日志
2)高可用:集群、分片、失败处理
3)高性能:分布式锁
4)扩展功能:可视化运维、多语言、任务编排
一个分布式定时任务调度框架一般分为3个模块:
调度中心:负责接收并分配任务,任务调度,核心调度模块。
任务执行:负责执行任务,执行完反馈给调度中心。
监控中心:主要负责节点管理,任务队列管理,监控管理等。
JOB: 定义自己的任务
JobDetail: 封装 JOB 对象的
scheduler调度器: 管理全部的任务(Scheduler)
Trigger触发器: 开启新的线程执行任务(jobDetail)
在Quartz中,线程分为Scheduler调度线程和任务执行线程。
Scheduler调度线程主要有:执行常规调度的线程和执行misfired trigger的线程。
Scheduler有一个QuartzSchedulerThread(Thread的子类)属性,在scheduler实例化的时候,实例化了一个对象,并用ThreadExecutor启动该线程对象。该线程就是调度线程,主要任务就是不停的从JobStore中获取即将被触发的触发器(默认30s调度一次)。
使用数据库分布式事务锁。
1)默认不开启悲观锁,需要在配置文件中
org.quartz.jobStore.acquireTriggersWithinLock=true
2)也可以集成redis实现分布式锁
任务:定义某一个任务,绑定实现IScheduleTaskDealSingle或者IScheduleTaskDealMulti的任务类,同时可以通过设置任务项,将任务同一时间分片。
策略:定义执行的时间,一般采用cron表达式。绑定某个任务以及绑定机器。用于按照某个时间点分配给不同机器执行某个任务。策略可以设置线程组数量,就是使用多少给线程组来同时处理任务。
机器:监控调度机的状态。
策略会根据最小ID的机器,分配任务执行。定时器使用Timer实现。
使用zookeeper来做分布式锁,就是机器注册zookeeper后,会查找所有策略中绑定的机器,然后写入到策略节点下面。策略会根据最小ID的机器,分配任务执行。
搞清楚几个参数的作用
1)策略中的线程组:该参数是该策略总共启动多少个线程组来执行任务
2)任务中的任务项:可以按照0、1、2、3、4或者A、B、C、D等划分
3)selectTasks(String taskParameter, String ownSign, int taskItemNum, List list, int eachNum)方法
其中 List list就是分配到不同线程组的任务项。
那么任务分片就是根据设定的任务项,将其分配到不同的线程组中实现分片功能。
分布式任务调度SchedulerX是阿里巴巴自研的基于Akka架构的分布式任务调度平台,兼容开源XXL-JOB、ElasticJob,支持Cron定时、一次性任务、任务编排、分布式执行批量任务等功能,具备高可用、可视化、可运维、低延时等能力。
elasti-job分为2独立2大块,一个是lite-core(核心去中心化的调度),一个是cloud(监控平台)。
schedule:是会选出一个leader,作为每次任务执行时,分配任务(包括分片)的机器
job:是真正执行任务
Simple类型作业:意为简单实现,未经任何封装的类型。需实现SimpleJob接口。该接口仅提供单一方法用于覆盖,此方法将定时执行。与Quartz原生接口相似,但提供了弹性扩缩容和分片等功能。
Dataflow类型作业:Dataflow类型用于处理数据流,需实现DataflowJob接口。该接口提供2个方法可供覆盖,分别用于抓取(fetchData)和处理(processData)数据。(类似tbschedule的seletTask)
Script类型作业:Script类型作业意为脚本类型作业,支持shell,python,perl等所有类型脚本。只需通过控制台或代码配置scriptCommandLine即可,无需编码。执行脚本路径可包含参数,参数传递完毕后,作业框架会自动追加最后一个参数为作业运行时信息。
定时任务触发时,如需重新分片,则通过主服务器分片,分片过程中阻塞,分片结束后才可执行任务。如分片过程中主服务器下线,则先选举主服务器,再分片
使用zookeeper来做分布式锁,就是机器注册zookeeper后,会选出leader,然后做分配工作,最后执行
AverageAllocationJobShardingStrategy:基于平均分配算法的分片策略,也是默认的分片策略。
OdevitySortByNameJobShardingStrategy:根据作业名的哈希值奇偶数决定IP升降序算法的分片策略。
RotateServerByNameJobShardingStrategy:根据作业名的哈希值对服务器列表进行轮转的分片策略。
elastic-job使用了quartz的调度机制,内部原理一致,他可以看作是quartz的一个扩展实现,使用注册中心(zookeeper)替换了quartz的jdbc数据存储方式,此外,elastic-job又支持分片等特殊功能。对应的概念:
Job | LiteJob |
Trigger | cron |
Scheduler | JobScheduler |
底层其实使用LiteJob 实现了quartz的Job接口,在JobScheduleController.java创建创建trigger。
调度中心:一个用于发布任务的中心,可以控制任务启动和停止,已经维护监控注册和日志
执行器:用于执行任务的客户端,调度中心会根据注册执行器,按照算法分配任务执行。执行器有一个appName,与调度中心的执行器管理的appName对应,名称一致才会分配任务
任务:设置任务、执行策略、分片机制、执行器等属性,其中执行器与执行器管理中选择一个执行器名称,这样就可以分配到对应appName的执行器。
执行器集群部署时,任务路由策略选择”分片广播”情况下,一次任务调度将会广播触发对应集群中所有执行器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务;
利用容器化,定时启动执行器,执行任务。