Go 生态中 Fiber 无定时任务能力,需依赖 robfig/cron/v3 等外部调度器;延时任务须用 Redis ZSET 持久化,避免 goroutine + Sleep;后台任务需配合优雅停机与 WaitGroup 协调生命周期。

Go 生态里没有“Fiber 定时任务”这回事——Fiber 本身不提供定时调度能力,它只管 HTTP 请求生命周期;所有定时、延时、后台任务都得靠外部机制组合实现。别在路由 handler 里写 time.Sleep 或裸起 go func(),那是开发环境能跑、上线就丢任务的陷阱。
robfig/cron/v3 是最稳的定时调度选择
它支持标准 cron 表达式、秒级精度、时区控制和 panic 捕获,是生产环境首选。
- 必须显式启用秒级:
cron.WithSeconds(),否则"0/5 * * * * *"这类六段表达式会直接报cron: invalid time spec - 默认用本地时区,容器环境大概率是 UTC,初始化要写死:
cron.New(cron.WithLocation(time.UTC)) - 每个任务函数开头加
defer func() { if r := recover(); r != nil { log.Printf("task panic: %v", r) } }(),否则一次 panic 就让整个 cron 实例静默退出 -
c.Start()是非阻塞的,主 goroutine 必须保持存活,常见写法是select {}或监听os.Interrupt
Fiber 触发的延时任务不能靠 goroutine + Sleep
HTTP handler 里起 go func() { time.Sleep(5 * time.Minute); doWork() }() 看似简单,但实际不可靠:
- 服务重启时,所有未触发的延时任务彻底丢失(无持久化)
- goroutine 持有闭包变量(如
*sql.DB、log.Logger)可能引发资源泄漏或 panic - 多实例部署下,任务只会在当前机器执行,无法保证唯一性
- 没有失败重试、死信队列、执行记录等运维必需能力
真要延时,得把任务写入 Redis ZSET(score 为 UNIX 时间戳),由独立消费者进程拉取执行;Fiber 只负责接收请求并投递到队列。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
立即学习“go语言免费学习笔记(深入)”;
后台任务需配合优雅停机协调生命周期
服务关闭时,正在运行的定时任务、延时任务、数据库事务不能被粗暴中断。
-
http.Server.Shutdown()不会等待 cron job 或后台 goroutine 结束,得自己用sync.WaitGroup记录活跃任务 - 启动任务前
wg.Add(1),结束时wg.Done();停机流程里调用wg.Wait()阻塞直到全部完成 - 若任务依赖数据库,把 shutdown context 传给
db.BeginTx(ctx, ...)和tx.Commit(ctx),超时自动 rollback - 别在 shutdown 流程中新开 goroutine,
WaitGroup跟踪不到
真正难的不是写个 cron.AddFunc,而是任务失败后怎么补、怎么查、怎么避免重复执行——这些逻辑不会自动出现,得你一条条补全。

















