你知道多少种定时任务的实现方式?
1. 定时任务的诞生
- 需求分析
- 在平常的业务场景当中,经常有一些场景需要使用到定时任务
- 比如说在某个时间点会发送优惠券、发送短信等等的一些业务操作,难道这些操作都需要人工来进行干预吗?
- 比如一些支付系统,需要在每天的凌晨1点来进行对前一天的清算,难道每次都要一个人来负责这个业务吗?
2. 什么是定时任务?
- 定时任务
- 通过时间表达式这一方式来进行任务调度的被称为定时任务
- 分类
- 单机定时任务
- 单机的容易实现,但应用于集群环境做分布式部署,就会带来重复执行
- 解决方案有很多比如加锁、数据库等,但是增加了很多非业务逻辑
- 分布式调度(分布式定时任务)
- 把需要处理的计划任务放入到统一的平台,实现集群管理调度与分布式部署的定时任务 叫做分布式定时任务
- 支持集群部署、高可用、并行调度、分片处理等
- 单机定时任务
3. 常见定时任务
- 单机:Java自带的java.util.Timer类配置比较麻烦,具有时间延后问题
- 单机:ScheduledExecutorService
- 是基于线程池来进行设计的定时任务类,在这里每个调度的任务都会分配到线程池里的一个线程去执行该任务,并发执行,互不影响
- 单机:SpringBoot框架自带
- SpringBoot使用注解方式开启定时任务
- 启动类里面 @EnableScheduling开启定时任务,自动扫描
- 定时任务业务类 加注解 @Component 被容器扫描
- 定时执行的方法加上注解 @Scheduled(fixedRate=2000) 定期执行一次
4. 为什么需要任务调度平台?
- 因为在传统的Java当中,传统的定时任务实现方案,像上述的Timer、Quartz等
- 它们都有不少缺点
- 不支持集群、不支持统计、没有管理的平台、也没有报警、监控等等
- 在分布式架构当中,有一些场景是需要用到分布式的任务调度的,在同一个服务器中的多个实例任务之间存在着互斥,需要进行统一的调度,所以任务调度需要支持高可用、监控、故障告警等一系列措施。
- 需要统一管理和追踪各个的服务节点之间任务调度的结果,并保存记录任务信息等等
5. 如何解决上述问题?
- 分布式调度平台
6. 常见的分布式调度平台有哪些?
-
Quartz
- Quartz关注点在于定时任务而并非是数据,并没有一套根据数据化处理而定的流程
- 虽然可以实现数据库作业的高可用,但是缺少了分布式的并行调度功能,相对弱点
- 不支持任务分片、没UI界面管理,并行调度、失败策略等也缺少
-
TBSchedule
- 这个是阿里早期开源的分布式任务调度系统,使用的是timer而不是线程池执行任务调度,使用timer在处理异常的时候是有缺陷的,但TBSchedule的作业类型比较单一,文档也缺失得比较严重
- 目前阿里内部使用的是ScheduleX
- 阿里云也有商业化版本: https://help.aliyun.com/product/147760.html
-
Elastic-job
- 当当开发的分布式任务调度系统,功能强大,采用的是zookeeper实现分布式协调,具有高可用与分片。
- 2020年6月,ElasticJob的四个子项目已经正式迁入Apache仓库
- 由 2 个相互独立的子项目 ElasticJob-Lite 和 ElasticJob-Cloud 组成
- ElasticJob-Lite 定位为轻量级****无中心化解决方案,使用jar的形式提供分布式任务的协调服务;
- ElasticJob-Cloud 使用 Mesos 的解决方案,额外提供资源治理、应用分发以及进程隔离等服务
- 地址:https://shardingsphere.apache.org/elasticjob/index_zh.html
-
XXL-JOB
- 大众点评的员工徐雪里在2015年发布的分布式任务调度平台,是轻量级的分布式任务调度框架,目标是开发迅速、简单、清理、易扩展; 老版本是依赖quartz的定时任务触发,在v2.1.0版本开始 移除quartz依赖
- 地址:https://www.xuxueli.com/xxl-job/
7. 如何选择分布式任务调度平台?
暂且只讨论主流的XXL-Job和Elastic-Job。
- XXL-Job 和 Elastic-Job 都具有广泛的用户基础和完善的技术文档,都可以满足定时任务的基本功能需求
- xxl-job 侧重在业务实现简单和管理方便,容易学习,失败与路由策略丰富, 推荐使用在用户基数相对较少,服务器的数量在一定的范围内的场景下使用
- elastic-job关注的点在数据,添加了弹性扩容和数据分片的思路,更方便利用分布式服务器的资源, 但是学习难度较大,推荐在数据量庞大,服务器数量多的时候使用。