springBoot框架分布式部署定时任务重复执行之解决方案
问题描述: 在集群模式部署服务端时,会出现所有的定时任务在各自的节点处均会执行一遍,这显然不符合实际的开发场景,针对这种问题,本文给出一种springboot集成shedlock的解决方案
第一步:引入相关包;
<!-- 负载均衡定时任务执行一次 -->
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-jdbc-template</artifactId>
<version>2.2.1</version>
</dependency>
注意:因为本公司的项目持久化采用的mysql数据库,所以引入的是JDBC数据库进行协调

ShedLock还可以使用Mongo,Redis,Hazelcast,ZooKeeper等外部存储进行协调,例如使用redis则引入下面的包(只尝试过jdbc方式):
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-redis-spring</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
针对不同的协调方式,相关的配置信息可参考https://www.jianshu.com/p/9c6791b617a7
第二步:向数据库中插入表shedlock;
CREATE TABLE shedlock(
NAME VARCHAR(64),
lock_until TIMESTAMP(3) NULL,
locked_at TIMESTAMP(3) NULL,
locked_by VARCHAR(255),
PRIMARY KEY (NAME)
)
第三步:在application.properties中添加数据库配置信息
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.datasource.username=root1
spring.datasource.password=root1
第四步:添加配置类
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
import net.javacrumbs.shedlock.spring.ScheduledLockConfiguration;
import net.javacrumbs.shedlock.spring.ScheduledLockConfigurationBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling; import javax.sql.DataSource;
import java.time.Duration; @Configuration
@EnableScheduling
public class ShedlockConfig { @Bean
public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(dataSource);
} // @Bean
// public TaskScheduler taskScheduler(){
// return new MySpecialTaskScheduler();
// } @Bean
public ScheduledLockConfiguration scheduledLockConfiguration(LockProvider lockProvider) {
return ScheduledLockConfigurationBuilder
.withLockProvider(lockProvider)
.withPoolSize(10)
.withDefaultLockAtMostFor(Duration.ofMinutes(10))
.build();
}
}
第五步:在启动类上添加启动注解,否则SchedulerLock不会生效
@EnableSchedulerLock(defaultLockAtMostFor = "PT50S")
第六步:添加@SchedulerLock到定时器业务方法入口
private static final int TWENTY_NINE_MIN = 29 * 60 * 1000;
@Scheduled(cron = "0 */30 * * * ?")
@SchedulerLock(name = "scheduledTask", lockAtMostFor = TWENTY_NINE_MIN, lockAtLeastFor = TWENTY_NINE_MIN)
public void scheduledTask() {
// System.out.println(new Date() + "scheduledTask执行1次");
}
参数解释:
name属性:锁名称,必须指定,每次只能执行一个具有相同名字的任务,锁名称应该是全局唯一的;
lockAtMostFor属性:设置锁的最大持有时间,为了解决如果持有锁的节点挂了,无法释放锁,其他节点无法进行下一次任务;
lockAtMostForString属性:成功执行任务的节点所能拥有的独占锁的最长时间的字符串表达,例如“PT14M”表示为14分钟
lockAtLeastFor属性:指定保留锁的最短时间。主要目的是在任务非常短的且节点之间存在时钟差异的情况下防止多个节点执行。这个属性是锁的持有时间。设置了多少就一定会持有多长时间,再此期间,下一次任务执行时,其他节点包括它本身是不会执行任务的
lockAtLeastForString属性:成功执行任务的节点所能拥有的独占锁的最短时间的字符串表达,例如“PT14M”表示为14分钟
springBoot框架分布式部署定时任务重复执行之解决方案的更多相关文章
- Spring+quartz集群解决多服务器部署定时器重复执行的问题
一.问题描述 Spring自带的Task虽然能很好使用定时任务,只需要做些简单的配置就可以了.不过如果部署在多台服务器上的时候,这样定时任务会在每台服务器都会执行,造成重复执行. 二.解决方案 Spr ...
- 小程序后端项目【Springboot框架】部署到阿里云服务器【支持https访问】
前言: 我的后端项目是Java写的,用的Springboot框架.在部署服务器并配置https访问过程中,因为做了一些令人窒息的操作(事后发现),所以老是不能成功. 不成功具体点说就是:域名地址可以正 ...
- Laravel是怎样防止你的定时任务重复执行的
基本介绍 有时候一个定时任务执行需要的时间可能会比我们想象的要长,这就会引起一个问题——当前任务还没有执行完毕的时候另一个相同的任务也会执行,从而导致任务重复.例如想象一下我们执行每分钟生成一次报告的 ...
- jemter分布式部署及linux下分布式脚本执行
jmeter进行接口性能测试,占用内存较大,在模拟千万计并发用户时,使用分布式部署进行分压测试. 操作步骤:选择一台机器作为调度机,其他机器作为执行机 一.jmeter分布式部署 前提条件:A.执行机 ...
- 可重复执行的SQL Script
问题 在工作中偶尔会遇到这样的问题:SQL script重复执行时会报错. 理想的状态下,SQL script跑一遍就够了,是不会重复执行的,但是实际情况往往很复杂. 比如Dev同学在开发时在A环境把 ...
- SpringBoot 使用定时任务动态执行任务
import com.patient.core.adapter.CorsFilter; import org.mybatis.spring.annotation.MapperScan; import ...
- 【G】开源的分布式部署解决方案(一) - 开篇
做这个开源项目的意义是什么?(口水自问自答,不喜可略过) 从功能上来说,请参考 预告篇,因自知当时预告片没有任何含金量,所以并没有主动推送到首页,而是私下的给一些人发的. 从个人角度上来说,我希望.n ...
- 【spring-boot】 springboot整合quartz实现定时任务
在做项目时有时候会有定时器任务的功能,比如某某时间应该做什么,多少秒应该怎么样之类的. spring支持多种定时任务的实现.我们来介绍下使用spring的定时器和使用quartz定时器 1.我们使用s ...
- java Spring-Boot框架学习视频-百度云盘
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/lk142500/article/deta ...
随机推荐
- 洛谷P3905 道路重建
题目:https://www.luogu.org/problemnew/show/P3905 分析: 此题是显然的最短路算法,只是看到一起删掉的一堆边感到十分棘手,而且还要求出的是最短添加边的总长度 ...
- Surging实践经验
背景 在去年9月份的时候,我入职一家做航空软件产品的公司.当时公司部门领导决定构建一个技术平台(或称为技术中台),通过该技术平台进而孵化各个业务系统.说白了就是需要通过一个分布式框架或是微服务框架提高 ...
- Ambassador,云原生应用的“门神”
目前,行业内基于云原生思想的开源项目,重点在于管理.控制微服务以及微服务架构下服务之间的通信问题.它们有效的解决了“服务异构化”.“动态化”.“多协议”场景所带来的east/west流量的管控问题,而 ...
- Linux系统安装jdk——.tar.gz版
1.rpm.deb.tar.gz的区别: rpm格式的软件包适用于基于Red Hat发行版的系统,例如Red Hat Linux.SUSE.Fedora. deb格式的软件包则是适用于基于Debian ...
- 【MySQL】(七)事务
我的个人博客 http://www.haxianhe.com/ 数据库系统引入事务的主要目的:事务会把数据库从一种状态转换为另一种一致状态.在数据库提交工作时,可以确保要么所有修改都已经保存了,要么所 ...
- 我是这样一步步理解--主题模型(Topic Model)、LDA
1. LDA模型是什么 LDA可以分为以下5个步骤: 一个函数:gamma函数. 四个分布:二项分布.多项分布.beta分布.Dirichlet分布. 一个概念和一个理念:共轭先验和贝叶斯框架. 两个 ...
- handlerAdapter与方法返回值的处理
前提:处理器方法被调用并返回了结果 public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer ma ...
- jboss 未授权访问漏洞复现
jboss 未授权访问漏洞复现 一.漏洞描述 未授权访问管理控制台,通过该漏洞,可以后台管理服务,可以通过脚本命令执行系统命令,如反弹shell,wget写webshell文件. 二.漏洞环境搭建及复 ...
- .NET Core CSharp 中级篇 2-2 List,ArrayList和Dictionary
.NET Core CSharp 中级篇 2-2 本节内容为List,ArrayList,和Dictionary 简介 在此前的文章中我们学习了数组的使用,但是数组有一个很大的问题就是存储空间不足,我 ...
- S2:c#继承
在C#中,如果一个类后面通过冒号又跟了另外一个类,那么我们就称冒号前面的类为子类,冒号后面的类为父类.这种书写类的方式放映出来的关系就称为类的继承关系. 1.子类:派生类 父类:基类或者超类 满足is ...