带你深入了解 cron 任务调度

当涉及自动化任务和定时执行时,CRON 是一个强大的工具。CRON 允许你在预定的时间间隔内自动运行脚本、命令或任务,无需手动干预。在本文中,我们将深入探讨基于定时 CRON 的自动化任务,介绍如何设置和管理定时任务,以及一些常见的用例。

什么是 cron

CRON 是一个在类 Unix 操作系统中用于自动化任务调度的工具。它使用一种简单的语法来定义任务运行的时间间隔,可以精确到分钟、小时、日期等。通过使用 CRON,你可以编排和管理重复性的任务,从而减少手动操作的需求。 简单的来说 cron 作用是用来描述任务执行执行时机

CRON 表达式

CRON 表达式是一个包含五个或六个字段的字符串,用于定义任务的执行时间。这些字段分别表示分钟、小时、日期、月份和星期几。

Cron表达式是一个字符串,通常字符串由6个域或者7个域构成,每一个域代表一个含义

语法格式:

  • 7 个域: 秒、分、时 、月天、月、周天、年
  • 6 个域:秒、分、时、月天、月、周天
  • 5 个域: 分、时、月天、月、周天

CRON 应用场景

  1. 数据备份: 每天定时备份重要数据到远程服务器。
  2. 定时清理: 在特定时间清理临时文件或日志。
  3. 监控和报警: 定期检查系统健康状况,发现问题时发送报警通知。
  4. 更新软件: 每周自动更新操作系统和应用程序。
  5. 定时发布内容: 在特定时间发布文章、新闻或社交媒体帖子。
  6. 定时任务执行: 在低峰期运行资源密集型任务,以避免对系统性能造成影响。

CRON 表达式域的取值

允许值 允许特殊字符
0-59 ,-* /
0-59 ,-* /
0-23 ,-* /
1-31 ,-* / ? L W
1-12 ,-* /
1-7 ,-* / ? L #
1970-2099 ,-* /

Cron 字符描述

  • * : 代表所有可能的值,
  • - : 代表指定范围
  • , : 代表列举出枚举值,比如在分钟子表达式中,"5,20" 表示在第 5 分钟和第 20 分钟出发
  • / : 表示指定增量,比如在分钟子表达式中,"0/15" 表示从第 0 分钟开始,每 15 分钟执行一次,"3/20" 表示从第 3 分钟开始,每 20 分钟执行一次
  • :主要用于月天或者周天中,指"没有具体的值",当两个子表达式其中一个被指定了值以后,为了避免冲突,需要将另外一个值设置为 ?。比如想在每月 20 日出发调度,不管 20 号是星期几,只能用如下的写法:0 0 0 20 * ? ,其中最后一位只能用 ? ,而不能用 *
  • L : 主要用于月天或者周天中,在周天中, L 表示一个星期的最后一天,也就是 7 或者 SAT,在月天中,L 表示一个月的最后一天,比如 1 月 31 号,或者 2 月 28 号,或者 3 月 30 号。如果 L 前有具体的内容,那么就有其他含义,比如 6L 表示这个月的倒数第六天
  • # :只能用在周天中

CRON 示例

bash 复制代码
* * * * ? # 每分钟触发一次  
0 0 * * * ? # 每天每1小时触发一次  
0 0 10 * * ? # 每天10点触发一次  
0 * 14 * * ? # 在每天下午2点到下午2:59期间的每1分钟触发  
0 30 9 1 * ? # 每月1号上午9点半  
0 15 10 15 * ? # 每月15日上午10:15触发  
*/5 * * * * ? # 每隔5秒执行一次  
*/1 * * * *  # 每隔 1 分钟执行一次
0 */1 * * * ? # 每隔1分钟执行一次 
30 3,12 * * * # 每天凌晨三点半和十二点半执行
0 0 5-15 * * ? # 每天5-15点整点执行
0 0/3 * * * ? # 每三分钟执行一次
30 */6 * * * # 每六个半小时执行一次
0 0-5 14 * * ? # 在每天下午2点到下午2:05期间的每1分钟触发  
0 0/5 14 * * ? # 在每天下午2点到下午2:55期间的每5分钟触发  
0 0/5 14,18 * * ? # 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发  
0 0/30 9-17 * * ? # 朝九晚五工作时间内每半小时  
30 8-18/2 * * * # 在每天的早上 8 点到下午 6 点之间间隔两个半小时执行一次
30 21 * * * # 在每天的晚上九点半执行一次
45 4 1,10,22 * * # 在每个月的第一、十、二十二天的凌晨四点四十五执行
10 1 * * 6,0 # 每周六日凌晨一点十分执行
0,30 18-23 * * * # 在每天的下午六点到十一点之间零点和半点执行
* 23,00-07/1 * * * # 每天的晚上二十三点和半夜零点和早上七点每隔一小时每分钟执行
0 0 10,14,16 * * ? # 每天上午10点,下午2点,4点  
0 0 12 ? * WED # 表示每个星期三中午12点  
0 0 17 ? * TUES,THUR,SAT # 每周二、四、六下午五点  
0 10,44 14 ? 3 WED # 每年三月的星期三的下午2:10和2:44触发  
0 15 10 ? * MON-FRI # 周一至周五的上午10:15触发  
0 0 23 L * ? # 每月最后一天23点执行一次  
0 15 10 L * ? # 每月最后一日的上午10:15触发  
0 15 10 ? * 6L # 每月的最后一个星期五上午10:15触发  
0 15 10 * * ? 2005 # 2005年的每天上午10:15触发  
0 15 10 ? * 6L 2002-2005 # 2002年至2005年的每月的最后一个星期五上午10:15触发  
0 15 10 ? * 6#3 # 每月的第三个星期五上午10:15触发

