背景
在现代软件开发中,计划任务是一种常见的需求。无论是定时发送邮件、定期清理缓存,还是执行数据同步,计划任务都能帮助我们自动化这些重复性工作。
最近有一个需求,用户想要自己设定定时时间,来动态的执行定时任务。 很离谱,原来每天晚上12点定时执行的几个数据同步、数据清理任务,想不通用户要这个功能干啥!!!
探索历程
原本的cron表达式,是直接写死到代码里的,显然不能动态的修改。
如果采用配置文件的方式,每次改动要重启项目,或者再写个定时任务,每秒读取文件内容,也不太合适。
如果引入分布式任务调度平台,比如xxl-job、power-job、snail-job,又觉得太复杂。
选择采用放到数据库的方式,实现过程中,发现并不是很顺利,写一篇文章记录一下这次的过程。
原本的实现
结果
图片
动态设置
配置类
修改入口
将 0/10 * * * * * 改为 0/5 * * * * *
结果
图片
可以看出来 修改的时间是 15:01 ,但是下次执行时间还是间隔了10秒,第二次之后的时间才是间隔5秒。 更新结果有一个周期的延迟。
在这种情况下,延迟还算可以接收,但是周期如果是一天、一周,那生效周期就太长了,需要一种即时生效的方法。
即时生效
实现方案是,以事件驱动,动态修改定时任务。
定义事件
构造调度任务程序
动态任务配置
修改接口,增加事件
结果
图片
可以看到,在收到修改任务的事件后,直接删除了原来的定时任务,创建了一个新的执行任务,即时生效,不需要等待一个执行周期就可立即执行。
小结
通过上述方法,我们可以在 Spring Boot 应用中实现动态计划任务,使得任务的执行更加灵活可控。
还实验了几种不同的方式,比如每秒轮询数据库、手动计算cron表达式 的执行时间。感觉就属这个事件驱动的方式最优雅。