golang实现简单流畅的定时任务调度插件库gocron的使用
Golang实现简单流畅的定时任务调度插件库gocron的使用
简介
gocron是一个Golang作业调度包,它允许你在预定时间间隔内运行Go函数。
快速开始
首先安装gocron:
go get github.com/go-co-op/gocron/v2
下面是一个基本使用示例:
package main
import (
"fmt"
"time"
"github.com/go-co-op/gocron/v2"
)
func main() {
// 创建调度器
s, err := gocron.NewScheduler()
if err != nil {
// 处理错误
}
// 向调度器添加任务
j, err := s.NewJob(
gocron.DurationJob(
10*time.Second,
),
gocron.NewTask(
func(a string, b int) {
// 执行任务
fmt.Printf("任务执行 - 参数a: %s, 参数b: %d\n", a, b)
},
"hello",
1,
),
)
if err != nil {
// 处理错误
}
// 每个任务都有唯一ID
fmt.Println("任务ID:", j.ID())
// 启动调度器
s.Start()
// 阻塞直到准备关闭
select {
case <-time.After(time.Minute):
}
// 完成后关闭调度器
err = s.Shutdown()
if err != nil {
// 处理错误
}
}
核心概念
- Job(任务):任务封装了一个"task(任务)",由Go函数和任何函数参数组成。然后任务向调度器提供下次应该调度运行的时间。
- Scheduler(调度器):调度器跟踪所有任务,并在任务准备运行时将其发送给执行器。
- Executor(执行器):执行器调用任务的任务函数,并管理不同任务执行时序要求的复杂性。
功能特性
任务类型
任务可以在各种时间间隔运行:
- Duration(固定间隔):任务可以在固定的
time.Duration
间隔运行。 - Random duration(随机间隔):任务可以在最小和最大之间的随机
time.Duration
间隔运行。 - Cron:任务可以使用crontab运行。
- Daily(每日):任务可以每隔x天在特定时间运行。
- Weekly(每周):任务可以每隔x周在每周的特定天数和特定时间运行。
- Monthly(每月):任务可以每隔x月在每月的特定天数和特定时间运行。
- One time(一次性):任务可以在特定时间运行(一次或多次)。
并发限制
任务可以单独限制或在整个调度器中限制:
- 单例模式:任务可以限制为单个并发执行,要么重新调度(跳过重叠的执行),要么排队(等待前一次执行完成)。
- 限制模式:任务可以限制为在整个调度器中的一定数量的并发执行,使用重新调度(达到限制时跳过)或排队(任务添加到队列以等待限制可用)。
分布式gocron实例
可以运行多个gocron实例:
- 选举器:可以使用选举器选举单个gocron实例作为主实例运行,其他实例检查是否需要选举新的领导者。
- 锁:可以使用锁将每个任务的运行锁定到单个gocron实例。
事件
任务事件可以触发操作:
- 监听器:可以添加到任务中,使用事件监听器,或通过调度器监听所有任务的事件并触发操作。
日志记录
可以启用日志:
- 可以使用您想要的日志库实现Logger接口。提供的NewLogger使用标准库的log包。
监控
可以从每个任务的执行中收集指标:
- Monitor(监控器):可以使用监控器从调度器中收集每个任务的指标。
完整示例
下面是一个更完整的示例,展示各种任务类型:
package main
import (
"fmt"
"time"
"github.com/go-co-op/gocron/v2"
)
func main() {
// 创建调度器
s, err := gocron.NewScheduler()
if err != nil {
panic(err)
}
// 固定间隔任务
_, err = s.NewJob(
gocron.DurationJob(5*time.Second),
gocron.NewTask(func() {
fmt.Println("固定间隔任务执行:", time.Now().Format("15:04:05"))
}),
)
if err != nil {
panic(err)
}
// 随机间隔任务
_, err = s.NewJob(
gocron.DurationRandomJob(3*time.Second,7*time.Second),
gocron.NewTask(func() {
fmt.Println("随机间隔任务执行:", time.Now().Format("15:04:05"))
}),
)
if err != nil {
panic(err)
}
// Cron表达式任务
_, err = s.NewJob(
gocron.CronJob("*/10 * * * * *", false), // 每10秒
gocron.NewTask(func() {
fmt.Println("Cron任务执行:", time.Now().Format("15:04:05"))
}),
)
if err != nil {
panic(err)
}
// 启动调度器
s.Start()
// 运行5分钟
time.Sleep(5 * time.Minute)
// 关闭调度器
err = s.Shutdown()
if err != nil {
panic(err)
}
}
这个示例展示了gocron的基本用法,包括固定间隔、随机间隔和Cron表达式任务。你可以根据需要扩展这个示例,添加更多功能如并发限制、事件监听等。
更多关于golang实现简单流畅的定时任务调度插件库gocron的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang实现简单流畅的定时任务调度插件库gocron的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
GoCron - 简单流畅的定时任务调度库
GoCron 是一个轻量级的 Golang 定时任务调度库,它提供了简单易用的 API 来安排周期性任务。下面我将详细介绍如何使用 GoCron 实现定时任务调度。
安装
首先安装 GoCron 库:
go get github.com/go-co-op/gocron
基本使用
1. 创建调度器
package main
import (
"fmt"
"time"
"github.com/go-co-op/gocron"
)
func main() {
// 创建调度器实例
s := gocron.NewScheduler(time.UTC)
// 添加任务
_, err := s.Every(1).Seconds().Do(task)
if err != nil {
panic(err)
}
// 启动调度器
s.StartBlocking()
}
func task() {
fmt.Println("任务执行:", time.Now().Format("2006-01-02 15:04:05"))
}
2. 多种时间间隔设置
// 每5秒执行一次
s.Every(5).Seconds().Do(task)
// 每1分钟执行一次
s.Every(1).Minute().Do(task)
// 每2小时执行一次
s.Every(2).Hours().Do(task)
// 每天执行一次
s.Every(1).Day().Do(task)
// 每周一执行
s.Every(1).Monday().Do(task)
// 每月1号执行
s.Every(1).Month(1).Do(task)
3. 指定具体时间执行
// 每天10:30执行
s.Every(1).Day().At("10:30").Do(task)
// 每周一10:30执行
s.Every(1).Monday().At("10:30").Do(task)
// 每月1号10:30执行
s.Every(1).Month(1).At("10:30").Do(task)
高级功能
1. 带参数的任务
func greet(name string) {
fmt.Printf("Hello, %s! Time: %s\n", name, time.Now().Format("15:04:05"))
}
func main() {
s := gocron.NewScheduler(time.UTC)
// 传递参数给任务
_, err := s.Every(2).Seconds().Do(greet, "Alice")
if err != nil {
panic(err)
}
s.StartBlocking()
}
2. 任务标签与移除任务
func main() {
s := gocron.NewScheduler(time.UTC)
// 添加带标签的任务
_, err := s.Every(1).Second().Tag("task1").Do(task)
if err != nil {
panic(err)
}
// 5秒后移除任务
time.AfterFunc(5*time.Second, func() {
err := s.RemoveByTag("task1")
if err != nil {
fmt.Println("移除任务失败:", err)
} else {
fmt.Println("任务已移除")
}
})
s.StartBlocking()
}
3. 单例模式(防止任务重叠)
func main() {
s := gocron.NewScheduler(time.UTC)
// 设置单例模式 - 如果前一个任务还在运行,则跳过本次执行
_, err := s.Every(1).Second().SingletonMode().Do(longRunningTask)
if err != nil {
panic(err)
}
s.StartBlocking()
}
func longRunningTask() {
fmt.Println("长任务开始:", time.Now().Format("15:04:05"))
time.Sleep(3 * time.Second)
fmt.Println("长任务结束:", time.Now().Format("15:04:05"))
}
4. 并发限制
func main() {
s := gocron.NewScheduler(time.UTC)
// 设置最大并发任务数为2
s.SetMaxConcurrentJobs(2, gocron.RescheduleMode)
// 添加多个任务
for i := 0; i < 5; i++ {
_, err := s.Every(1).Second().Do(taskWithID, i)
if err != nil {
panic(err)
}
}
s.StartBlocking()
}
func taskWithID(id int) {
fmt.Printf("任务 %d 开始: %s\n", id, time.Now().Format("15:04:05"))
time.Sleep(3 * time.Second)
fmt.Printf("任务 %d 结束: %s\n", id, time.Now().Format("15:04:05"))
}
5. Cron 表达式支持
func main() {
s := gocron.NewScheduler(time.UTC)
// 使用标准cron表达式
_, err := s.Cron("*/5 * * * *").Do(task) // 每5分钟执行一次
if err != nil {
panic(err)
}
s.StartBlocking()
}
实际应用示例
package main
import (
"fmt"
"time"
"github.com/go-co-op/gocron"
)
func main() {
// 创建调度器
scheduler := gocron.NewScheduler(time.UTC)
// 添加多个任务
_, _ = scheduler.Every(5).Seconds().Do(monitorSystem)
_, _ = scheduler.Every(1).Hour().Do(cleanTempFiles)
_, _ = scheduler.Every(1).Day().At("02:00").Do(backupDatabase)
// 启动调度器
fmt.Println("定时任务调度器启动...")
scheduler.StartBlocking()
}
func monitorSystem() {
fmt.Printf("[%s] 监控系统状态...\n", time.Now().Format("2006-01-02 15:04:05"))
// 实际监控逻辑...
}
func cleanTempFiles() {
fmt.Printf("[%s] 清理临时文件...\n", time.Now().Format("2006-01-02 15:04:05"))
// 实际清理逻辑...
}
func backupDatabase() {
fmt.Printf("[%s] 数据库备份开始...\n", time.Now().Format("2006-01-02 15:04:05"))
// 实际备份逻辑...
time.Sleep(10 * time.Second) // 模拟耗时操作
fmt.Printf("[%s] 数据库备份完成\n", time.Now().Format("2006-01-02 15:04:05"))
}
注意事项
- 默认情况下,GoCron 使用 UTC 时区,可以通过
NewScheduler
指定本地时区 - 长时间运行的任务可能会影响调度精度,考虑使用单例模式
- 在生产环境中,建议添加适当的错误处理和恢复机制
- 对于分布式系统,需要考虑分布式锁机制
GoCron 是一个简单但功能强大的定时任务调度库,适合大多数定时任务场景。对于更复杂的需求,可以考虑结合其他工具如消息队列或专门的作业调度系统。