CRON表达式,让你轻松掌握定时任务设置!

发布时间 2023-12-13 16:17:23作者: 何童鞋

一、什么是CRON表达式

1.1 介绍CRON表达式概念

CRON表达式是一种时间表达式,用于指定定期执行任务的时间规则。它可以被用来执行非常基本的任务,例如从数据库备份到每天自动发送电子邮件。

1.2 CRON表达式的由来

CRON表达式最初是在UNIX和类似的操作系统中创建的。名称“CRON”代表“命令调度程序(Command Rund On)”。CRON表达式是用来控制命令何时运行的方式。通过它们,用户可以在操作系统下创建定期运行的命令或任务。这些任务可以包括备份、更新索引等。

1.3 CRON表达式在计算机操作系统和应用程序中的应用

CRON表达式广泛应用于计算机操作系统和应用程序中。在操作系统中,CRON表达式可以控制定期执行系统维护任务,如清理日志、备份数据等。在应用程序中,CRON表达式可以被用于定时执行一些特定的业务逻辑,比如定时发送邮件、生成报告、数据分析等。

领域应用操作系统/应用程序
操作系统 定期备份、定时清理 Linux、Unix、Windows等操作系统
应用程序 定时触发后台处理、邮件发送等 Java中的quartz框架、Spring框架、Python中的APScheduler库等

二、CRON表达式语法

2.1 CRON表达式格式

CRON表达式的格式是一个字符串,共有六个字段,分别代表秒、分、小时、日期、月份、星期。每个字段都可以使用通配符、范围、逗号分隔的列表以及"/"取模符号等来表示时间规则。CRON表达式包含了六个部分,分别表示任务执行的时间点。这些部分被空格分隔开,依次表示:

*    *    *    *    *    *
┬    ┬    ┬    ┬    ┬    ┬
│    │    │    │    │    │
│    │    │    │    │    └── 星期(0 - 6,0表示星期日)
│    │    │    │    └───── 月份(1 - 12)
│    │    │    └────────── 日(1 - 31)
│    │    └─────────────── 小时(0 - 23)
│    └──────────────────── 分钟(0 - 59)
└───────────────────────── 秒(0 - 59)

2.2 CRON表达式字符含义

CRON表达式中的每个部分都有其特定的字符含义,具体如下:

是否必需取值范围特殊字符
秒 Seconds [0, 59] * , - /
分钟 Minutes [0, 59] * , - /
小时 Hours [0, 23] * , - /
日期 DayofMonth [1, 31] * , - / ? L W
月份 Month [1, 12]或[JAN, DEC] * , - /
星期 DayofWeek [1, 7]或[MON, SUN]。若使用[1, 7]表达方式,1代表星期一,7代表星期日。 * , - / ? L #
年 Year 1970+ - * /

2.3 支持的特殊字符

CRON表达式还支持些特殊字符,包括:

  • *:表示匹配该域的任意值。假如在Minutes域使用*, 即表示每分钟都会触发事件。
  • ?:只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值,但实际不会。因为DayofMonth和DayofWeek会相互影响。例如想在每月的20日触发调度,不管20日到底是星期几,则只能使用如下写法: 13 13 15 20 * ?, 其中最后一位只能用?,而不能使用,如果使用表示不管星期几都会触发,实际上并不是这样。
  • -:表示范围。例如在Minutes域使用5-20,表示从5分到20分钟每分钟触发一次
  • /:表示起始时间开始触发,然后每隔固定时间触发一次。例如在Minutes域使用5/20,则意味着5分钟触发一次,而25,45等分别触发一次.
  • ,:表示列出枚举值。例如:在Minutes域使用5,20,则意味着在5和20分每分钟触发一次。
  • L:表示最后,只能出现在DayofWeek和DayofMonth域。如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。
  • W:表示有效工作日(周一到周五),只能出现在DayofMonth域,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份 。
  • LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。
  • #:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。

2.4 示例

以下是常见的CRON表达式示例:

按照秒维度:

序号CRON表达式含义
1 0/10 * * * * * 每隔10秒执行一次任务
2 */30 * * * * * 每隔30秒执行一次任务
3 0 * * * * * 每分钟的0秒执行任务
4 15 * * * * * 每分钟的15秒执行任务
5 30 * * * * * 每分钟的30秒执行任务

按照分钟维度:

序号CRON表达式含义
1 0 * * * * ? 每小时的0分0秒执行任务
2 0 */5 * * * * 每隔5分钟执行一次任务
3 0 */10 * * * * 每隔10分钟执行一次任务
4 0 */15 * * * * 每隔15分钟执行一次任务
5 0 5 0 * * * 每天凌晨0点5分0秒执行一次任务

