带你深入了解 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 表达式,确保任务按计划运行。

相关推荐
不光头强2 小时前
spring cloud知识总结
后端·spring·spring cloud
SPC的存折3 小时前
1、Redis数据库基础
linux·运维·服务器·数据库·redis·缓存
小疙瘩4 小时前
只是记录自己发布若依分离系统到linux过程中遇到的问题
linux·运维·服务器
GetcharZp5 小时前
告别 Python 依赖!用 LangChainGo 打造高性能大模型应用,Go 程序员必看!
后端
阿里加多5 小时前
第 4 章:Go 线程模型——GMP 深度解析
java·开发语言·后端·golang
小小李程序员5 小时前
Langchain4j工具调用获取不到ThreadLocal
java·后端·ai
IronMurphy5 小时前
【算法三十九】994. 腐烂的橘子
算法
我是伪码农5 小时前
外卖餐具智能推荐
linux·服务器·前端