栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

@ScedulerLock踩坑

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

@ScedulerLock踩坑

背景:我们需要做一个分布式定时任务,定时给用户发短信,设计思路是用@SchedulerLock做分布式定时任务,任务是从每次从数据库查询1000条用户数据,并异步发送短信,发送完成后在数据库里记录发送信息,@Schedule配置为@Scheduled(cron = “0/5 0/1 10-17 * * ?”),@SchedulerLock配置为 @SchedulerLock(name = SCHEDULE_MODEL_NAME + “ticketRemind”, lockAtLeastFor = “PT5S”, lockAtMostFor = “PT10S”)

问题:我们发现有用户收到两条相同的短信,且间隔时间1s

排查思路:先查看数据库,发现确实有对相同用户发送两条短信的记录,且间隔时间为1s,并且同一批1000个用户,每个用户都发送了两次,随后查询系统日志,发现任务确实如@Scheduled配置每5s执行一次,如果获取不到分布式锁,就在下一个5s执行,查询问题前后的日志,发现在11:03:25的定时任务在11:03:37才处理完,同时在11:03:35又开始了新的定时任务,因此可以推断出,由于我们的lockAtMostFor设置只有10s,因此当任务处理时间超过10s时,该任务处理节点就会放弃分布式锁,其他节点可以获得该分布式锁,由于前一个任务还没有处理完成,数据库里还没有任务完成的记录,因此会导致下一个节点执行相同的任务。

解决办法:
1.保证任务不可重复执行
由于我们的业务需要在任务确实处理完成后,才能记录完成信息,不能保证不可重复执行,因此需要想其他办法
2.增大lockAtMostFor 时间
无法百分之百地保证任务不会重复执行,但是能大大降低任务重复执行的概率

思考:如果不设置lockAtMostFor ,知道任务处理完成才释放锁,那么当该节点出现问题时,锁可能就会一直锁住,无法让出锁给其他节点处理,显然不合适,而设置了就可能会出现任务重复执行的问题,不知道@SchedulerLock能不能在超时的时候回滚任务或者跳过该任务

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/770486.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号