Go 实现定时任务有多种方式,每种方式都有其适用的场景。下面是一些常见的实现方法:
1、使用 time.Ticker
time.Ticker
是 time
包提供的一个结构体,它会在一个指定的时间间隔重复执行某个任务。有两种使用方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package main import ( "fmt" "time" ) func main () { ticker := time.NewTicker(2 * time.Second) defer ticker.Stop() done := make (chan bool ) go func () { for { select { case <-done: return case t := <-ticker.C: fmt.Println("Tick at" , t) } } }() time.Sleep(10 * time.Second) done <- true }
或者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package main import ( "fmt" "time" ) func main () { ticker := time.NewTicker(1 * time.Minute) defer ticker.Stop() for range ticker.C { fmt.Println("Doing something..." ) } }
2、使用 time.AfterFunc
time.AfterFunc
可以在指定的时间间隔后执行一次性的定时任务。它接受两个参数,第一个参数是等待的时间间隔,第二个参数是待执行的函数。如果你想重复执行,可以在函数内部再次调用 time.AfterFunc
,和轮训一样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package main import ( "fmt" "time" ) func doSomething () { fmt.Println("Doing something..." ) } func main () { var tick func () tick = func () { fmt.Println("Tick at" , time.Now()) time.AfterFunc(1 *time.Second, tick) } time.AfterFunc(1 *time.Second, tick) time.Sleep(10 * time.Second) fmt.Println("Done!" ) }
注意:通常不推荐在time.AfterFunc
中使用立即延迟(如time.AfterFunc(0, doSomething)
),因为这将导致每次调用都创建一个新的定时器,这不是最佳实践。更好的做法是直接调用函数或者在另一个 goroutine 中调用doSomething
。
3、使用cron
包(第三方库) 如果你需要更复杂的定时任务调度,比如按照 cron 表达式执行任务,可以使用第三方库如 robfig/cron
。首先需要安装这个包:
1 go get github.com/robfig/cron/v3
然后你可以这样使用它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package main import ( "fmt" "github.com/robfig/cron/v3" ) func main () { c := cron.New() c.AddFunc("*/5 * * * *" , func () { fmt.Println("Running task every 5 minutes" ) }) c.Start() }
使用第三方库可以让你更灵活地安排复杂的定时任务。例如,你可以按照特定的时间表(如每天的特定时间、每周的特定天等)来安排任务。