Go (Golang) 任务调度器:cron、gocron 和 robfig/cron
任务调度器 (task scheduler) 是应用程序中自动化周期性操作不可或缺的工具:从缓存清理、通知发送到后台数据处理器的启动。在 Go (Golang) 生态系统中,有多个流行的库可用于实现类似 cron 的行为。在本文中,我们将探讨三种主要方法:内置包 cron、轻量级库 gocron 以及事实上的标准库 robfig/cron。
1. 内置包 cron(实验性)
从 Go 1.19 开始,标准库中引入了实验性包 cron,位于 golang.org/x/exp/cron。它提供了按计划运行任务的基本功能。然而,由于功能有限且不支持复杂的 cron 表达式(例如带秒的表达式),在实际中使用较少。
package main
import ( "context" "fmt" "golang.org/x/exp/cron" "time")
func main() { sched := cron.New() // 每 10 秒运行一次 sched.Add("*/10 * * * * *", func() { fmt.Println("任务已执行:", time.Now()) }) sched.Start() time.Sleep(30 * time.Second) sched.Stop()}2. robfig/cron 库——黄金标准
github.com/robfig/cron/v3 库是 Go 中最流行且最成熟的任务调度器实现。它支持:
- 标准 cron 表达式(5 个字段),可选秒字段
- 预定义计划:
@yearly、@monthly、@weekly、@daily、@hourly - 间隔:
@every 5m(每 5 分钟) - 时区 (timezone)
- 通过 Recovery 日志处理器处理恐慌
- 通过
Logger接口实现灵活的日志记录系统
安装
go get github.com/robfig/cron/v3基本示例
package main
import ( "fmt" "github.com/robfig/cron/v3" "time")
func main() { c := cron.New(cron.WithSeconds()) // 启用秒支持
// 每分钟的第 30 秒 c.AddFunc("30 * * * * *", func() { fmt.Println("每分钟的第 30 秒:", time.Now().Format("15:04:05")) })
// 每天早上 8:00 c.AddFunc("0 0 8 * * *", func() { fmt.Println("每天 8:00") })
// 每 2 小时 c.AddFunc("@every 2h", func() { fmt.Println("每 2 小时") })
// 每周一 9:30 c.AddFunc("30 9 * * 1", func() { fmt.Println("每周一 9:30") })
c.Start() defer c.Stop()
// 等待 1 分钟以查看执行 time.Sleep(70 * time.Second)}robfig/cron 中的 cron 表达式语法
标准表达式由 5 个字段组成(分钟、小时、日、月、星期几)。启用 cron.WithSeconds() 选项后,会添加第六个字段——秒 (0-59)。
*— 任意值*/5— 每 5 个单位1,15,30— 特定值1-10— 范围L— 最后(例如,月份的最后一天)
3. gocron 库——简单易读
github.com/go-co-op/gocron 提供了更高级的流畅接口 (fluent interface) 来创建计划。如果您不需要复杂的 cron 表达式,而只需要简单的间隔,它非常理想。
安装
go get github.com/go-co-op/gocron/v2使用示例
package main
import ( "fmt