在使用GoFrame开发后台服务时,我们经常需要实现一些定时任务,比如:
- 每天凌晨进行一些数据统计和分析
- 定期清理过期的缓存数据
- 定时发送一些通知消息
- 定期执行一些数据备份
这些定时任务可以通过在代码中直接使用原生的time包、ticker来实现。不过GoFrame框架提供了一个gron模块,封装了更加简洁友好的定时任务API。下面我们具体看看如何使用。 首先在项目目录下执行:
go get github.com/gogf/gf/v2/os/gcron
安装gron模块。
然后在代码中这样使用:
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gcron"
"time"
)
func main() {
ctx := gctx.New()
gcron.Add(ctx,"0 30 * * * *", func(ctx context.Context) {
g.Log().Info(ctx,"Every hour on the half hour")
})
gcron.Add("15 * * * * *", func(ctx context.Context) {
g.Log().Info(ctx,"Every 15 seconds")
})
gcron.Add("@hourly", func(ctx context.Context) {
g.Log().Info(ctx,"Every hour")
})
gcron.Add("@every 1h30m", func(ctx context.Context) {
g.Log().Info(ctx,"Every hour thirty")
})
g.Log().Info(ctx,"cron started")
select {}
}
gcron.Add方法用于添加定时任务,第一个参数是cron表达式,第二个参数是任务执行的函数。
cron表达式语法类似linux的crontab,从左到右分别表示:秒 分 时 日 月 星期
上面的例子中:
- "0 30 * * * *" 表示每个小时的第30分钟(每小时执行一次)
- "15 * * * * *" 表示每隔15秒执行一次
- "@hourly"是预定义的宏,等同于"0 0 * * * *",表示每小时执行一次
- "@every 1h30m"表示每隔1小时30分钟执行一次 除了使用gcron.Add动态添加任务,还可以将任务配置在配置文件中,例如:
cron:
cron.job:
- name: "task1"
spec: "0 30 * * * *"
command: "task1Command"
- name: "task2"
spec: "@every 1h30m"
command: "task2Command"
可见,gron模块提供了简洁的API来管理定时任务,支持cron表达式、预定义的时间间隔宏等多种定义方式,也可以集成到GoFrame的配置管理中,是开发后台定时任务的利器。
处理执行失败
在处理定时任务时,我们需要考虑任务执行失败的情况。定时任务执行失败的原因可能有:
- 任务本身的代码逻辑有bug,比如空指针异常、数组越界等。
- 任务依赖的外部资源出现问题,比如网络中断、数据库连接失败等。
- 任务执行时间过长,超过了预期的时间。
在任务执行函数中添加recover机制
在gron定时任务的执行函数中,我们可以通过defer+recover机制来捕获任务执行过程中的panic异常,避免panic导致进程崩溃:
gcron.Add(ctx,"0 30 * * * *", func(ctx context.Context) {
defer func() {
if err := recover(); err != nil {
// 记录错误日志
g.Log().Errorf("panic recovered: %v", err)
}
}()
// 任务逻辑
// ...
})
为任务设置超时时间
如果定时任务执行时间过长,超过了预期时间,可能会影响到其他任务的执行,或者占用过多系统资源。
任务执行失败重试
有些任务执行失败后,我们希望能够自动重试执行,直到成功为止。
任务执行失败告警通知
对于一些非常重要的定时任务,我们可能需要在任务执行失败时及时收到告警通知,以便快速排查问题。可以在任务执行函数中添加失败告警通知逻辑,例如:
gcron.Add(ctx,"0 30 * * * *", func(ctx context.Context) {
defer func() {
if err := recover(); err != nil {
g.Log().Errorf("panic recovered: %v", err)
// 发送告警通知,如邮件、短信、微信等
sendAlertNotification(err)
}
}()
// 任务逻辑
// ...
})
定期检查任务执行状态
我们可以为gron设置一个统计日志的输出函数,定期输出各个任务的执行情况统计信息,包括成功次数、失败次数、执行时间等,以便我们及时了解任务的执行状态.
总结
在使用GoFrame框架中的gron模块实现定时任务时,我们可以通过简洁的API来管理任务。同时,为了提高任务的可靠性,我们需要处理任务执行失败的情况。通过添加recover机制、设置超时时间、重试策略、告警通知以及定期检查任务状态,我们可以更好地监控和优化定时任务的执行,确保系统的稳定性。