简介

在Linux中,Cron是计划任务管理系统,通过crontab命令使任务在约定的时间执行已经计划好的工作,例如定时备份系统数据、周期性清理缓存、定时重启服务等。

本文介绍的cron库是一个用于管理定时任务的库,就是用Go实现Linux中crontab命令的相似效果。

快速使用

文本代码使用 Go Modules

创建目录并初始化:

$ mkdir cron && cd cron
$ go mod init cron

安装cron,目前最新稳定版本为 v3:

$ go get -u github.com/robfig/cron/v3

在项目中导入包使用:

package main

import (
"fmt"
"time" "github.com/robfig/cron/v3"
) func main() {
c := cron.New() c.AddFunc("@every 1s", func() {
fmt.Println("tick every 1 second")
}) c.Start() // 阻塞,或者使用其他延迟时间函数、
select{}
}

使用非常简单,创建cron对象,这个对象用于管理定时任务。

调用cron对象的AddFunc()方法向管理器中添加定时任务。AddFunc()接受两个参数,参数 1 以字符串形式指定触发时间规则,参数 2 是一个无参的函数,每次触发时调用。@every 1s表示每秒触发一次,@every后加一个时间间隔,表示每隔多长时间触发一次。例如@every 1h表示每小时触发一次,@every 1m2s表示每隔 1 分 2 秒触发一次。time.ParseDuration()支持的格式都可以用在这里。

调用c.Start()启动定时循环。

注意一点,因为c.Start()启动一个新的 goroutine 做循环检测,我们在代码最后加了一行time.Sleep(time.Second * 5)防止主 goroutine 退出。

运行效果,每隔 1s 输出一行字符串:

$ go run main.go
tick every 1 second
tick every 1 second
tick every 1 second
tick every 1 second
tick every 1 second

时间格式

与Linux 中crontab命令相似,cron库支持用 5 个空格分隔的域来表示时间。

字段名 是否必须 允许的值 允许的特定字符
秒(Seconds) 0-59 * / , -
分(Minute) 0-59 * / , -
时(Hours) 0-23 * / , -
日(Day of month) 1-31 * / , - ?
月(Month) 1-12 或 JAN-DEC * / , -
星期(Day of week) 0-6 或 SUM-SAT * / , - ?

注意,月份和周历名称都是不区分大小写的,也就是说SUN/Sun/sun表示同样的含义(都是周日)。

