由于存在着这种情况,我们就想着把这些定时任务脚本管理起来,并且需要具备高可用。这就需要一个分布式调度任务系统。🧐
概述
关于定时执行任务的工具或框架系统有很多,一般情况下针对不同的应用场景可以选择适合该场景下工具或框架。例如:如果不想引入其他语言,只使用shell来执行的,可以使用 linux Crontab 来执;如果是基于Spring 想着简单实现一个定时任务,可以使用@Scheduled注解。如果按照是否为单独的系统来分可以分为两类:1. 系统或框架自带的定时执行方法或工具。2. 单独作为一个服务的调度任务系统。
系统或框架自带的定时执行方法或工具
Linux Crontab
只能单机执行与linux机器固定绑定,可以通过cron 表达式定时执行shell脚本。简单易使用,不好后期维护,只能执行shell脚本。
Java 原生的定时器Timer
优点:简单,不用引入其他框架。
缺点:
- Timer在执行所有定时任务时只会创建一个线程,如果某个任务的执行时间过长,那么将破坏其他TimerTask的定时精确性
- Timer的另一个问题是,如果TimerTask抛出了一个未检查的异常,那么Timer线程不会捕获异常,此时会终止定时线程,并且不会恢复。
参考:java定时器之Timer使用与原理分析
Spring 的 @Scheduled注解
一般集成于项目中,小任务很方便,不能分布式。注意,如果使用了,在集群部署的时候需要使用分布式锁来限制
单独作为一个服务的调度任务系统
这部分主要的调度任务系统都是开源系统,并且大部分是基于Java的Quratz框架来封装的
XXL-JOB
(美团公司个人开放)“调度中心”基于集群Quartz实现,提供官方docker镜像,作业与语言无关。社区较活跃,一直有维护状态。 较多公司使用。
elastic-job
当当开源的,使用 Zookeeper 实现分布式分布式部署。2019年10月前停止维护过一段时间,后面才重新维护。并且在2020 年 5 月 28 日成为 Apache ShardingSphere
的子项目未来前景应该很不错。
Saturn
唯品会开源的,基于elastic-job。支持多种语言作业,语言无关(Java/Go/C++/PHP/Python/Ruby/shell)。社区活跃度一般,小部分公司使用。
基于Quartz自己开发
开源的有个好处就是大部分都是开箱即用。但是通常来说,如果直接使用开源的系统,后期改造起来都是比较麻烦,而且如果有什么问题,排查起来也比较麻烦,毕竟不是自己的系统。基于我们要求的调度任务系统,并不需要太多功能,所以我们计划自己基于Quartz框架来开发调度任务系统。
原生quartz任务的缺点
- 只能在单个服务器上运行,或者在多个服务器上集群运行,在单个数据库的情况下,不能指定不同服务器运行不同任务。
为了解决原生Quartz的确定,我们基于Quartz和GRPC框架来开发任务调度系统,具体方案如下:
- 利用一台服务器部署quartz服务和作为服务注册中心(rpc调用中心)。
- 通过创建不同的cron定时任务,通过传入服务器地址,要执行的方法,定时远程rpc调用不同服务器上的方法。
- 定义每个master和slaver都定义http请求调度,命令行请求调度和邮箱发送请求调度,当不需要指定执行机器时,则通过随机找一个slaver去执行。
初版项目地址:https://github.com/KANLON/job-scheduling (这个还不太完善,目前执行还不支持执行的高可用,后面需要修改执行任务的机器为一个列表,遍历该列表执行)
总结
如果没有时间或资源搭一套调度任务系统,可以使用系统或框架自带的定时执行方法或工具来简单使用。如果需要统一管理,方便后期维护建议首先使用开源系统的。开源的分布式调度任务系统中建议使用xxl-job
,该开源系统社区活跃度高,使用的公司数量相对较多,而且一直有在维护。
以下是我整理的思维导图: