beego 定时任务需在 main() 中、beego.run() 前调用 beego.beeapp.addtask 注册并显式调用 beego.beeapp.starttask() 启动,使用 6 字段 cron 表达式,无运行时启停 api,不适用于高可靠场景。

Beego 的定时任务用 beego.BeeApp.AddTask 注册就行,但必须在 main() 里调用且早于 beego.Run()
Beego 自带的定时任务能力基于 github.com/beego/beego/v2/core/scheduler,不是独立进程,而是嵌入主服务的 goroutine。常见错误是把 AddTask 写在某个 controller 里——它根本不会执行,因为 scheduler 只在启动阶段扫描一次注册列表。
正确做法是在 main.go 的 main() 函数中、beego.Run() 之前完成注册:
beego.BeeApp.AddTask("sync_user_cache", "0 */30 * * * ?", func() { /* 每30分钟执行 */ })- 时间表达式用 Unix cron 格式(6字段),注意 Beego 不支持秒级字段的别名如
@every 30m,必须写成"0 */30 * * * ?" - 任务名(第一个参数)必须全局唯一,重复会导致 panic
- 函数体里不要阻塞,避免拖垮整个 scheduler;耗时操作建议用
go func() {...}()异步处理
多任务共存时,beego.BeeApp.StartTask() 必须显式调用
Beego 默认不自动启动 scheduler,即使你注册了任务,不手动触发也不会跑。很多项目上线后发现定时任务“没反应”,就是漏了这一步。
在 main.go 中 beego.Run() 之前加一行:
beego.BeeApp.StartTask()
注意:StartTask() 是幂等的,多次调用无副作用;但它必须在所有 AddTask 之后、Run() 之前 —— 否则会漏掉刚注册的任务。
停止或删除已注册任务只能靠重启,没有运行时 API
Beego 的 scheduler 没有提供 RemoveTask 或 StopTask 方法。如果你需要动态启停,得自己封装一层:用 sync.Once 控制首次启动,用 context.WithCancel 包裹任务逻辑,在外部控制 cancel 函数。
典型陷阱:
- 试图在 controller 里调用
beego.BeeApp.StopTask("xxx")→ 方法不存在,编译失败 - 改了 cron 表达式但没重启服务 → 旧表达式继续生效
- 任务 panic 后 scheduler 不会自动恢复,后续同名任务将被跳过(日志里只报错,不终止进程)
生产环境别依赖 Beego 内置 scheduler 做关键任务
它的设计目标是轻量、够用,不是高可靠调度器。比如:
- 单实例运行,集群部署时多个副本会重复执行同一任务
- 无持久化,进程崩溃后未执行的任务直接丢失
- 无执行历史记录,排查“某次没跑”只能翻日志
真正要保障的后台任务(如支付对账、报表生成),应该拆出去用专门的调度系统,比如 asynq + Redis,或者用 Kubernetes CronJob。Beego 内置方案只适合开发期验证逻辑、或非关键的缓存刷新类任务。











