Golang - Cron 定时任务
robfig/cron/v3
是一个 Golang 的定时任务库,支持 cron 表达式。低耦合高内聚,其中涉及装饰器模式,并发处理等。
依赖包
import "github.com/robfig/cron/v3"
Cron 表达式
robfig/cron/v3与robfig/cron有差异,cron v3版本默认已经不再是支持到秒级别的定时了。
特殊符号
星号(*)
星号表示匹配该字段的所有值,如在上面表达式的天位置中使用星号,就表示每天。
斜线(/)
斜杠用于描述范围的增量,比如'3-59/15'这个表达式在表示从现在的第三分钟开始和往后的每15分钟,到第59分钟为止。表现形式为"* \ / ...",等同于"N-MAX / m",即在该字段范围内的增量。即从N开始,使用增量 m 直到 MAX 结束,它没有重复
逗号(,)
逗号用于分隔列表中的项,比如,在上表的'星期几'中使用 "MON,WED,FRI" 表示星期一、星期三和星期五
连字符(-)
连字符用于定义范围。例如,9-17表示包括上午9点至下午5点在内的每小时
问号 (?)
表示不指定值,可以来代替 *
预定义表达式
表达式示例
示例
package main
import "github.com/robfig/cron/v3"
c := cron.New()
// 添加一个任务,每 30 分钟 执行一次
c.AddFunc("30 * * * *", func() { fmt.Println("Every hour on the half hour") })
// 开始执行(每个任务会在自己的 goroutine 中执行)
c.Start()
// 允许往正在执行的 cron 中添加任务
c.AddFunc("@daily", func() { fmt.Println("Every day") })
// 检查上一个和下一个任务执行的时间
inspect(c.Entries())
...
c.Stop() // 停止调度,但正在运行的作业不会被停止
定时任务Cron执行不成功?
解决方案一:
使用老版本的cron包
package main
import (
"fmt"
"github.com/robfig/cron"
)
func main() {
// 每隔3秒执行一次:*/3 * * * * *
spec := "*/3 * * * * *"
c := cron.New()
c.AddFunc(spec, func() {
fmt.Println("每隔3秒执行一次")
})
go c.Start()
defer c.Stop()
select {}
}
解决方案二:
使用新版本的cron包,但是要cron.New(cron.WithSeconds())方法
package main
import (
"fmt"
"github.com/robfig/cron/v3"
)
func main() {
// 每天凌晨0点执行一次:0 0 0 * * ?
// 每隔3秒执行一次:*/3 * * * * *
// spec := "*/3 * * * * *"
spec := "* * * * *"
c := cron.New(cron.WithSeconds())
c.AddFunc(spec, func() {
fmt.Println("execute")
})
go c.Start()
defer c.Stop()
select {}
}
总结
Cron 的几个特点:
1)允许在允许中添加或删除 Job:通过 chan 发送信号,select 监听,重新排序。
2)装饰器机制:允许给 Job 添加装饰器,装饰器会在 Entry 初始化时执行。
3)低耦合:New() 时可以传递 Option, 以此可以改变一些默认行为,如可以实现自己的 cron 解释器。
4)每个 Job 使用单独的 goroutine 执行。
5)Stop Cron 不会停止已经开始执行但为执行完的 Job, 可以通过 Context 得知什么时候执行完了。