服务部署了多个实例,定时任务怎样保证只执行一次?
先自己想一想,再看参考要点
参考要点
- 每个实例都有自己的调度器,到点时会各自执行一次,例如每个用户收到两条账单短信
- 简单的做法是到点时抢一把分布式锁,抢不到就跳过,锁的键对应这一次触发(例如带上账单月份),执行完也不删除、等它过期,避免时钟慢的实例再执行一遍
- 也可以在执行记录表的 (job_name, fire_time) 上建唯一索引,插入成功的实例执行
- XXL-JOB 这类调度中心把触发和执行分开,多个调度节点用 SELECT ... FOR UPDATE 抢锁,同一次触发只发出一次
- 数据量大时用分片广播按 ID 取模分摊到各实例,失败时只重试失败的分片,任务本身仍要做到幂等