golang定时任务调度与管理插件库go-cron的使用
golang定时任务调度与管理插件库go-cron的使用
简介
go-cron是一个简单的定时任务调度库,可以处理计划任务。任务可以以最小一秒的延迟运行(虽然这并不是Cron最初设计的目的)。比较操作快速高效,并在goroutine中进行;匹配的作业也在goroutine中执行。
使用示例
以下是一个在web应用中使用go-cron的示例,该应用使用MySQL数据库:
func init() {
// 创建一个每周一23:59:59执行的定时任务
cron.NewWeeklyJob(1, 23, 59, 59, func (time.Time) {
// 执行MySQL表优化操作
_, err := conn.Query("OPTIMIZE TABLE mytable;")
if err != nil {
println(err)
}
})
}
完整示例demo
下面是一个更完整的go-cron使用示例,展示了多种定时任务的创建方式:
package main
import (
"fmt"
"time"
"github.com/thewickedflea/go-cron"
)
func main() {
// 创建一个每秒执行的任务
cron.NewJob("* * * * * *", func(t time.Time) {
fmt.Printf("每秒执行的任务 - 当前时间: %v\n", t)
})
// 创建一个每分钟的第30秒执行的任务
cron.NewJob("30 * * * * *", func(t time.Time) {
fmt.Printf("每分钟第30秒执行的任务 - 当前时间: %v\n", t)
})
// 创建一个每天12:30:00执行的任务
cron.NewDailyJob(12, 30, 0, func(t time.Time) {
fmt.Printf("每天中午12:30执行的任务 - 当前时间: %v\n", t)
})
// 创建一个每周三15:45:00执行的任务
cron.NewWeeklyJob(3, 15, 45, 0, func(t time.Time) {
fmt.Printf("每周三15:45执行的任务 - 当前时间: %v\n", t)
})
// 保持程序运行
select {}
}
注意事项
- go-cron的任务执行是在goroutine中进行的,因此任务是并发执行的
- 定时任务的精度可以达到秒级
- 使用NewWeeklyJob时,参数1表示周一,7表示周日
- 使用NewDailyJob时,参数依次是小时、分钟、秒
许可证
Copyright 2011 Robert Kosek thewickedflea@gmail.com. 保留所有权利。
在满足以下条件的情况下,允许以源代码和二进制形式重新分发和使用,无论是否修改:
- 源代码的重新分发必须保留上述版权声明、本条件列表和以下免责声明。
- 以二进制形式重新分发必须在分发时提供的文档和/或其他材料中复制上述版权声明、本条件列表和以下免责声明。
本软件按"原样"提供,不作任何明示或暗示的保证,包括但不限于对适销性和特定用途适用性的暗示保证。在任何情况下,Robert Kosek或贡献者均不对任何直接、间接、附带、特殊、示范性或后果性损害(包括但不限于替代商品或服务的采购、使用损失、数据或利润损失或业务中断)负责,无论是合同责任、严格责任还是侵权行为(包括疏忽或其他)引起的,即使已被告知此类损害的可能性。
软件和文档中包含的观点和结论是作者的观点和结论,不应被解释为代表Robert Kosek的官方政策,无论是明示还是暗示。
更多关于golang定时任务调度与管理插件库go-cron的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang定时任务调度与管理插件库go-cron的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Go-Cron 定时任务调度与管理
go-cron 是一个基于 Go 语言的定时任务调度库,它提供了类似于 Unix 的 cron 表达式的任务调度功能。下面我将详细介绍 go-cron 的使用方法。
安装
go get github.com/robfig/cron/v3
基本使用
1. 创建 cron 实例
package main
import (
"fmt"
"time"
"github.com/robfig/cron/v3"
)
func main() {
c := cron.New()
// 添加任务
c.AddFunc("@every 1s", func() {
fmt.Println("每秒执行一次", time.Now())
})
// 启动 cron
c.Start()
// 防止主程序退出
select {}
}
2. 使用 cron 表达式
c.AddFunc("0 30 * * * *", func() {
fmt.Println("每小时的第30分钟执行", time.Now())
})
cron 表达式格式:
秒 分 时 日 月 周
3. 预定义时间表
go-cron 提供了一些预定义的时间表:
@yearly
或@annually
- 每年一次@monthly
- 每月一次@weekly
- 每周一次@daily
或@midnight
- 每天一次@hourly
- 每小时一次@every <duration>
- 每隔指定时间执行
高级功能
1. 带 ID 的任务
id, err := c.AddFunc("@every 5s", func() {
fmt.Println("每5秒执行一次", time.Now())
})
if err != nil {
fmt.Println("添加任务失败:", err)
}
fmt.Println("任务ID:", id)
2. 移除任务
// 添加任务并获取ID
id, _ := c.AddFunc("@every 10s", func() {
fmt.Println("这个任务将被移除", time.Now())
})
// 5秒后移除任务
time.Sleep(5 * time.Second)
c.Remove(id)
3. 任务日志
c := cron.New(
cron.WithLogger(
cron.VerbosePrintfLogger(log.New(os.Stdout, "cron: ", log.LstdFlags)),
),
)
4. 时区设置
loc, _ := time.LoadLocation("Asia/Shanghai")
c := cron.New(cron.WithLocation(loc))
5. 任务恢复
c := cron.New(cron.WithChain(
cron.Recover(cron.DefaultLogger), // 捕获 panic
)
完整示例
package main
import (
"fmt"
"log"
"os"
"time"
"github.com/robfig/cron/v3"
)
func main() {
// 创建带日志的 cron 实例
c := cron.New(
cron.WithLogger(
cron.VerbosePrintfLogger(log.New(os.Stdout, "cron: ", log.LstdFlags)),
),
cron.WithChain(
cron.Recover(cron.DefaultLogger),
),
)
// 添加多个任务
c.AddFunc("@every 1s", func() {
fmt.Println("每秒任务执行", time.Now())
})
c.AddFunc("0 30 * * * *", func() {
fmt.Println("每小时30分任务执行", time.Now())
})
// 带ID的任务
id, err := c.AddFunc("@every 5s", func() {
fmt.Println("每5秒任务执行", time.Now())
})
if err != nil {
log.Fatal("添加任务失败:", err)
}
fmt.Println("5秒任务的ID:", id)
// 启动 cron
c.Start()
// 10秒后移除5秒任务
time.Sleep(10 * time.Second)
c.Remove(id)
fmt.Println("已移除5秒任务")
// 运行30秒后停止
time.Sleep(20 * time.Second)
c.Stop()
fmt.Println("cron 已停止")
}
最佳实践
- 错误处理:始终检查 AddFunc 返回的错误
- 资源清理:使用 defer c.Stop() 确保资源释放
- 日志记录:生产环境务必启用日志
- 任务轻量:避免在任务中执行耗时操作
- 并发控制:考虑使用 sync.WaitGroup 控制并发
go-cron 是一个简单而强大的定时任务库,适合大多数 Go 应用的定时任务需求。对于更复杂的分布式任务调度,可以考虑使用更专业的系统如 Celery 或分布式任务队列。