Cron 在线测试工具

www.jsons.cn/quartzcheck...

任务调度原理

说到任务调度,我们需要了解一个算法,时间轮算法;时间轮算法,是一种实现定时器的巧妙算法,任务调度等各种框架中都有用到。

时间轮算法的设计其实就是来自于时钟;

时间轮算法实例

圆心位置表示的是当前的时间,随着时间推移, 圆心处的时间也会不断跳动。在计算机中时间轮的底层

就是一个环形链表,或者环形数组,每个元素都存放一个链表,链表中封装了很多定时任务;

时间轮执行任务流程

我只需要把任务放到它需要被执行的时刻,然后等着时针转到这个时刻时,取出该时刻放置的任务,执

行就可以了。对于时间轮算法,主要的功能有4个 。1. 加入任务 2. 执行任务 3. 删除任务 4. 沿着时间刻

度前进;

对于这4个功能来说最复杂的功能就是加入任务。下面我们重点来讲解加入任务;

eg:初始的时候, 时间轮的指针定格在0。此时添加一个延迟时间为2s的任务, 那么这个任务将会插入到第

二个时间格中;当时间轮的指针指到第二个时间格就会触发任务;

如果这个时候又插入一个延时时间为8s的任务进来, 这个任务的触发时间就是在当前时间2s的基础上加

8s, 也就是10s, 那么这个任务将会插入到10s的时间格中。

"动态"时间轮

那么如果在当前时间是2s的时候, 插入一个延时时间为19s的任务时,这个任务的触发时间就是在当前时

间 2s的基础上加19s, 也就是21s,在我们的时间轮上是没有21s的时间格的;这个任务将会插入到过期

时间为1s的 时间格中。为什么呢?

时间轮升级

如果在当前时间是2s的时候, 插入一个延时时间为22s的任务, 这个任务的触发时间就是在2s的基础上加

22s,也就是24s。

显然当前时间轮是无法找到过期时间格为24秒的时间格,因为当前过期时间最大的时间格才到21s。而

且我们也没办法像前面那样再复用时间格,其他的时间格都还没过期呢。当前时间轮无法承载这个定时

任务,那么应该怎么办呢?

层级时间轮

第二层时间轮也是由20个时间格组成, 每个时间格的跨度是20s。图中展示了每个时间格对应的过期时间

范围, 我们可以清晰地看到, 第二层时间轮的第0个时间格的过期时间范围是 [0,19]。也就是说, 第二层时

间轮的一个时间格就可以表示第一层时间轮的所有(20个)时间格;

第一级的时间轮走一圈,第二级的时间轮走一格。

在当前时间是2s的时候, 插入一个延时时间为22s的任务,该任务触发时间时间为24s。当第一层时间轮

容纳不下时,进入第二层时间轮,并插入到过期时间为[20,39]的时间格中。

"动态"层级时间轮

当第一层时间轮的指针定格在1s时,超时时间0s的时间格就过期了。而这个时候,第二层时间轮第0个

时间格的时间范围就从[0,19]分为了过期的[0],和未过期的[1,19]。而过期的[0]就会被新的过期时间

400\]复用。 ## 总结 CRON 是一个强大的工具,可以帮助你自动化重复性任务,提高效率并减少手动操作的需求。通过设置和管理定时 CRON 任务,你可以轻松实现各种自动化场景,从数据备份到系统监控,都可以通过 CRON 实现。务必仔细考虑任务的需求和影响,合理配置 CRON 表达式,确保任务按计划运行。

相关推荐
神奇小汤圆4 小时前
告别手写HTTP请求!Spring Feign 调用原理深度拆解:从源码到实战,一篇搞懂
后端
YuTaoShao4 小时前
【LeetCode 每日一题】1653. 使字符串平衡的最少删除次数——(解法三)DP 空间优化
算法·leetcode·职场和发展
茉莉玫瑰花茶4 小时前
C++ 17 详细特性解析(5)
开发语言·c++·算法
布列瑟农的星空4 小时前
前端都能看懂的Rust入门教程(三)——控制流语句
前端·后端·rust
wVelpro4 小时前
如何在Pycharm 2025.3 版本实现虚拟环境“Make available to all projects”
linux·ide·pycharm
汤姆yu4 小时前
基于springboot的尿毒症健康管理系统
java·spring boot·后端
暮色妖娆丶4 小时前
Spring 源码分析 单例 Bean 的创建过程
spring boot·后端·spring
野犬寒鸦4 小时前
从零起步学习JVM || 第一章:类加载器与双亲委派机制模型详解
java·jvm·数据库·后端·学习
cpp_25014 小时前
P10570 [JRKSJ R8] 网球
数据结构·c++·算法·题解
cpp_25014 小时前
P8377 [PFOI Round1] 暴龙的火锅
数据结构·c++·算法·题解·洛谷