特殊字符含义如下:

  • 星号():使用的域可以匹配任何值,例如将月份域(第 5 个)设置为*,表示每个月;
  • 斜线(/):用来指定范围的步长,例如如第1个字段(minutes) 值是 3-59/15,表示每小时的第3分钟开始执行一次,之后每隔 15 分钟执行一次(即 3、18、33、48 这些时间点执行),这里也可以表示为:3/15;
  • 逗号(,):用来列举一些离散的值和多个范围,例如将周历的域(第 6 个)设置为MON,WED,FRI表示周一、三和五;
  • 连字号(-):用来表示范围,例如将小时的域(第 3 个)设置为9-17表示上午 9 点到下午 17 点(包括 9 和 17);
  • 问号(?):只能用在月历和周历的域中,用来代替*,表示每月/周的任意一天。
  • (L,W,#): Go中没有L,W,#的用法

了解规则之后,我们可以定义任意时间:

每隔5秒执行一次:*/5 * * * * ?

每隔1分钟执行一次:0 */1 * * * ?

每天23点执行一次:0 0 23 * * ?

每天凌晨1点执行一次:0 0 1 * * ?

每月1号凌晨1点执行一次:0 0 1 1 * ?

在26分、29分、33分执行一次:0 26,29,33 * * * ?

每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ?

记熟了这几个域的顺序,再多练习几次很容易就能掌握格式。熟悉规则了之后,就能熟练使用crontab命令了。

func main() {
c := cron.New() c.AddFunc("30 * * * *", func() {
fmt.Println("Every hour on the half hour")
}) c.AddFunc("30 3-6,20-23 * * *", func() {
fmt.Println("On the half hour of 3-6am, 8-11pm")
}) c.AddFunc("0 0 1 1 *", func() {
fmt.Println("Jun 1 every year")
}) c.Start() for {
time.Sleep(time.Second)
}
}

预定义时间规则

为了方便使用,cron预定义了一些时间规则:

  • @yearly:也可以写作@annually,表示每年第一天的 0 点。等价于0 0 1 1 *;
  • @monthly:表示每月第一天的 0 点。等价于0 0 1 * *;
  • @weekly:表示每周第一天的 0 点,注意第一天为周日,即周六结束,周日开始的那个 0 点。等价于0 0 * * 0;
  • @daily:也可以写作@midnight,表示每天 0 点。等价于0 0 * * *;
  • @hourly:表示每小时的开始。等价于0 * * * *。

例如:

func main() {
c := cron.New() c.AddFunc("@hourly", func() {
fmt.Println("Every hour")
}) c.AddFunc("@daily", func() {
fmt.Println("Every day on midnight")
}) c.AddFunc("@weekly", func() {
fmt.Println("Every week")
}) c.Start() for {
time.Sleep(time.Second)
}
}

上面代码只是演示用法,实际运行可能要等待非常长的时间才能有输出。

注意:这样使用一个 cron.New() 的定时任务,执行的每个方法是顺序执行的,也就是说并不是同一时刻开始执行

固定时间间隔

cron支持固定时间间隔,格式为:

@every <duration>

含义为每隔duration触发一次。<duration>会调用time.ParseDuration()函数解析,所以ParseDuration支持的格式都可以。例如1h30m10s

时区

默认情况下,所有时间都是基于当前时区的。当然我们也可以指定时区,有 2 两种方式:

  • 在时间字符串前面添加一个CRON_TZ= + 具体时区,具体时区的格式在之前carbon的文章中有详细介绍。东京时区为Asia/Tokyo,纽约时区为America/New_York
  • 创建cron对象时增加一个时区选项cron.WithLocation(location)locationtime.LoadLocation(zone)加载的时区对象,zone为具体的时区格式。或者调用已创建好的cron对象的SetLocation()方法设置时区。

示例:

func main() {
nyc, _ := time.LoadLocation("America/New_York")
c := cron.New(cron.WithLocation(nyc))
c.AddFunc("0 6 * * ?", func() {
fmt.Println("Every 6 o'clock at New York")
}) c.AddFunc("CRON_TZ=Asia/Tokyo 0 6 * * ?", func() {
fmt.Println("Every 6 o'clock at Tokyo")
}) c.Start() for {
time.Sleep(time.Second)
}
}

巨人的肩膀

Go 每日一库之 cron

Go 每日一库之定时任务库:cron

Go -- cron定时任务的用法

go 定时任务库 cron的更多相关文章

  1. 摆脱定时任务的cron表达式的困扰

    一.背景 最近因为需要,需要适用Spring的task定时任务进行跑定时任务,以前也接触过,但是因为懒没有好好地理解@Scheduled的cron表达式,这次便对它做了一个全方位的了解和任务,记录下来 ...

  2. Go 的定时任务模块 Cron 使用

    前言 新项目是Golang作为开发语言, 遇到了些新的坑, 也学到了新的知识, 收获颇丰 本章介绍在Go中使用Cron定时任务模块来实现逻辑 正文 在项目中, 我们往往需要定时执行一些逻辑, 举个例子 ...

  3. Quartz.net 定时任务之Cron表达式

    一.cron表达式简单介绍和下载 1.在上一篇博客"Quartz.net 定时任务之简单任务"中,我简单介绍了quartz的使用,而这篇博客我将介绍cron的具体使用(不足之处望大 ...

  4. @Scheduled执行定时任务与cron表达式

    1 配置文件形式执行定时任务 1 1.X 版本与spring结合使用实例 1.1 常用maven管理 pom.xml文件 <project xmlns="http://maven.ap ...

  5. Linux /etc/cron.d作用(转自 定时任务crontab cron.d)

    原文链接:http://huangfuligang.blog.51cto.com/9181639/1608549 一.cron.d增加定时任务 当我们要增加全局性的计划任务时,一种方式是直接修改/et ...

  6. 【Linux常用工具】02. 创建启动定时任务工具cron

    一. cron 1. cron是一个守护程序,它提供定时器的功能,让用户在特定的时间得以执行默认的指令或程序.只要用户会编辑定时器的设置文件,就可以使用定时器的功能. 定时器文件格式: 2. cron ...

  7. spring 定时任务 scheduled Cron表达式

    转载:https://blog.csdn.net/u011789653/article/details/51153536 可以借鉴:https://www.cnblogs.com/softidea/p ...

  8. 使用cron命令配置定时任务(cron jobs)

    原文 http://www.cnblogs.com/end/archive/2012/02/21/2361741.html 开机就启动cron进程的设置命令:chkconfig --add crond ...

  9. 定时任务 Linux cron job 初步使用

     查看定时任务的命令为:crontab -l   编辑定时任务的命令为:crontab -e   (编辑后立即生效 若注释可在行首加#  同vi)         定时任务说明       每一行为一 ...

  10. Spring之Quartz定时任务和Cron表达式详解

    1.定时业务逻辑类 public class ExpireJobTask { /** Logger */ private static final Logger logger = LoggerFact ...

随机推荐

  1. Qt音视频开发21-通用硬解码

    一.前言 硬件解码是图形芯片厂家提出的用GPU资源解码视频流的方案,与之相对的是软解,也就是传统的用CPU承担解码工作的方案:优点是效率高,功耗低.热功耗低,缺点是缺乏有力的支持(包括滤镜.字幕等), ...

  2. [转]boost使用之编译库及遇到的问题

    最近因为在学习网络编程相关的东西,准备学习一下boost,毕竟原生的网络编程太麻烦.看了一下其实windows下想使用起来很简单,就是下载库,然后运行脚本,然后运行exe库就出来.在把头文件和库的目录 ...

  3. 阿里IM技术分享(五):闲鱼亿级IM消息系统的及时性优化实践

    本文由阿里闲鱼技术团队有攸分享,原题"向消息延迟说bybye:闲鱼消息及时到达方案",有修订和改动,感谢作者的分享. 1.引言 IM消息作为闲鱼用户重要的交易咨询工具,核心目标有两 ...

  4. 深入解析 Spring AI 系列:剖析OpenAI接口接入组件

    今天我们将继续探讨如何在Spring AI中接入大语言模型,以OpenAI为例,详细分析其接入过程.我们将逐步探讨OpenAI是如何与Spring AI系统对接的,具体包括如何配置接口.如何封装接口参 ...

  5. Solution Set -「LOCAL」冲刺省选 Round X

    \(\mathscr{Summary}\)   时间利用效率?   同学,你的效率呢?   我真不知道中途几个小时干了啥,我也不知道我实在划水.神游还是真的在自闭想题.   虽然真实考场肾上腺素不会允 ...

  6. WPF 获取拖拽网页图片链接

    在浏览器里拖拽一个元素,我只获取图片链接 private void Grid_PreviewDragOver(object sender, DragEventArgs e) { e.Effects = ...

  7. 一点区块链资料-copy

    1. 场景描述 (1)今天找资料,无意中看到15年底-16年初弄的关于区块链的资料,当时写了个交流汇报区块链的ppt,感觉挺好的,共享下,希望能帮助朋友们理解区块链. (2)背景:15年底,老板从朋友 ...

  8. 计算今天是该年的第几天(c语言实现)

    遇到一个有意思的编程题,使用C语言实现计算今天是该年的第几天. 实现代码如下: #include<stdio.h> int d[12]={31,28,31,30,31,30,31,31,3 ...

  9. langchain-agent

    Agent 参考:LangChain 实战:Agent思维 大模型是被训练出来的,知识是有时间限制的,所以当进行问答时,可以结合本地知识库和调用搜索或在线API来增强自身能力,这些不属于大模型的内部数 ...

  10. LPN问题

    郁昱老师的某次讲座,记录一下! LWE和LPN: 1.LWE是模p的:噪音取自离散高斯分布 2.LPN是模2的:噪音取自伯努利分布 3.LPN很难构造同态加密方案 4.都可以分为判定型和搜索型