0/参考网址
blog.csdn.net/qq_42887507…
1/前言
我们在项目开发中,常常会遇到定时任务的场景,比如定期执行某个函数,定期清理日志文件,定期备份数据等。
在go语言开发中,我们可以使用go语言内置的库包cron来实现定时任务。
Cron是Go中用于设置定时任务的一个库包,需要注意的是,Cron库分两个大版本,v1.2和v3.0,
其功能和go get地址都是不同的,注意区分。
2/cron1.2版本
安装该库包
go get github.com/robfig/cron
使用demo
package main
import (
"github.com/robfig/cron"
"log"
)
func testCornv1_2() {
log.Println("Starting...")
c := cron.New()
c.AddFunc("*/5 * * * * *", func() {
log.Println("hello world1")
})
c.AddFunc("*/8 * * * * *", func() {
log.Println("hello world2")
})
c.Start()
defer c.Stop() # 延迟关闭定时任务
}
func main() {
go testCornv1_2()
select {
}
}
cron表达式的设置说明
Cron的v1.2版本默认支持精确到`秒`的cron表达式,Linux系统原生支持的标准cron表达式只能精确到分钟。
具体的设置如下所示:一共是5个字段
┌─────────────second 范围 (0 - 60)
│ ┌───────────── min 范围 (0 - 59)
│ │ ┌────────────── hour 范围 (0 - 23)
│ │ │ ┌─────────────── day of month 范围 (1 - 31)
│ │ │ │ ┌──────────────── month 范围 (1 - 12)
│ │ │ │ │ ┌───────────────── day of week 范围 (0 - 6) (0 to 6 are Sunday to
│ │ │ │ │ │ Saturday)
│ │ │ │ │ │
│ │ │ │ │ │
* * * * * *
匹配符号
<1>星号(*) :表示 cron 表达式能匹配该字段的所有值。如在第5个字段使用星号(month),表示每个月
<2>斜线(/):表示增长间隔,如第2个字段(minutes) 值是 3-59/15,表示每小时的第3分钟开始执行一次,之后 每隔 15 分钟执行一次(即 3(3+0*15)、18(3+1*15)、33(3+2*15)、48(3+3*15) 这些时间点执行),这里也可以表示为:3/15
<3>逗号(,):用于枚举值,如第6个字段值是 MON,WED,FRI,表示 星期一、三、五 执行
<4>连字号(-): 表示一个范围,如第3个字段的值为 9-17 表示 9am 到 5pm 直接每个小时(包括9和17)
<5>问号(?):只用于 日(Day of month) 和 星期(Day of week),表示不指定值,可以用于代替 *
// 每5秒执行一次:*/5 * * * * *
// 每个工作日早上9点45分执行一次:0 45 9 * * 1,2,3,4,5
3/cron3.0版本
安装
go get github.com/robfig/cron/v3@v3.0.0
demo
Cron的v3版本相比v1.2版本最大的变化就是支持定时任务的撤销功能:
cron.Remove(cron.EntryID)。
cron.EntryID这个值在添加定时任务会返回。
package main
import (
"github.com/robfig/cron/v3"
"learn-go/corn/DB"
"log"
"time"
)
var c *cron.Cron
func InitCron() {
c = cron.New(cron.WithSeconds())
for examId := range DB.DB {
id, err := addCron(examId, DB.DB[examId].Spec)
if err != nil {
log.Printf("InitCron err: %v", err)
}
DB.Update(examId, DB.DB[examId].Spec, id)
}
}
func StartCron() {
c.Start()
defer c.Stop()
select {}
}
func AddCron(examId, spec string) int {
id, err := addCron(examId, spec)
if err != nil {
log.Println(err)
return 0
}
DB.Insert(examId, spec, id)
return id
}
func addCron(examId, spec string) (int, error) {
id, err := c.AddFunc(spec, func() {
log.Printf("推送考试提醒消息 examId: %v\n", examId)
})
if err != nil {
log.Printf("err: %v\n", err)
}
return int(id), err
}
func DeleteCron(examId string) {
deleteCron(examId)
DB.Delete(examId)
}
func deleteCron(examId string) {
ccron := DB.Query(examId)
id := ccron.Id
c.Remove(cron.EntryID(id))
}
func UpdateCron(examId, spec string) {
id := updateCron(examId, spec)
DB.Update(examId, spec, id)
}
func updateCron(examId, spec string) int {
DeleteCron(examId)
id := AddCron(examId, spec)
return id
}
func main() {
InitCron()
go StartCron()
AddCron("6652", "*/1 * * * * *")
log.Printf("examId :%v Cron: %v \n", "6652", DB.Query("6652"))
AddCron("6616", "*/1 * * * * *")
log.Printf("examId :%v Cron: %v \n", "6616", DB.Query("6616"))
AddCron("6636", "*/3 * * * * *")
log.Printf("examId :%v Cron: %v \n", "6636", DB.Query("6636"))
log.Println(c.Entry(1).Next.Unix())
time.Sleep(time.Second * 8)
log.Println(c.Entry(1).Prev.Unix())
log.Println("-------------UpdateCron-------------")
UpdateCron("6652", "*/2 * * * * *")
time.Sleep(time.Second * 20)
log.Println("-------------DeleteCron-------------")
log.Printf("DB Before DeleteCron: %v\n", DB.DB)
DeleteCron("6616")
log.Printf("DB After DeleteCron: %v\n", DB.DB)
select {} # 保持程序运行
}