主流定时任务解决方案全横评

定时任务作为一种按照约定时间执行预期逻辑的通用模式,在企业级开发中承载着丰富的业务场景,诸如后台定时同步数据生成报表,定时清理磁盘日志文件,定时扫描超时订单进行补偿回调等 。程序开发人员在定时任务领域有着诸多框架和方案可供选择,并借此快速实现业务功能实现产品上线 。本文将就当前主流定时任务解决方案进行介绍和分析,期望可以在企业技术选型和项目架构重构时作为参考 。
01
CrontabAliware
01
目标定位
Crontab 作为 linux 内置的可执行命令,可以实现按照 cron 表达式生成的时间执行指定的系统指令或 shell 脚本 。
02
使用方式
crontab 命令语法:
crontab [-u username] [-l | -e | -r ]参数:-u : 只有root用户才能进行这个任务,编辑某个用户的crontab-e : 编辑 crontab 的工作内容-l : 查阅 crontab 的工作内容-r : 移除所有的 crontab 的工作内容配置文件示例:
* * * * * touch ~/crontab_test* 3 * * * ~/backup0 */2 * * * /sbin/service httpd restart03
实现原理
crond 守护进程是通过 Linux 启动时的 init 进程启动,由 cornd 每分钟会检查/etc/crontab 配置文件中是否有需要执行的任务,并通过 /var/log/cron 文件输出定时任务的执行情况 。用户可以使用 Crontab 命令管理/etc/crontab 配置文件 。
04
方案分析
借助 Crontab 用户可以十分便利地快速实现简易的定时任务功能,但存在以下痛点:

  • 定时任务与指定 linux 机器绑定,当机器扩容或者更换时需要重新配置 contab,同时存在单点故障风险
  • 随着定时任务规模增多,无法统一视角对其进行任务进度的追踪和管控,难以维护
  • 功能过于简单,没有超时,重试,阻塞等任务的高级特性
  • 可观测能力差,问题排查定位困难
  • 任务常驻,当无任务执行时造成不必要的资源成本浪费
02
Spring TaskAliware
01
目标定位
Spring 框架提供了开箱即用的定时调度功能,用户可以通过 xml 或者@Scheduled 注解的方式标识指定方法执行的周期 。Spring Task 支持多种任务执行模式,包括带时区配置的 corn,固定延迟,固定速率等 。
02
使用方式
【主流定时任务解决方案全横评】代码实例如下:
@EnableScheduling@SpringBootApplicationpublic class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}}@Componentpublic class MyTask {@Scheduled(cron = "0 0 1 * * *")public void test() {System.out.println("test");}}03
实现原理
Spring Task 原理是在初始化 bean 时借助
ScheduledAnnotationBeanPostProcessor 拦截@Scheduled 注解所标识的方法,并根据每个方法及其注解配置构建相应的 Task 实例注册到 ScheduledTaskRegistrar 中,并在单例 bean 初始化完成后通过 afterSingletonsInstantiated 回调设置 ScheduledTaskRegistrar 中的调度器 TaskScheduler,其底层依赖于 jdk 并发包中的 ScheduledThreadPoolExecutor 实现,并在 afterPropertiesSet 时将所有 Task 添加到 TaskScheduler 中调度执行 。
04
方案分析
借助 Spring Task 用户可以通过注解快速实现对指定方法的周期性执行,支持多种周期性策略 。但与 crontab 相似,同样有如下的痛点:
  • 默认为单线程执行,若前一个任务执行时间较长会导致后续任务阻塞,需要用户自行配置线程池
  • 各个节点独立运行,存在单点风险,无分布式协调机制,要考虑禁止并发执行
  • 随着定时任务规模增多,无法统一视角对其进行任务进度的追踪和管控,难以维护
  • 功能过于简单,没有超时,重试,阻塞等任务的高级特性
  • 可观测能力差,问题排查定位困难
  • 任务常驻,当无任务执行时造成不必要的资源成本浪费
03
ElasticJobAliware
01
目标定位
ElasticJob 作为当当网开源的一款分布式任务框架,提供弹性调度,资源管控,作业治理等诸多特性,其已经成为 Apache Shardingsphere 的子项目 。ElasticJob 目前由 2 相互独立的子项目 ElasticJob-Lite 和 ElasticJob-Cloud 组成,ElasticJob-Lite 定位为轻量级无中心化解决方案,使用 jar 的形式提供分布式任务的协调服务;ElasticJob-Cloud 使用 Mesos 的解决方案,额外提供资源治理、应用分发以及进程隔离等服务 。一般使用 ElasticJob-Lite 即可满足需求 。


推荐阅读