标签:形式 article 逗号 int run init com none location
在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秒执行一次:*/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预定义了一些时间规则:
例如:
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
支持固定时间间隔,格式为:
@every <duration>
含义为每隔duration
触发一次。<duration>
会调用time.ParseDuration()
函数解析,所以ParseDuration
支持的格式都可以。例如1h30m10s
。
默认情况下,所有时间都是基于当前时区的。当然我们也可以指定时区,有 2 两种方式:
CRON_TZ=
+ 具体时区,具体时区的格式在之前carbon的文章中有详细介绍。东京时区为Asia/Tokyo
,纽约时区为America/New_York
;cron
对象时增加一个时区选项cron.WithLocation(location)
,location
为time.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定时任务的用法
标签:形式 article 逗号 int run init com none location
原文地址:https://www.cnblogs.com/niuben/p/14615806.html