按照小时维度:

序号CRON表达式含义
1 0 0 * * * * 每小时执行任务
2 0 0 */2 * * * 每两个小时执行一次任务
3 0 30 8-18/2 * * * 每天早上8点到晚上6点之间,每两个小时的30分0秒执行任务
4 0 0 */6 * * * 每六个小时执行一次任务
5 0 0 0 */3 * * 每三天凌晨0点0分0秒执行任务

按照天维度:

序号CRON表达式含义
1 0 0 0 * * * 每天凌晨0点0分0秒执行任务
2 0 0 12 * * ? 每天中午12点0分0秒执行任务
3 0 0 8-18 * * * 每天早上8点到晚上6点之间执行任务
4 0 0 0,12 * * ? 每天的0点和12点0分0秒执行任务
5 0 0 1 * * ? 每月的第一天凌晨0点执行任务

按照星期维度:

序号CRON表达式含义
1 0 0 0 ? * SUN 每周日凌晨0点0分0秒执行任务
2 0 0 0 ? * MON 每周一凌晨0点0分0秒执行任务
3 0 0 0 ? * FRI 每周五凌晨0点0分0秒执行任务
4 0 0 0 ? * SAT 每周六凌晨0点0分0秒执行任务
5 0 0 0 ? * TUE 每周二凌晨0点0分0秒执行任务

按照月维度:

序号CRON表达式含义
1 0 0 0 1 * ? 每个月的第一天凌晨0点执行任务
2 0 0 0 L * ? 每个月的最后一天凌晨0点执行任务
3 0 0 0 1,15 * ? 每个月的1日和15日凌晨0点执行任务
4 0 0 0 1-7 * ? 每个月的前7天凌晨0点执行任务
5 0 0 0 2-4 * ? 每个月的第二到第四天凌晨0点执行任务

三、CRON表达式使用场景

3.1 定时触发任务

最常见的CRON表达式使用场景是定时触发任务。可以通过CRON表达式设置任务执行的时间规则,然后在这个时间点自动触发任务执行。 例如:

  1. 数据备份
  2. 自动清理日志
  3. 定时爬取网站数据
  4. 邮件定时发送
  5. 定时任务调度
  6. 后台任务运行等

3.2 执行周期性任务

除了定时触发任务,还可以使用CRON表达式执行周期性任务。通过CRON表达式设置任务执行的时间间隔、执行次数等规则,让定时任务自动执行一系列的操作。例如,您可以设置一个每天晚上10点执行的任务,或者设置一个每小时执行一次的任务。

以下是一些常见的使用场景,说明了如何使用CRON表达式执行周期性任务:

  1. 数据备份:可以设置一个每天凌晨3点执行一次的任务,将数据库中的数据备份到指定的位置。
  2. 自动清理日志:可以设置一个每隔7天执行一次的任务,删除一周前的日志文件,以释放磁盘空间。
  3. 定时爬取网站数据:可以设置一个每隔1小时执行一次的任务,爬取指定网站的数据并保存到数据库中。
  4. 邮件定时发送:可以设置一个每天下午4点执行一次的任务,发送当日的报告和提醒邮件。
  5. 定时任务调度:可以设置不同的CRON表达式,按照需求执行指定的任务,例如每周五下午2点执行一次数据汇总任务等。
  6. 后台任务运行:可以设置一个每隔10分钟执行一次的任务,检查后台任务的执行状态,并根据需要进行相应的处理。

3.3 监控应用程序运行状态

CRON表达式也可以被用来监控应用程序的运行状态。通过合理的CRON表达式设置,可以在程序异常时及时通知管理员并采取措施,保证程序正常运行。

以下是一些常见的使用场景,说明了如何使用CRON表达式监控应用程序的运行状态:

  1. 监控Web应用程序:可以设置一个每隔30秒执行一次的任务,检查Web应用程序的响应时间和页面状态。如果响应时间超过阈值或者页面出现异常,则发送邮件通知管理员。
  2. 监控数据库连接池:可以设置一个每隔10分钟执行一次的任务,检查数据库连接池中连接的数量和使用情况。如果连接数量低于阈值或者有连接长时间没有释放,则发送邮件通知管理员。
  3. 监控消息队列:可以设置一个每隔5分钟执行一次的任务,检查消息队列中消息的数量和处理速度。如果消息数量过多或者处理速度过慢,则发送邮件通知管理员。
  4. 监控文件系统:可以设置一个每天凌晨1点执行一次的任务,检查文件系统的空间占用率和文件数量。如果空间不足或者文件数量过大,则发送邮件通知管理员。

3.4 其他应用场景

