请问下在负载均衡下定时任务被执行多次这个问题怎么破?

rock_turf 发布于 2018/01/09 10:01
阅读 951
收藏 2

我现在用的定时任务是Spring的@Scheduled,每天凌晨两点会触发一次。现在的问题是,项目正式环境是nginx负载均衡,这个定时任务会被执行两次。我找了一些解决办法,但实现起来都不那么容易,比如说:

1.验证ip,只允许一台nginx执行,如果非指定ip则返回。这个问题在于如果线上指定nginx故障的话,定时任务就无法执行了。

2.数据库增加某表或某字段。第一次执行的时候修改,后面的再来执行会判断。这个问题在于线上的数据库对字段的增删改是很严谨的,从测试到执行一套流程没那么容易。线上数据库多而且杂,不会轻易修改数据库。

还有没有其他方法能做到只让这个定时任务执行一次的方法么?

加载中
0
JPer
JPer

分布式锁可以实现调度逻辑,具体实现可以使用redis、mc、数据库等,如果服务不重要的话,你单独抽出来一台机器搞Scheduled服务也可以;

0
y
youngkun
使用quartz 数据库模式,完美解决
0
kakai
kakai

quartz 集群模式是基于数据库实现的,它内部好像有这种问题的解决方案,你可以试试。分布式锁也能实现,不过锁只是让执行逻辑等待,并不能执行完一次后面被锁住的就不执行了,所以用锁解决还是有些细节要处理的。

JPer
JPer
说得对,有任务分发逻辑,类似流水,执行完就没了;不会有重复的任务判断,如果百万级别的任务会有很多无用的判断逻辑;
0
rock_turf
rock_turf

引用来自“BoXuan”的评论

quartz 集群模式是基于数据库实现的,它内部好像有这种问题的解决方案,你可以试试。分布式锁也能实现,不过锁只是让执行逻辑等待,并不能执行完一次后面被锁住的就不执行了,所以用锁解决还是有些细节要处理的。

感谢,问题解决了。会关注下这个知识点。

0
rock_turf
rock_turf

引用来自“JPer”的评论

分布式锁可以实现调度逻辑,具体实现可以使用redis、mc、数据库等,如果服务不重要的话,你单独抽出来一台机器搞Scheduled服务也可以;

感谢,在redis里加一个key,判断这个key就可以了。但可以去查查分布式锁相关知识,感觉这个东西用的会比较多。

JPer
JPer
对的,更好的方案就是区分task和server,task不重复那么server就不重复了,方便扩展而且不需要那么多的判断;
0
f
freezingsky

把任务调度放到一个单独的系统去调用。而不是让业务系统自己调用自己,太危险

0
buglife
buglife

使用quartz,直接支持分布式多节点部署

0
一枚假程序猿
一枚假程序猿
定时任务可以支持集群啊
返回顶部
顶部