唯一可用的是 github.com/robfig/cron/v3,它修复了 panic、时区混乱、跨月漏触发等问题,但需显式启用 cron.withseconds() 支持秒级调度,且必须六段格式(秒分时日月周)、手动调用 start() 并阻塞主 goroutine。

robfig/cron/v3 是唯一还能用的“robfig/cron”
别再 import github.com/robfig/cron —— 它早在 2021 年就被作者标记为 archived,且不兼容 Go 1.21+。你现在能安全用的,只有 github.com/robfig/cron/v3(由社区维护的 fork)。它修复了原版 panic 崩溃、时区混乱、跨月漏触发等致命问题,但仍是“能用”,不是“推荐”。
-
go get github.com/robfig/cron/v3是唯一正确的安装命令;github.com/robfig/cron(无版本后缀)会拉取已归档的老版本,上线即踩坑 - v3 默认 parser 是 5 段(分时日月周),想用秒级必须显式传
cron.WithSeconds(),否则"*/5 * * * * *"直接解析失败 - v3 的
cron.New()返回*cron.Cron,和老版同名但类型不兼容,混用会导致编译报错或运行时 panic
秒级表达式必须六段,且顺序是“秒分时日月周”
Linux crontab 是五段(分时日月周),而启用 cron.WithSeconds() 后,v3 要求严格六段,顺序固定为:秒、分、时、日、月、周。写错字段数或顺序,任务永远不触发。
- 正确示例:
"*/10 * * * * *"(每 10 秒)、"0 */5 * * * *"(每 5 分钟的第 0 秒) - 错误写法:
"0 */5 * * *"(少一段,静默失败)、"* * */5 * * *"(把“每 5 小时”误写在日位,实际是“每 5 天”) - 空格敏感:
"0 0 * * * *"(两个连续空格)也会解析失败,建议用 linter 或cron.ParseStandard()提前校验
必须手动 Start() + 阻塞主 goroutine,否则任务不执行
cron.New() 只是构造调度器,AddFunc() 只是注册任务——两者都不启动调度。没调 .Start(),或调了但 main 函数立刻退出,任务就永远不会跑。
在 Golang 中使用 samber/hot 进行内存缓存,支持 LRU、LFU、TinyLFU、W‑TinyLFU、S3FIFO、ARC、TwoQueue、SIEVE、FIFO 等淘汰算法,提供 TTL、缓存加载器及分片功能。
- 常见静默失败场景:用
log.Fatal(c.Start()),错误被吞掉;或忘记select {}/signal.Notify,程序启动即退出 - 推荐阻塞方式:
sig := make(chan os.Signal, 1); signal.Notify(sig, os.Interrupt); ,比 <code>select {}更可控 - 务必配
defer c.Stop(),否则进程退出时可能残留 goroutine 或 ticker 资源
robfig/cron/v3 不适合高并发或长耗时任务
它底层靠 ticker 遍历所有 job 判断是否该触发,没有时间轮或最小堆,job 数量超 100 个或单次执行超 1s,就会明显漂移甚至漏触发。
- 耗时任务必须异步:
go func() { doHeavyWork() }(),否则阻塞整个调度循环 - 防止单点 panic 拖垮全局:用
cron.WithChain(cron.Recover(cron.DefaultLogger)) - 如果只是“每 30 秒查健康状态”,直接用
time.Ticker更轻量;如果要“每月 1 号凌晨 2 点发报表”,就得换gocron或自己算time.Until()
robfig/cron/v3 的真实定位是:过渡期兼容老 cron 表达式的轻量替代品,不是生产级调度底座。真正要上规模,时区、并发、可观测性、动态启停这些能力,它都靠不住。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