除了上述场景之外,CRON表达式还可以被用于其它很多场景,包括编写批处理文件、协调分布式系统中的任务执行、编写自动化测试脚本等。

四、CRON表达式实现原理

4.1 手动解析CRON表达式

手动解析CRON表达式需要了解以下几个方面:

  1. CRON表达式的语法:CRON表达式包含6个字段,每个字段使用空格分隔。每个字段的取值范围为特定的数字或符号,例如*表示任意值,/表示步长等。
  2. CRON表达式中的匹配规则:每个字段的取值都可以是一个具体的数值、一系列数值、范围和间隔值、以及通配符、L、W等符号。了解这些规则有助于快速理解和编写CRON表达式。
  3. 时间的时间戳转换:CRON表达式中的时间信息需要先转换为时间戳格式,才能进行比较和计算。时间戳是指从某个时间点开始计算的秒数或毫秒数,通常使用UTC标准时区来计算。
  4. CRON表达式的计算:将每个字段的取值代入CRON表达式中进行计算,得出下次执行任务的时间。

手动解析CRON表达式需要一定的经验和技巧,而且容易出错。因此,在实际应用中,通常采用成熟的CRON库或者在线工具来自动解析和生成CRON表达式。

例如下面几个方便的:

Cron - 在线Cron表达式生成器 (ciding.cc) 在线Cron表达式生成器 (qqe2.com) quartz/Cron/Crontab表达式在线校验工具-BeJSON.com 在线cron表达式生成器,cron表达式解析 (zhaotool.com)

4.2 转化为时间调度程序调度

另外一种实现方式是将CRON表达式转化为时间调度程序进行调度。例如,Java语言中的Quartz框架就是一种时间调度程序,可以用来执行CRON表达式指定的任务。Quartz框架提供了许多功能强大的特性,比如任务调度、集群支持、监控和管理等。除了Java语言中的Quartz框架,其他编程语言中也有类似的时间调度程序,如Python中的schedule库、Node.js中的node-schedule模块等。

使用时间调度程序进行调度可以方便地实现任务的自动化运行,并且支持更灵活的任务调度策略和管理方式。例如,在Quartz框架中,用户可以设置任务的执行时间、执行频率、执行优先级、执行参数等,同时支持多种任务调度器和触发器类型,满足不同场景的需求。

五、CRON表达式常见问题及应用实例

5.1 CRON表达式最小粒度

CRON表达式最小粒度是秒级别。在某些特殊的应用场景下,可能需要更高精度的调度,如使用毫秒级调度,但这需要对时间调度库或框架进行适当修改才能实现。

5.2 同时执行多个任务

在CRON表达式中无法直接指定同时执行多个任务,因为每个CRON表达式只能对应一个调度任务。不过,可以通过一些方式来实现同时执行多个任务的效果。

其中一种常见的做法是使用调度器框架,如Quartz,将多个任务添加到同一个调度器中,并设置每个任务的CRON表达式。调度器会按照CRON表达式来触发每个任务,从而实现同时执行多个任务的效果。需要特别注意的是,在同时运行的多个任务之间要合理安排优先级和资源占用,避免出现互相影响和冲突的情况。

另外,如果多个任务之间没有强依赖关系,可以将它们分别制定不同的CRON表达式并单独调度,从而实现任务的并行执行。这样可以提高系统的吞吐量和执行效率,但也可能会增加系统负担和复杂度,需要根据具体情况进行权衡和选择。

5.3 CRON表达式配置错误导致问题

由于CRON表达式格式比较严格,可能会出现由于表达式格式配置错误而导致的问题。在实际应用中,可以通过日志信息、监控等手段定位并解决这些问题。

5.4 常见的应用实例和案例

CRON表达式被广泛应用于各种场景,如Web项目中定时刷新缓存、备份数据等。另外一些案例包括定时发送报表、定时监控服务器状态、早期的Unix系统清理日志等。

六、CRON表达式的优缺点

6.1 CRON表达式的优点

  • CRON表达式简单易学,容易上手。
  • 能够满足大部分时间规则设置需求,支持各种复杂的时间规则设置。
  • 经过验证,CRON表达式执行效率较高,可靠性较高。

6.2 CRON表达式的缺点

  • CRON表达式格式比较严格,需要开发人员一定的技术储备和经验。
  • 部分时间规则设置可能会导致运行时间不稳定。
  • 对于高并发任务或更小的时间粒度,CRON表达式的效率不如其他框架机制。

6.3 与其他定时调度框架的比较

相对于其他定时调度框架,CRON表达式的优点在于语法明确,通俗易懂,支持复杂的时间规则设置,并且经过广泛的使用和验证。缺点在于需要开发人员花费较多的时间和精力学习其使用,同时在某些场景下效率可能不够高。在使用CRON表达式时需要根据具体的需求和场景综合考虑。

