在 Go 中实现每周执行一次的任务,可以使用标准库的 time
包结合定时器(Ticker
)或第三方调度库(如 github.com/robfig/cron
)。以下是两种常见方法:
方法1:使用 time.Ticker
(适合简单场景)
通过计算当前时间到下一次目标时间点(如每周一零点)的间隔,启动一个定时器:
package main
import (
"fmt"
"time"
)
func weeklyTask() {
fmt.Println("Executing weekly task at", time.Now())
}
func main() {
// 计算下一个周一零点的时间
now := time.Now()
nextMonday := now.AddDate(0, 0, (8-int(now.Weekday()))%7) // 如果今天是周一,则取下周一
nextMonday = time.Date(nextMonday.Year(), nextMonday.Month(), nextMonday.Day(), 0, 0, 0, 0, nextMonday.Location())
// 等待到目标时间
initialDelay := nextMonday.Sub(now)
if initialDelay <= 0 {
initialDelay += 7 * 24 * time.Hour // 如果已过本周一,延迟到下周
}
timer := time.NewTimer(initialDelay)
defer timer.Stop()
for {
<-timer.C
go weeklyTask() // 执行任务
timer.Reset(7 * 24 * time.Hour) // 重置为下一周
}
}
方法2:使用 cron
库(推荐复杂调度)
第三方库 github.com/robfig/cron/v3
提供更灵活的调度语法:
package main
import (
"fmt"
"github.com/robfig/cron/v3"
)
func weeklyTask() {
fmt.Println("Executing weekly task at", time.Now())
}
func main() {
c := cron.New()
// Cron表达式格式: "秒 分 时 日 月 星期"
// "0"表示周日,"1"表示周一,以此类推
_, err := c.AddFunc("0 */5 * * *", func() {
fmt.Println("每5分钟执行一次")
})
if err != nil {
panic(err)
}
_, err = c.AddFunc("0 */30 * * *", func() {
fmt.Println("每30分钟执行一次")
})
if err != nil {
panic(err)
}
c.Start()
defer c.Stop()
select {} //阻塞主线程
}
关键点
- 时区处理:确保
time.Location()
与你的目标时区一致。 - 任务隔离:长时间运行的任务建议用
goroutine
避免阻塞调度。 - 容错机制:添加日志和异常恢复逻辑(如
defer+recover
)。
如果需要动态调整调度计划或分布式环境支持,可考虑更强大的框架(如 gocron
、celery-go
)。
内容由零声教学AI助手提供,问题来源于学员提问