Go (Golang) 任务调度器:从简单的 ticker 到工业级 cron
任务调度器 (task scheduler) 是一个组件,它允许在指定时间或按指定周期执行特定函数。在 Go (Golang) 生态系统中,有多种实现调度器的方法:从语言内置的原语到强大的第三方库。在本文中,我们将探讨如何使用 Go 创建任务调度器,从简单的示例开始,最后使用流行的 robfig/cron 库。
为什么在 Go 中需要任务调度器?
Go 非常适合创建高性能的服务器应用程序、微服务和命令行工具。任务调度器可以自动化日常操作:
- 清理缓存或临时文件
- 发送定期通知(电子邮件、短信)
- 收集指标和监控
- 与外部 API 同步数据
- 按计划生成报告
使用 time.Ticker 的基础调度器
每 N 秒执行任务的最简单方法是使用 time.Ticker。这个 Go 内置工具会按设定的时间间隔向通道发送值。
package main
import ( "fmt" "time")
func main() { ticker := time.NewTicker(2 * time.Second) done := make(chan bool)
go func() { for { select { case <-ticker.C: fmt.Println("任务已执行:", time.Now().Format(time.RFC3339)) case <-done: ticker.Stop() return } } }()
// 10 秒后停止调度器 time.Sleep(10 * time.Second) done <- true fmt.Println("调度器已停止")}这段代码创建了一个 goroutine,每 2 秒输出一次当前时间。请注意 select 的使用——这是 Go 中用于非阻塞处理多个通道的关键模式。
具有灵活调度的调度器:robfig/cron 库
对于需要类似 cron 调度的实际项目(例如,“每周一上午 9:00”或“每天 9 点到 18 点之间每 5 分钟”),github.com/robfig/cron/v3 库是最佳选择。它完全支持标准的 cron 语法,并添加了方便的功能,例如时区支持和 panic 处理。
安装
go get github.com/robfig/cron/v3使用示例
package main
import ( "fmt" "log" "time"
"github.com/robfig/cron/v3")
func main() { c := cron.New(cron.WithSeconds()) // 启用秒支持
// 添加任务:每 10 秒 _, err := c.AddFunc("*/10 * * * * *", func() { fmt.Println("任务 1: 每 10 秒", time.Now().Format(time.RFC3339)) }) if err != nil { log.Fatal(err) }
// 任务:每天 UTC 时间 14:30 _, err = c.AddFunc("0 30 14 * * *", func() { fmt.Println("任务 2: 每天 UTC 时间 14:30") }) if err != nil { log.Fatal(err) }
// 带名称的任务,便于后续管理 entryID, _ := c.AddFunc("@every 1m", func() { fmt.Println("任务 3: 每分钟") })
c.Start()
// 5 分钟后删除任务 time.Sleep(5 * time.Minute) c.Remove(entryID) fmt.Println("任务 3 已删除")
// 阻塞 main select {}}该库支持多种调度格式:
- 标准 cron:
"30 * * * *"— 每 30 分钟 - 带秒数:
"0 30 * * * *"— 每分钟的第 30 秒 - @every:
"@every 5m"— 每 5 分钟 图书馆中也有
推荐