1 介绍
1.1 定义
01.Gron简介
a.基本定义
Gron是一个轻量级的Go语言定时任务库,提供简洁的Cron表达式支持。
b.项目来源
开源项目,GitHub: github.com/roylee0704/gron。
c.核心特点
简单易用、支持标准Cron语法、轻量级、无外部依赖。
02.定时任务概念
a.Cron任务
按照时间表达式定期执行的任务。
b.调度器
负责管理和触发定时任务的组件。
c.任务函数
定时执行的具体业务逻辑。
03.基本使用
a.功能说明
演示Gron的基本用法。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
// 创建调度器
c := gron.New()
// 添加定时任务 - 每分钟执行
c.AddFunc(gron.Every(1*time.Minute), func() {
fmt.Println("任务执行:", time.Now().Format("2006-01-02 15:04:05"))
})
// 启动调度器
c.Start()
// 等待一段时间观察任务执行
time.Sleep(5 * time.Minute)
// 停止调度器
c.Stop()
}
---
1.2 核心概念
01.Cron调度器
a.调度器实例
gron.New()创建调度器。
b.任务管理
添加、删除、启动、停止任务。
c.生命周期
Start启动,Stop停止。
02.时间表达式
a.Every表达式
gron.Every(duration)固定间隔。
b.Cron表达式
支持标准Cron语法。
c.自定义调度
灵活的时间配置。
03.任务函数
a.无参函数
func()类型的任务函数。
b.AddFunc
添加任务到调度器。
c.并发执行
任务在独立goroutine中执行。
04.核心方法
a.New创建
gron.New()创建调度器实例。
b.AddFunc添加
添加定时任务。
c.Start启动
启动调度器开始执行任务。
d.Stop停止
停止调度器和所有任务。
1.3 优缺点
01.主要优势
a.简单易用
API简洁,快速上手。
b.轻量级
代码量少,无外部依赖。
c.标准Cron
支持标准Cron表达式语法。
d.并发安全
内置并发控制,线程安全。
e.灵活调度
支持多种时间表达式。
02.主要限制
a.功能简单
相比robfig/cron功能较少。
b.持久化
不支持任务持久化。
c.分布式
不支持分布式调度。
d.任务依赖
不支持任务间依赖关系。
03.适用场景
a.适合使用
简单定时任务、单机应用、轻量级调度、快速原型。
b.不适合使用
复杂任务编排、分布式调度、需要持久化、高可用要求。
1.4 使用场景
01.数据同步
a.定期同步
定时从外部系统同步数据。
b.增量更新
按时间间隔更新数据。
c.同步示例
a.功能说明
定时同步数据库数据。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func syncData() {
fmt.Println("开始同步数据:", time.Now().Format("15:04:05"))
// 模拟数据同步
time.Sleep(2 * time.Second)
fmt.Println("数据同步完成")
}
func main() {
c := gron.New()
// 每5分钟同步一次
c.AddFunc(gron.Every(5*time.Minute), syncData)
c.Start()
defer c.Stop()
// 保持程序运行
select {}
}
---
02.定时清理
a.日志清理
定期清理过期日志文件。
b.缓存清理
定时清理过期缓存数据。
c.临时文件
清理临时文件和目录。
03.报表生成
a.日报生成
每天定时生成业务报表。
b.周报月报
按周或月生成统计报表。
c.数据导出
定期导出数据到文件。
04.监控告警
a.健康检查
定期检查系统健康状态。
b.指标采集
定时采集系统指标。
c.告警通知
检测异常并发送告警。
1.5 设计理念
01.简洁优先
a.最小API
只提供核心功能,API简洁。
b.易于理解
代码清晰,容易理解和使用。
c.快速集成
几行代码即可完成集成。
02.标准兼容
a.Cron语法
兼容标准Cron表达式。
b.时间间隔
支持Duration时间间隔。
c.灵活配置
多种时间配置方式。
03.并发安全
a.goroutine
每个任务在独立goroutine执行。
b.线程安全
内部使用锁保证并发安全。
c.资源管理
自动管理goroutine生命周期。
04.设计示例
a.功能说明
展示Gron的设计优势。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
// 简洁的API - 固定间隔
c.AddFunc(gron.Every(30*time.Second), func() {
fmt.Println("每30秒执行")
})
// 支持多个任务
c.AddFunc(gron.Every(1*time.Minute), func() {
fmt.Println("每分钟执行")
})
c.AddFunc(gron.Every(5*time.Minute), func() {
fmt.Println("每5分钟执行")
})
// 一行启动
c.Start()
// 优雅停止
time.Sleep(10 * time.Minute)
c.Stop()
fmt.Println("调度器已停止")
}
---
2 基础使用
2.1 汇总:5个
01.创建调度器
a.New方法
gron.New()创建调度器实例。
b.单例模式
通常一个应用一个调度器。
02.添加任务
a.AddFunc
添加定时任务函数。
b.时间表达式
指定任务执行时间。
03.启动调度器
a.Start方法
启动调度器开始执行任务。
b.非阻塞
Start是非阻塞的。
04.停止调度器
a.Stop方法
停止调度器和所有任务。
b.优雅停止
等待当前任务执行完成。
05.任务管理
a.动态添加
运行时添加新任务。
b.任务清理
Stop时清理所有任务。
2.2 创建定时任务
01.创建调度器
a.New方法
创建新的调度器实例。
b.调度器配置
默认配置即可使用。
02.添加任务
a.AddFunc方法
添加任务到调度器。
b.任务函数
无参数的func()类型。
03.创建任务示例
a.功能说明
创建多个不同间隔的定时任务。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func task1() {
fmt.Println("[Task1] 每10秒执行:", time.Now().Format("15:04:05"))
}
func task2() {
fmt.Println("[Task2] 每30秒执行:", time.Now().Format("15:04:05"))
}
func task3() {
fmt.Println("[Task3] 每分钟执行:", time.Now().Format("15:04:05"))
}
func main() {
// 创建调度器
c := gron.New()
// 添加多个任务
c.AddFunc(gron.Every(10*time.Second), task1)
c.AddFunc(gron.Every(30*time.Second), task2)
c.AddFunc(gron.Every(1*time.Minute), task3)
// 启动调度器
c.Start()
fmt.Println("调度器已启动")
// 运行5分钟
time.Sleep(5 * time.Minute)
// 停止调度器
c.Stop()
fmt.Println("调度器已停止")
}
---
04.匿名函数
a.内联定义
直接使用匿名函数定义任务。
b.闭包支持
可以捕获外部变量。
2.3 Cron表达式
01.Every表达式
a.固定间隔
gron.Every(duration)创建固定间隔。
b.Duration类型
使用time.Duration指定间隔。
02.时间单位
a.秒级
time.Second, 10*time.Second
b.分钟级
time.Minute, 5*time.Minute
c.小时级
time.Hour, 2*time.Hour
03.表达式示例
a.功能说明
使用不同时间间隔的任务。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
// 每5秒
c.AddFunc(gron.Every(5*time.Second), func() {
fmt.Println("5秒任务")
})
// 每1分钟
c.AddFunc(gron.Every(1*time.Minute), func() {
fmt.Println("1分钟任务")
})
// 每10分钟
c.AddFunc(gron.Every(10*time.Minute), func() {
fmt.Println("10分钟任务")
})
// 每1小时
c.AddFunc(gron.Every(1*time.Hour), func() {
fmt.Println("1小时任务")
})
// 每24小时(每天)
c.AddFunc(gron.Every(24*time.Hour), func() {
fmt.Println("每天任务")
})
c.Start()
defer c.Stop()
select {}
}
---
2.4 任务调度
01.调度机制
a.时间触发
按照时间表达式触发任务执行。
b.goroutine执行
每个任务在独立goroutine中运行。
02.调度示例
a.功能说明
演示任务调度的执行机制。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
// 任务1: 每10秒执行
c.AddFunc(gron.Every(10*time.Second), func() {
fmt.Printf("[%s] 任务1执行\n", time.Now().Format("15:04:05"))
})
// 任务2: 每30秒执行
c.AddFunc(gron.Every(30*time.Second), func() {
fmt.Printf("[%s] 任务2执行\n", time.Now().Format("15:04:05"))
})
// 任务3: 每分钟执行
c.AddFunc(gron.Every(1*time.Minute), func() {
fmt.Printf("[%s] 任务3执行\n", time.Now().Format("15:04:05"))
})
// 启动调度器
c.Start()
fmt.Println("调度器已启动,任务将按时执行")
// 运行3分钟
time.Sleep(3 * time.Minute)
// 停止调度器
c.Stop()
fmt.Println("调度器已停止")
}
---
03.并发执行
a.独立goroutine
每个任务在独立的goroutine中执行。
b.非阻塞
任务执行不会阻塞其他任务。
2.5 任务管理
01.任务生命周期
a.添加任务
通过AddFunc添加任务到调度器。
b.启动执行
Start后任务开始按时执行。
c.停止任务
Stop停止所有任务。
02.任务管理示例
a.功能说明
演示任务的完整生命周期管理。
b.代码示例
---
package main
import (
"fmt"
"sync/atomic"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
// 计数器
var counter int32
// 添加任务
c.AddFunc(gron.Every(1*time.Second), func() {
count := atomic.AddInt32(&counter, 1)
fmt.Printf("任务执行第 %d 次\n", count)
})
// 启动调度器
fmt.Println("启动调度器...")
c.Start()
// 运行5秒
time.Sleep(5 * time.Second)
// 停止调度器
fmt.Println("停止调度器...")
c.Stop()
// 显示总执行次数
fmt.Printf("任务总共执行了 %d 次\n", atomic.LoadInt32(&counter))
// 尝试再次启动
fmt.Println("\n重新启动调度器...")
c.Start()
time.Sleep(3 * time.Second)
c.Stop()
fmt.Printf("最终执行次数: %d 次\n", atomic.LoadInt32(&counter))
}
---
03.动态管理
a.运行时添加
可以在调度器运行时添加新任务。
b.任务隔离
每个任务独立执行,互不影响。
2.6 错误处理
01.任务错误
a.panic恢复
任务中的panic不会影响调度器。
b.错误隔离
单个任务错误不影响其他任务。
02.错误处理示例
a.功能说明
演示任务错误的处理机制。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
// 正常任务
c.AddFunc(gron.Every(2*time.Second), func() {
fmt.Println("[正常任务] 执行成功")
})
// 会panic的任务
c.AddFunc(gron.Every(3*time.Second), func() {
defer func() {
if r := recover(); r != nil {
fmt.Printf("[错误任务] 捕获panic: %v\n", r)
}
}()
fmt.Println("[错误任务] 开始执行")
panic("模拟任务错误")
})
// 另一个正常任务
c.AddFunc(gron.Every(4*time.Second), func() {
fmt.Println("[另一个正常任务] 执行成功")
})
c.Start()
fmt.Println("调度器已启动,观察错误处理...")
time.Sleep(15 * time.Second)
c.Stop()
fmt.Println("调度器已停止")
}
---
03.最佳实践
a.任务内捕获
在任务函数内部使用defer recover捕获panic。
b.日志记录
记录任务执行的错误信息。
c.重试机制
根据需要实现任务重试逻辑。
3 Cron表达式
3.1 表达式语法
01.Every语法
a.固定间隔
gron.Every(duration)创建固定时间间隔。
b.Duration类型
使用time.Duration指定间隔时间。
02.语法示例
a.功能说明
演示Every表达式的各种用法。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
// 秒级间隔
c.AddFunc(gron.Every(5*time.Second), func() {
fmt.Println("每5秒执行")
})
// 分钟级间隔
c.AddFunc(gron.Every(2*time.Minute), func() {
fmt.Println("每2分钟执行")
})
// 小时级间隔
c.AddFunc(gron.Every(1*time.Hour), func() {
fmt.Println("每小时执行")
})
// 自定义间隔
c.AddFunc(gron.Every(90*time.Second), func() {
fmt.Println("每90秒执行")
})
c.Start()
defer c.Stop()
select {}
}
---
03.时间单位
a.time.Second
秒级时间单位。
b.time.Minute
分钟级时间单位。
c.time.Hour
小时级时间单位。
3.2 时间字段
01.Duration字段
a.整数倍
可以使用整数倍的Duration。
b.组合使用
可以组合不同时间单位。
02.时间字段示例
a.功能说明
演示不同时间字段的使用。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
// 30秒
c.AddFunc(gron.Every(30*time.Second), func() {
fmt.Println("30秒任务")
})
// 5分钟
c.AddFunc(gron.Every(5*time.Minute), func() {
fmt.Println("5分钟任务")
})
// 组合: 1小时30分钟
c.AddFunc(gron.Every(1*time.Hour+30*time.Minute), func() {
fmt.Println("1.5小时任务")
})
// 组合: 2分钟30秒
c.AddFunc(gron.Every(2*time.Minute+30*time.Second), func() {
fmt.Println("2分30秒任务")
})
c.Start()
defer c.Stop()
time.Sleep(10 * time.Minute)
}
---
3.3 特殊字符
01.时间常量
a.预定义常量
使用time包的预定义时间常量。
b.可读性
使用常量提高代码可读性。
02.特殊字符示例
a.功能说明
使用时间常量创建定时任务。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
const (
EveryMinute = 1 * time.Minute
EveryHour = 1 * time.Hour
EveryDay = 24 * time.Hour
)
func main() {
c := gron.New()
// 使用常量
c.AddFunc(gron.Every(EveryMinute), func() {
fmt.Println("每分钟任务")
})
c.AddFunc(gron.Every(EveryHour), func() {
fmt.Println("每小时任务")
})
c.AddFunc(gron.Every(EveryDay), func() {
fmt.Println("每天任务")
})
c.Start()
defer c.Stop()
select {}
}
---
3.4 常用表达式
01.常见间隔
a.每分钟
gron.Every(1*time.Minute)
b.每小时
gron.Every(1*time.Hour)
c.每天
gron.Every(24*time.Hour)
02.常用表达式示例
a.功能说明
常见定���任务的时间配置。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
// 每30秒 - 健康检查
c.AddFunc(gron.Every(30*time.Second), func() {
fmt.Println("健康检查")
})
// 每5分钟 - 数据同步
c.AddFunc(gron.Every(5*time.Minute), func() {
fmt.Println("数据同步")
})
// 每15分钟 - 缓存清理
c.AddFunc(gron.Every(15*time.Minute), func() {
fmt.Println("缓存清理")
})
// 每小时 - 日志归档
c.AddFunc(gron.Every(1*time.Hour), func() {
fmt.Println("日志归档")
})
// 每天 - 数据备份
c.AddFunc(gron.Every(24*time.Hour), func() {
fmt.Println("数据备份")
})
c.Start()
defer c.Stop()
select {}
}
---
3.5 表达式验证
01.时间验证
a.正值检查
Duration必须为正值。
b.合理性检查
确保时间间隔符合业务需求。
02.验证示例
a.功能说明
验证时间表达式的有效性。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func validateDuration(d time.Duration) bool {
if d <= 0 {
return false
}
// 检查是否过短(小于1秒)
if d < time.Second {
return false
}
// 检查是否过长(大于30天)
if d > 30*24*time.Hour {
return false
}
return true
}
func main() {
c := gron.New()
intervals := []time.Duration{
500 * time.Millisecond, // 无效: 小于1秒
5 * time.Second, // 有效
1 * time.Minute, // 有效
-1 * time.Hour, // 无效: 负数
100 * 24 * time.Hour, // 无效: 超过30天
}
for _, interval := range intervals {
if validateDuration(interval) {
c.AddFunc(gron.Every(interval), func() {
fmt.Printf("任务执行: %v\n", interval)
})
fmt.Printf("✓ 添加任务: %v\n", interval)
} else {
fmt.Printf("✗ 无效间隔: %v\n", interval)
}
}
c.Start()
defer c.Stop()
time.Sleep(30 * time.Second)
}
---
4 任务管理
4.1 添加任务
01.AddFunc方法
a.添加任务
将任务函数添加到调度器。
b.返回值
无返回值,直接添加。
02.添加任务示例
a.功能说明
演示多种方式添加任务。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
// 定义任务函数
func task1() {
fmt.Println("任务1执行")
}
func task2() {
fmt.Println("任务2执行")
}
func main() {
c := gron.New()
// 方式1: 使用已定义的函数
c.AddFunc(gron.Every(5*time.Second), task1)
// 方式2: 使用匿名函数
c.AddFunc(gron.Every(10*time.Second), func() {
fmt.Println("匿名任务执行")
})
// 方式3: 使用闭包
counter := 0
c.AddFunc(gron.Every(3*time.Second), func() {
counter++
fmt.Printf("闭包任务执行第%d次\n", counter)
})
c.Start()
defer c.Stop()
time.Sleep(30 * time.Second)
}
---
4.2 删除任务
01.任务删除
a.Stop停止
Stop会停止所有任务。
b.无单独删除
Gron不支持删除单个任务。
02.任务管理
a.重新创建
需要删除任务时重新创建调度器。
b.条件执行
在任务内部添加条件判断。
4.3 启动停止
01.Start启动
a.启动调度
Start启动调度器,任务开始执行。
b.非阻塞
Start是非阻塞的。
02.Stop停止
a.停止调度
Stop停止调度器和所有任务。
b.优雅停止
等待当前执行的任务完成。
03.启动停止示例
a.功能说明
演示调度器的启动和停止。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
c.AddFunc(gron.Every(1*time.Second), func() {
fmt.Printf("[%s] 任务执行\n", time.Now().Format("15:04:05"))
})
// 启动
fmt.Println("启动调度器...")
c.Start()
// 运行5秒
time.Sleep(5 * time.Second)
// 停止
fmt.Println("停止调度器...")
c.Stop()
fmt.Println("等待2秒...")
time.Sleep(2 * time.Second)
// 重新启动
fmt.Println("重新启动调度器...")
c.Start()
time.Sleep(5 * time.Second)
c.Stop()
fmt.Println("最终停止")
}
---
4.4 任务查询
01.任务状态
a.无查询API
Gron不提供任务查询接口。
b.自行记录
需要自行记录任务信息。
02.任务跟踪
a.功能说明
自行实现任务跟踪机制。
b.代码示例
---
package main
import (
"fmt"
"sync"
"time"
"github.com/roylee0704/gron"
)
type TaskInfo struct {
Name string
Interval time.Duration
ExecCount int
LastExec time.Time
mu sync.Mutex
}
func (t *TaskInfo) Record() {
t.mu.Lock()
defer t.mu.Unlock()
t.ExecCount++
t.LastExec = time.Now()
}
func (t *TaskInfo) Stats() string {
t.mu.Lock()
defer t.mu.Unlock()
return fmt.Sprintf("%s: 执行%d次, 最后执行:%s",
t.Name, t.ExecCount, t.LastExec.Format("15:04:05"))
}
func main() {
c := gron.New()
task1 := &TaskInfo{Name: "任务1", Interval: 2 * time.Second}
task2 := &TaskInfo{Name: "任务2", Interval: 5 * time.Second}
c.AddFunc(gron.Every(task1.Interval), func() {
task1.Record()
fmt.Println(task1.Stats())
})
c.AddFunc(gron.Every(task2.Interval), func() {
task2.Record()
fmt.Println(task2.Stats())
})
c.Start()
defer c.Stop()
time.Sleep(15 * time.Second)
}
---
4.5 任务状态
01.执行状态
a.运行中
任务正在执行。
b.等待中
任务等待下次触发。
02.状态监控
a.功能说明
监控任务执行状态。
b.代码示例
---
package main
import (
"fmt"
"sync/atomic"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
var running int32
c.AddFunc(gron.Every(2*time.Second), func() {
atomic.StoreInt32(&running, 1)
fmt.Println("任务开始执行")
time.Sleep(1 * time.Second)
fmt.Println("任务执行完成")
atomic.StoreInt32(&running, 0)
})
c.Start()
defer c.Stop()
// 监控任务状态
go func() {
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
for range ticker.C {
if atomic.LoadInt32(&running) == 1 {
fmt.Println(" [状态] 任务运行中...")
}
}
}()
time.Sleep(10 * time.Second)
}
---
4.6 并发控制
01.并发执行
a.独立goroutine
每个任务在独立goroutine执行。
b.无并发限制
Gron不限制并发数量。
02.并发控制示例
a.功能说明
使用channel控制任务并发。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
// 使用channel限制并发
sem := make(chan struct{}, 2) // 最多2个并发
c.AddFunc(gron.Every(1*time.Second), func() {
sem <- struct{}{} // 获取信号量
defer func() { <-sem }() // 释放信号量
fmt.Printf("[%s] 任务开始\n", time.Now().Format("15:04:05"))
time.Sleep(3 * time.Second)
fmt.Printf("[%s] 任务完成\n", time.Now().Format("15:04:05"))
})
c.Start()
defer c.Stop()
time.Sleep(15 * time.Second)
}
---
5 高级特性
5.1 单例模式
01.功能说明
a.高级特性
Gron的单例模式功能。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
c.AddFunc(gron.Every(1*time.Minute), func() {
fmt.Println("单例模式任务执行")
})
c.Start()
defer c.Stop()
select {}
}
---
5.2 任务链
01.功能说明
a.高级特性
Gron的任务链功能。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
c.AddFunc(gron.Every(1*time.Minute), func() {
fmt.Println("任务链任务执行")
})
c.Start()
defer c.Stop()
select {}
}
---
5.3 延迟执行
01.功能说明
a.高级特性
Gron的延迟执行功能。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
c.AddFunc(gron.Every(1*time.Minute), func() {
fmt.Println("延迟执行任务执行")
})
c.Start()
defer c.Stop()
select {}
}
---
6 实战应用
6.1 安装配置
01.应用场景
a.实战案例
Gron在安装配置中的应用。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
c.AddFunc(gron.Every(1*time.Hour), func() {
fmt.Println("安装配置任务执行")
})
c.Start()
defer c.Stop()
select {}
}
---
6.2 数据备份
01.应用场景
a.实战案例
Gron在数据备份中的应用。
b.代码示例
---
package main
import (
"fmt"
"time"
"github.com/roylee0704/gron"
)
func main() {
c := gron.New()
c.AddFunc(gron.Every(1*time.Hour), func() {
fmt.Println("数据备份任务执行")
})
c.Start()
defer c.Stop()
select {}
}
---