本文详解 go 中使用 robfig/cron 库实现定时任务的正确姿势,重点解决程序启动后立即退出、cron 表达式误用及进程常驻问题,并提供可运行的完整示例与关键注意事项。
在 Go 中使用 github.com/robfig/cron(v2 及以下版本,注意:该库已归档,推荐生产环境迁移到 github.com/robfig/cron/v3 或 github.com/go-co-op/gocron)实现定时任务时,一个常见误区是:调用 c.Start() 后未保持主 goroutine 活跃,导致程序瞬间退出,定时器根本来不及触发。
例如原始代码中:
c.Start() // 启动调度器,但 main 函数随即结束
此时 main 函数执行完毕,整个进程终止,即使 cron 已启动也无济于事。
首先,修正 Cron 表达式:原 "1 * * * * *" 表示「每分钟第 1 秒执行」(即每 60 秒一次),而非「每秒执行」。若需每秒触发,请使用六字段格式的 * * * * * *(robfig/cron v2 默认支持秒级,字段顺序为:秒 分 时 日 月 周)。
其次,必须让 main 函数持续运行。推荐方式是监听系统中断信号(如

package main
import (
"fmt"
"os"
"os/signal"
"time"
"github.com/robfig/cron"
)
func main() {
c := cron.New()
// ✅ 每秒执行一次(六位表达式)
c.AddFunc("* * * * * *", RunEverySecond)
// ✅ 在 goroutine 中启动 cron,避免阻塞 main
go c.Start()
// ✅ 等待 OS 信号(如 SIGINT/Ctrl+C),防止程序退出
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt, os.Kill)
<-sig // 阻塞在此,直到收到信号
fmt.Println("Shutting down...")
c.Stop() // 可选:优雅停止调度器
}
func RunEverySecond() {
fmt.Printf("[%s] Tick!\n", time.Now().Format("15:04:05"))
}运行上述代码后,你将看到每秒输出一行时间戳,按下 Ctrl+C 即可安全退出。这正是构建可靠定时任务服务的基础范式。