Beego定时任务需显式调用toolbox.StartTask()才能生效,仅AddTask不触发;必须使用6字段cron表达式(秒分时日月周),并从配置文件安全读取、设默认值、加日志验证。

Beego 的定时任务不是靠 go run 启动后自动生效的——必须显式调用 toolbox.StartTask(),否则哪怕加了 toolbox.AddTask() 也完全不跑。
如何正确加载并启动定时任务
Beego 本身不内置调度器,依赖 github.com/astaxie/beego/toolbox 模块。这个模块已归档(官方不再维护),但仍在大量老项目中使用。启动逻辑有严格顺序:
- 先定义任务:
tk := toolbox.NewTask("name", "0 * * * * *", func() error { ... }) - 再注册:
toolbox.AddTask("name", tk)(注意名字要和 NewTask 一致) - 最后启动:
toolbox.StartTask()—— 必须在beego.Run()之前或之后立即执行,不能漏 - 如果用
tk.Run(),它会立刻同步执行一次,和 cron 表达式无关,仅用于调试
常见错误是只写 AddTask 就以为完事了,结果日志里完全看不到任务触发痕迹。
cron 表达式格式与 Beego 的 6 字段差异
Beego 的 toolbox 使用 6 位 cron 格式(秒 分 时 日 月 周),和 Linux crontab(5 位)不同,容易配错:
-
"* * * * * *":每秒执行(注意不是"* * * * *") -
"0 0 * * * *":每小时整点执行(第 0 秒、第 0 分) -
"0 30 14 * * *":每天 14:30:00 执行 - 星期字段:0 = 周日,1–6 = 周一至周六;
7不合法,*或0-6才有效 - 若表达式解析失败,
toolbox默认静默跳过,不会报错,任务也不会注册成功
从配置文件读取 cron 表达式的安全写法
直接硬编码 cron 表达式不利于运维。推荐从 conf/app.conf 读取,但要注意空值和默认兜底:
- 在
app.conf中加配置项:cron.sync_food = "0 0 */2 * * *" - 代码中读取时必须判空:
cronExpr := beego.AppConfig.String("cron.sync_food") - 空值或读取失败时,不能直接传空字符串给
NewTask,否则 panic;应设默认值:if cronExpr == "" { cronExpr = "0 0 */1 * * *" } - 建议加日志确认:
beego.Info("Loaded cron expr:", cronExpr),避免配置没生效却误以为任务在跑
任务函数签名与错误处理的实际约束
Beego toolbox 要求任务函数返回 error 类型,且不自动重试、不捕获 panic:
- 函数签名必须是:
func() error,不能带参数,不能是func(context.Context) error - 如果任务内 panic,整个 goroutine 会退出,该任务后续不再触发(
toolbox不 recover) - 返回
err != nil仅记日志,不会停止调度,也不会重试——重试需自行实现 - 耗时长的任务(如 HTTP 请求、DB 查询)建议加超时控制,否则会阻塞下一个周期的执行
真正上线时,别只测“能跑”,得测“挂了会不会断”、“配置改错有没有告警”、“日志是否可追溯”——这些才是定时任务最常翻车的地方。


















