前言
java技术栈使用定时任务框架肯定首选quartz,quartz本身支持分布式执行,其原理是借助数据库实现分布式锁竞争保证任务不会同时在多台机器上执行。
本文介绍springboot默认定时任务实现原理,以及在springboot单机模式下如何管理项目中所有定时任务:查看任务列表,动态修改定时cron表达式等。
执行流程
为了更清晰的了解springboot定时任务工作原理便绘制了定时任务初始化流程图。
该流程图主要做三件事
- 通过@EnableScheduling自动装配SchedulingConfiguration实例进而装配定时任务后置处理实例该实例实现了spring多个生命周期接口如图中所示设置bean名称Aware接口,设置bean工程Aware接口,最重要的设置容器上下文Aware接口
- 通过发布订阅接口实现初始化定时任务所用定时器,执行器并注入到后置处理器的注册器中
- 由于springbean初始化会调用各种处理器,因此定时任务后置处理器会将带有定时任务注解的bean封装为task并执行
ScheduledAnnotationBeanPostProcessor 类图
如果了解sprinboot的启动原理那么结合类图+流程图可以很直观的将上述流程分析清楚。
定时任务管理
通过上述解析后如果想要管理定时任务需要通过接口获取到下图中 scheduledTasks然后通过更改对应的task便可以修改定时任务了。
在流程分析中spring容器发出上下文刷新事件时该后置处理器会通过bean工厂获取所有实现了SchedulingConfigurer接口,借助该接口可以获取scheduledTaskRegister,scheduledTaskRegister管理当前应用所有定时任务,并可以动态修改定时任务。
因此只需要定义配置类实现该接口即可,此时ScheduleConf 即获取到了定时任务注册器引用
只需要在业务代码中将ScheduleConf注入即可获取到所有定时任务。
总结
虽然springboot提供了默认的定时任务,但目前企业应用都是分布式部署显然默认定时任务不能满足分布式环境下只有一台任务可以执行的问题。因此在springboot或springcloud项目中还是引入quartz后进行分布式任务的集成。
如果在对分布式任务有任务间以来需求可以考虑airflow(python 开发)与dolpinescheduler(java 开发),两者都是分布式调度开源框架。
airflow 分布式部署需要 数据库 redis
海豚调度 需要数据库 zookeeper
springboot调研线程模型比较简单文中没有展开分析