七、CRON表达式的进一步扩展和应用

7.1 Quartz定时调度框架中的CRON表达式

Quartz是一个Java语言写的开源日程安排库,它可以用来调度任务。Quartz支持CRON表达式,并且提供了丰富的功能,如任务调度、触发器、集群支持、监控和管理等。Quartz定时调度框架中的CRON表达式是一种用于指定时间调度的字符串格式,可以精确到秒级别。它由6个或7个字段组成,每个字段表示不同的时间维度和调度规则。

在Quartz中,一个CRON表达式的格式如下:

<second> <minute> <hour> <day-of-month> <month> <day-of-week> <year>

其中<second>(秒)、<minute>(分)、<hour>(小时)、<day-of-month>(一个月中的第几天)、<month>(月份)和<day-of-week>(一个星期中的第几天)是必需的字段。<year>是可选的字段,用于指定年份。

每个字段都有自己的取值范围和取值方式。例如,<second>字段的取值范围为0-59,可以使用星号(*)代表所有取值,也可以使用多个逗号分隔的值表示指定的取值,还可以使用连字符(-)代表一个范围内的取值。其他的字段也类似。

Quartz支持各种复杂的CRON表达式,可以表示各种不同的时间调度需求,例如分钟级、小时级、日历级别或者在某个特定时间点执行任务等。需要注意的是,复杂度越高的CRON表达式对于开发人员的编写和维护难度也越高,因此在实际应用中需要根据具体情况进行权衡和选择。

7.2 CRON及其它定时任务的组合使用

CRON和其他定时任务可以组合使用,以满足各种不同的时间调度需求。下面是一些常见的组合方式:

  1. CRON表达式和延迟任务:可以使用CRON表达式来触发周期性任务,而使用延迟任务来触发一次性任务,并根据需要在任务之间添加适当的延迟。
  2. CRON表达式和触发器:可以使用CRON表达式来触发周期性任务,而使用触发器来在任务完成后触发其他操作,例如发送通知或者更改任务状态等。
  3. CRON表达式和消息队列:可以使用CRON表达式来触发周期性任务,并将任务结果放入消息队列中,以供其他进程或服务进行处理。
  4. CRON表达式和定时切片:可以使用CRON表达式来触发周期性任务,并使用定时切片来限制任务的执行时间和资源占用。
  5. CRON表达式和任务流:可以使用CRON表达式来触发周期性任务,并将多个任务组合成一个任务流,在任务流中依次执行。
  6. CRON表达式和分布式任务调度器:可以使用CRON表达式来触发周期性任务,并使用分布式任务调度器来实现任务的分布式并行执行。

7.3 Web应用程序中CRON表达式的使用

在Web应用程序中,CRON表达式通常用于计划和执行后台任务,例如数据备份、定期清理、消息推送等。下面是一些Web应用程序中CRON表达式的使用场景:

  1. 数据备份:可以使用CRON表达式来指定数据备份的时间和频率,从而保证数据的安全性和完整性。
  2. 定期清理:可以使用CRON表达式来定时清理无用的数据和文件,以减少数据库和磁盘空间的占用。
  3. 消息推送:可以使用CRON表达式来定时发送消息到用户设备上,例如推送新闻、天气预报等。
  4. 统计分析:可以使用CRON表达式来定时执行统计任务,例如计算网站访问率、用户活跃度等,并将结果显示在后台或者前端页面上。
  5. 定期备份日志:可以使用CRON表达式来定时备份运行日志,以便在系统出现问题时进行排查和分析。

八、总结及展望

8.1 总结CRON表达式的应用

CRON表达式是一种用于指定时间调度的字符串格式,它可以实现定时任务的自动化执行,比如:

  1. 后台任务:CRON表达式可以用于定时执行后台任务,例如备份数据库、更新缓存、清理无用文件等。
  2. 消息推送:应用程序可以使用CRON表达式来实现消息推送,在固定的时间或者周期性地向用户推送最新的消息或通知。
  3. 定时任务:CRON表达式可以用于定时任务,包括批处理作业、数据处理任务、统计分析任务等。
  4. 网络爬虫:CRON表达式可以用于控制网络爬虫定时采集数据,并在指定时间或者周期性地进行更新。

总的来说,CRON表达式主要应用于需要定期或者定时执行的任务,使得开发人员可以更加便捷、高效地管理和维护这些任务,并且可以减少手动干预的操作,降低了系统维护成本。同时,使用CRON表达式还能够提高系统的安全性和稳定性,避免因为人为疏漏而导致的数据丢失和系统崩溃。