分布式定时任务
问题描述
在做springboot项目的时候,需要定时做对账任务。但因为项目是集群部署,就存在多个pod实例的定时任务同时运行,存在重复性。怎么保证集群中不重复地完成定时任务?下面给出本人总结的方案。
解决方案
对账任务表(merchant)
id | name | is_done(是否对账,0没有对账) |
---|---|---|
1 | 商家1 | 0 |
2 | 商家2 | 0 |
3 | 商家3 | 0 |
4 | 商家4 | 0 |
5 | 商家5 | 0 |
1.现开启3个pod去同时运行定时任务
2.每个pod 都去查是否存在没有对账的商家,存在则返回最前面的那条记录
;不存在则直接停止定时任务
select * from merchant limit 0,1 where is_done = 0
3.创建一张临时表(check_lock),实现分布式锁
name | 描述 | 约束 |
---|---|---|
id | 主键id | |
merchant_id | 商家id | 唯一性约束 |
task_id | 主键id |
其中id为主键,merchant_id 添加唯一性约束
。
4.假如三个任务都查到是商家1
,则三个任务都去往临时表插入一条数据,如下表,表示任务2抢到了商家1的对账任务。假如其他任务也想往临时表插入,会因为merchant_id
存在唯一性约束
,导致插入不成功。
INSERT INTO check_lock (check_id, task_id) VALUES ('1', '2');
id | merchant_id | task_id |
---|---|---|
1 | 1 | 2 |
5.其他插入不成功的任务,继续查询数据表中,是否还存在没对账的商家,存在则继续步骤1,不存在则直接停止定时任务。