鲁棒性定时任务设计7条准则
目录
1 定时任务执行过程可追溯设计
需要知道定时任务跑了没有,跑了多久,跑成功了,还是跑失败了。这些过程数据作为重跑的依据
需要跟进内容:
定时任务执行结果,是成功,失败,还是重试中。 一般重试N次后,状态变为失败。处于失败的定时任务需要监控告警
任务启动时间和结束时间,方便用来跟进定时任务的执行时间,方便做一些性能优化,或者很多任务需要合理编排任务的启动时间。
已重试的次数:用来了解失败的原因
任务处理的数据日期:根据该天的任务有没有执行,一般一天只有一个 任务处理的数据日期
2. 大数据量需分片处理(分布式调度)
分布式计算(分片技术)
断点续跑
解决:定时任务做最小粒度事务控制,并记录状态。比如计息,每个人每天是最小粒度, 完成一条记录一条的状态,挂了重跑,从没跑的地方继续执行。
3. 定时任务的依赖处理,避免上一个没有跑完,下一个却跑了。
问题:上一个没跑完,下个就跑了,或者上一个跑失败了,下一个也跑了。
解决:
1 合并定时任务
2 使用定时任务依赖链。链条中一个失败或者没有跑完,后面不能跑。如使用Airflow构建DAG
4 支持手动重跑(支持最小粒度的重试)
CREATE TABLE task_execution_logs (
-- 基础信息
id BIGSERIAL PRIMARY KEY,
task_name VARCHAR(128) NOT NULL, -- 任务名称(如 'daily_city_transaction_agg')
execution_date DATE NOT NULL, -- 任务处理的数据日期(如 '2023-10-01')
start_time TIMESTAMP NOT NULL, -- 任务启动时间
end_time TIMESTAMP, -- 任务结束时间
execution_status VARCHAR(32) NOT NULL, -- 状态(RUNNING/SUCCESS/FAILED/RETRYING)
retry_count INT DEFAULT 0, -- 已重试次数
-- 业务上下文
processed_cities JSONB, -- 已处理的城市列表(用于断点续跑),不同业务不一样
total_cities INT, -- 总需处理城市数
success_cities INT, -- 成功处理城市数
failed_cities JSONB, -- 失败城市及原因(如 [{"city": "上海", "error": "超时"}])
-- 系统信息
executor_node VARCHAR(64), -- 执行节点标识(IP 或容器ID)
error_message TEXT, -- 错误堆栈信息
parameters JSONB -- 任务参数(如分片策略、重试配置)
);
5 防止重叠设计
定时任务重叠的分布式锁
问题:redis定时任务锁,超时时间不好控制,设置太短没效果,太长影响后续的执行。如何实现,当任务有异常的时候解锁,如果任务
没有异常等任务执行完解锁
对于Java项目,推荐直接使用Redisson库的RLock,它内置了看门狗自动续期机制,简化开发:
核心思路
唯一标识锁:使用唯一值(如UUID)作为锁的值,确保只有锁的持有者能释放。
自动续期机制:后台线程定期延长锁过期时间,防止任务未完成时锁自动释放。
主动释放锁:无论任务成功或异常,都在finally块中主动释放锁。
兜底超时:设置合理超时时间作为安全网,防止程序崩溃导致死锁。lock_timeout应大于任务正常执行的最长时间。
RedissonClient redisson = Redisson.create();
RLock lock = redisson.getLock("my_task_lock");
try {
lock.lock(); // 默认30秒超时,看门狗每10秒续期
// 执行任务...
} finally {
lock.unlock();
}
通过态机设计 防止定时任务重叠
-- 在任务表中添加状态锁字段
UPDATE task_scheduler SET status = 'RUNNING'
WHERE task_name = 'daily_city_transaction_agg' AND status = 'PENDING';
-- 执行前抢占锁,成功后执行业务逻辑
6 自动补偿机制(失败重试几次,
- 自动重试:配置框架级重试(如 Spring Retry 或 Celery Retry),设定规则:
- 重试次数:3~5 次,避免无限重试。
- 重试间隔:指数退避(如 1min, 5min, 15min)。
- 人工介入兜底:重试失败后标记任务为
MANUAL_INTERVENTION_NEEDED,触发告警。

浙公网安备 33010602011771号