在Go语言里,实现定时任务有多种方式,下面为你介绍几种常见的方法及其示例代码。
1. 使用time.Ticker
(固定间隔执行)
这是实现定时任务最简单的方法,适合用于需要周期性执行的任务。
package main
import (
"fmt"
"time"
)
func main() {
// 创建一个每3秒触发一次的Ticker
ticker := time.NewTicker(3 * time.Second)
defer ticker.Stop() // 程序结束时停止Ticker
// 创建一个用于终止的通道
done := make(chan bool)
// 启动一个goroutine执行定时任务
go func() {
for {
select {
case <-done:
return
case t := <-ticker.C:
fmt.Println("执行定时任务,当前时间:", t)
// 在这里编写具体的任务逻辑
}
}
}()
// 让主程序运行15秒后退出
time.Sleep(15 * time.Second)
done <- true
fmt.Println("程序退出")
}
这个程序会每隔3秒执行一次任务,15秒后自动退出。
2. 使用time.Timer
(延迟执行单次任务)
若你只需要执行一次延迟任务,time.Timer
是个不错的选择。
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("程序启动")
// 创建一个5秒后触发的Timer
timer := time.NewTimer(5 * time.Second)
// 等待Timer触发
<-timer.C
fmt.Println("5秒后执行此任务")
// 也可以使用time.Sleep实现相同效果
// time.Sleep(5 * time.Second)
// fmt.Println("5秒后执行此任务")
}
3. 使用第三方库robfig/cron
(支持Cron表达式)
对于复杂的定时任务需求,推荐使用robfig/cron
库,它支持类似Unix Cron的表达式。
首先需要安装该库:
go get github.com/robfig/cron/v3
以下是使用示例:
package main
import (
"fmt"
"log"
"github.com/robfig/cron/v3"
)
func main() {
// 创建一个新的cron调度器
c := cron.New()
// 添加任务到调度器
// 格式:秒(可选) 分 时 日 月 周
_, err := c.AddFunc("0 */5 * * * *", func() { // 每5分钟执行一次
fmt.Println("执行每5分钟任务")
})
if err != nil {
log.Fatalf("添加任务失败: %v", err)
}
_, err = c.AddFunc("0 0 * * * *", func() { // 每小时执行一次
fmt.Println("执行每小时任务")
})
if err != nil {
log.Fatalf("添加任务失败: %v", err)
}
// 启动调度器
c.Start()
defer c.Stop() // 程序结束时停止调度器
// 让主程序保持运行
select {}
}
Cron表达式的格式为:秒(可选) 分 时 日 月 周
,例如:
0 0 * * * *
:每小时执行一次0 */5 * * * *
:每5分钟执行一次0 0 12 * * *
:每天中午12点执行0 0 0 * * 0
:每周日午夜执行
4. 带错误处理的定时任务
在实际应用中,通常需要对任务执行过程中可能出现的错误进行处理。
package main
import (
"fmt"
"log"
"time"
)
func main() {
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()
done := make(chan bool)
go func() {
for {
select {
case <-done:
return
case <-ticker.C:
if err := performTask(); err != nil {
log.Printf("任务执行失败: %v", err)
// 可以添加重试逻辑或其他错误处理
}
}
}
}()
time.Sleep(30 * time.Second)
done <- true
fmt.Println("程序退出")
}
// 模拟一个可能会出错的任务
func performTask() error {
// 任务逻辑...
fmt.Println("执行任务")
// 模拟错误
// return fmt.Errorf("模拟任务执行失败")
return nil
}
总结
- 若任务逻辑简单且执行间隔固定,可直接使用
time.Ticker
。 - 对于复杂的调度需求,建议使用
robfig/cron
库。 - 在生产环境中,还需要考虑任务执行失败的重试机制、并发控制以及日志记录等方面。