带你深入了解 cron 任务调度

2023年 8月 13日 80.4k 0

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

什么是 cron

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

CRON 表达式

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

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

语法格式:

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

CRON 应用场景

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

    * * * * ? # 每分钟触发一次  
    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…

    任务调度原理

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

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

    时间轮算法实例

    圆心位置表示的是当前的时间,随着时间推移, 圆心处的时间也会不断跳动。在计算机中时间轮的底层
    就是一个环形链表,或者环形数组,每个元素都存放一个链表,链表中封装了很多定时任务;

    image-20200623165936145.png

    时间轮执行任务流程

    我只需要把任务放到它需要被执行的时刻,然后等着时针转到这个时刻时,取出该时刻放置的任务,执
    行就可以了。对于时间轮算法,主要的功能有4个 。1. 加入任务 2. 执行任务 3. 删除任务 4. 沿着时间刻
    度前进;

    对于这4个功能来说最复杂的功能就是加入任务。下面我们重点来讲解加入任务;
    eg:初始的时候, 时间轮的指针定格在0。此时添加一个延迟时间为2s的任务, 那么这个任务将会插入到第
    二个时间格中;当时间轮的指针指到第二个时间格就会触发任务;

    v2-598b34649422af1de1a720e95d37a9b3_b.gif

    如果这个时候又插入一个延时时间为8s的任务进来, 这个任务的触发时间就是在当前时间2s的基础上加
    8s, 也就是10s, 那么这个任务将会插入到10s的时间格中。

    v2-7923e92df0f0343871820371a37fac2a_b.gif

    "动态"时间轮

    那么如果在当前时间是2s的时候, 插入一个延时时间为19s的任务时,这个任务的触发时间就是在当前时
    间 2s的基础上加19s, 也就是21s,在我们的时间轮上是没有21s的时间格的;这个任务将会插入到过期
    时间为1s的 时间格中。为什么呢?

    v2-480d1f3a2ddea9a5ccbc87235accc5d0_b.gif

    时间轮升级

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

    v2-480d1f3a2ddea9a5ccbc87235accc5d0_b.gif

    显然当前时间轮是无法找到过期时间格为24秒的时间格,因为当前过期时间最大的时间格才到21s。而
    且我们也没办法像前面那样再复用时间格,其他的时间格都还没过期呢。当前时间轮无法承载这个定时
    任务,那么应该怎么办呢?

    层级时间轮

    image-20200623201851364.png

    第二层时间轮也是由20个时间格组成, 每个时间格的跨度是20s。图中展示了每个时间格对应的过期时间
    范围, 我们可以清晰地看到, 第二层时间轮的第0个时间格的过期时间范围是 [0,19]。也就是说, 第二层时
    间轮的一个时间格就可以表示第一层时间轮的所有(20个)时间格;

    v2-f649b5f166c55a3c6b340cdd670b5229_b.gif

    第一级的时间轮走一圈,第二级的时间轮走一格。
    在当前时间是2s的时候, 插入一个延时时间为22s的任务,该任务触发时间时间为24s。当第一层时间轮
    容纳不下时,进入第二层时间轮,并插入到过期时间为[20,39]的时间格中。

    "动态"层级时间轮

    v2-50c4f9f7bbc77c84a0a1da23d86c36cf_b.gif

    当第一层时间轮的指针定格在1s时,超时时间0s的时间格就过期了。而这个时候,第二层时间轮第0个
    时间格的时间范围就从[0,19]分为了过期的[0],和未过期的[1,19]。而过期的[0]就会被新的过期时间
    [400]复用。

    总结

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

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论