定时任务需结构化记录状态与耗时并做趋势分析:每次执行写scheduled记录,结束更新status、duration_ms、error_code等字段;用sql查p95突增、连续失败;grafana可视化+动态基线告警。

定时任务执行状态和耗时不能只靠“跑没跑”来判断,得有结构化记录和持续趋势分析——一次慢是偶然,连续三次变慢就是问题信号。
状态与耗时必须同步记录
光记成功或失败不够,状态变更必须带时间戳、上下文和结果细节:
- 每次任务启动写一条 scheduled 记录,含计划触发时间、实际开始时间、分配的 worker ID;
- 执行结束时更新为 success / failed / timeout,同时写入耗时(毫秒)、错误摘要(如 MySQL 连接超时)、重试次数;
- 失败任务额外提取堆栈前 3 行和关键变量值(比如处理的订单 ID、批次大小),避免日志里大海捞针。
数据库表设计要支撑趋势分析
用一张轻量但字段完整的表长期存档,例如:
- task_name(varchar,索引):方便按任务名聚合;
- executed_at(datetime):精确到秒,用于时间范围筛选;
- duration_ms(int):整型存毫秒,避免浮点精度问题;
- status(enum 或 tinyint):便于统计成功率;
- error_code(varchar):标准化错误码(如 DB_CONN_TIMEOUT、HTTP_503),比纯文本更易聚合分析;
- trace_id(varchar):用于关联日志和调用链,查问题时一键拉取全路径。
用 SQL 快速看趋势和异常
不需要复杂 BI 工具,日常运维靠几条查询就能定位问题:
- 查最近 7 天各任务平均耗时变化:
SELECT task_name, DATE(executed_at) d, ROUND(AVG(duration_ms), 0) avg_ms FROM task_log WHERE executed_at > DATE_SUB(NOW(), INTERVAL 7 DAY) GROUP BY task_name, d ORDER BY d, avg_ms DESC; - 找 P95 耗时突增的任务:
SELECT task_name, PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY duration_ms) p95_ms FROM task_log WHERE executed_at > DATE_SUB(NOW(), INTERVAL 24 HOUR) GROUP BY task_name HAVING p95_ms > (SELECT PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY duration_ms) FROM task_log WHERE executed_at BETWEEN DATE_SUB(NOW(), INTERVAL 48 HOUR) AND DATE_SUB(NOW(), INTERVAL 24 HOUR)); - 统计连续失败任务:
SELECT task_name, COUNT(*) fail_cnt FROM task_log WHERE status = 'failed' AND executed_at > DATE_SUB(NOW(), INTERVAL 1 HOUR) GROUP BY task_name HAVING fail_cnt >= 3;
可视化不是可选项,而是必选项
把数据变成图形,才能一眼识别规律:
- 用 Grafana 做三张基础面板:「每小时任务总数」、「各任务 P95 耗时折线图」、「失败率热力图(按小时+任务名)」;
- 给每个任务设置动态基线——比如过去 7 天平均耗时 ×1.8 作为告警阈值,比固定值(如 30s)更适应业务波动;
- 失败率超过 5% 或 P95 耗时突破基线时,自动推送企业微信/钉钉消息,并附上最近一次失败的 trace_id 链接。










