分布式多机集群环境下定时任务只执行一次

导读:本篇文章讲解 分布式多机集群环境下定时任务只执行一次,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

当我们有多个服务器,每个服务器上都有相同的定时任务代码时,比如每天凌晨定时插入数据。

如果多个服务器上的定时任务都执行了会导致数据的重复;

如果只让一个服务器有定时代码,部署麻烦,需要多套代码,万一该机器挂了就完犊子了。

一般解决办法有如下几种:

数据库实现;2. 基于Redis的分布式锁;3. 基于ZooKeeper的分布式锁;4.利用quartz集群分布式

1.数据库实现

(1)数据库建立一个表,用来记录uuid(或ip)和插入时间;

(2)当多个服务器执行定时任务的时候先生成个uuid把uuid(或服务器ip)和当前时间插入表里;

(3)表中查询当天最早的插入时间那条记录返回,与uuid(或服务器自己的ip)对比;

(4)若服务器自己的uuid(或ip)与数据库查询的uuid(ip)匹配则执行,不匹配则不执行;

2.使用Shedlock库

Shedlock库可以确保你的定时任务最多同时执行一次。如果一个任务正在一个节点上执行,它会获取一个锁,以防止从另一个节点(或线程)执行相同的任务。
Shedlock库的github地址:Shedlock
示例:

2.1 对于spring或者springboot项目:

@Scheduled(cron = "0 */15 * * * *")
@SchedulerLock(name = "scheduledTaskName")
public void scheduledTask() {
   // do something
}

2.2 对于没有使用框架的项目:

LockingTaskExecutor executor = new DefaultLockingTaskExecutor(lockProvider);
     ...
Instant lockAtMostUntil = Instant.now().plusSeconds(600);
executor.executeWithLock(runnable, new LockConfiguration("lockName", lockAtMostUntil));

3.Redis的分布式锁实现

(1) 每个服务器生成随机uuid

(2) 利用redis的Setnx命令将随机uuid作为value存入redis

(3) 获取redis的value,与生成的随机uuid对比;

(4) value与生成的随机uuid匹配则执行,不匹配则不执行;


参考:
Spring Scheduled Task running in clustered environment
How can you make a cluster run a task only once
集群服务器定时任务重复执行的解决方案
Redis分布式锁解析
分布式环境下定时任务如何做到只执行一次

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/80267.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!