问题描述:

在集群模式部署服务端时,会出现所有的定时任务在各自的节点处均会执行一遍,这显然不符合实际的开发场景,针对这种问题,本文给出一种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 MySpecialTask​​Scheduler();
// } @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框架分布式部署定时任务重复执行之解决方案的更多相关文章

  1. Spring+quartz集群解决多服务器部署定时器重复执行的问题

    一.问题描述 Spring自带的Task虽然能很好使用定时任务,只需要做些简单的配置就可以了.不过如果部署在多台服务器上的时候,这样定时任务会在每台服务器都会执行,造成重复执行. 二.解决方案 Spr ...

  2. 小程序后端项目【Springboot框架】部署到阿里云服务器【支持https访问】

    前言: 我的后端项目是Java写的,用的Springboot框架.在部署服务器并配置https访问过程中,因为做了一些令人窒息的操作(事后发现),所以老是不能成功. 不成功具体点说就是:域名地址可以正 ...

  3. Laravel是怎样防止你的定时任务重复执行的

    基本介绍 有时候一个定时任务执行需要的时间可能会比我们想象的要长,这就会引起一个问题——当前任务还没有执行完毕的时候另一个相同的任务也会执行,从而导致任务重复.例如想象一下我们执行每分钟生成一次报告的 ...

  4. jemter分布式部署及linux下分布式脚本执行

    jmeter进行接口性能测试,占用内存较大,在模拟千万计并发用户时,使用分布式部署进行分压测试. 操作步骤:选择一台机器作为调度机,其他机器作为执行机 一.jmeter分布式部署 前提条件:A.执行机 ...

  5. 可重复执行的SQL Script

    问题 在工作中偶尔会遇到这样的问题:SQL script重复执行时会报错. 理想的状态下,SQL script跑一遍就够了,是不会重复执行的,但是实际情况往往很复杂. 比如Dev同学在开发时在A环境把 ...

  6. SpringBoot 使用定时任务动态执行任务

    import com.patient.core.adapter.CorsFilter; import org.mybatis.spring.annotation.MapperScan; import ...

  7. 【G】开源的分布式部署解决方案(一) - 开篇

    做这个开源项目的意义是什么?(口水自问自答,不喜可略过) 从功能上来说,请参考 预告篇,因自知当时预告片没有任何含金量,所以并没有主动推送到首页,而是私下的给一些人发的. 从个人角度上来说,我希望.n ...

  8. 【spring-boot】 springboot整合quartz实现定时任务

    在做项目时有时候会有定时器任务的功能,比如某某时间应该做什么,多少秒应该怎么样之类的. spring支持多种定时任务的实现.我们来介绍下使用spring的定时器和使用quartz定时器 1.我们使用s ...

  9. java Spring-Boot框架学习视频-百度云盘

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/lk142500/article/deta ...

随机推荐

  1. 渐进式web应用开发---promise式数据库(五)

    在前面的一篇文章中,我们已经实现了使用indexedDB实现ajax本地数据存储的功能,详情,请看这篇文章.现在我们需要把上面的一篇文章中的代码使用promise结构来重构下.我们为什么需要使用pro ...

  2. Hive的架构原理&Hive的安装步骤

    Hive架构图 元数据默认数据库是:Derby.开发使用MySQL Hive如何将SQL语句翻译成MapReduce的? 1.使用SQL解析器解析SQL语句 2.使用编译器进行编译逻辑 3.使用优化器 ...

  3. python找质数对

    python找质数对 编写python脚本,输入一个正整数,输出有几对质数的和等于这个正整数. 例如输入一个正整数10,可以找出有“3+7=10”.“5+5=10”两个质数对的和为10. 要实现这个功 ...

  4. 程序员的长安十二时辰:Java实现从Google oauth2.0认证调用谷歌内部api

    最近公司在做一个app购买的功能,主要思路就是客户在app上购买套餐以后,Google自动推送消息到Java后端,然后Java后端通过订单的token获取订单信息,保存到数据库. Java后端要获取订 ...

  5. 机器学习经典分类算法 —— k-近邻算法(附python实现代码及数据集)

    目录 工作原理 python实现 算法实战 约会对象好感度预测 故事背景 准备数据:从文本文件中解析数据 分析数据:使用Matplotlib创建散点图 准备数据:归一化数值 测试算法:作为完整程序验证 ...

  6. 前后端分离 之vue-cli 搭建项目mac 系统讲解

    前端项目搭建必备技术 webpack nodejs 搭建 vue-cli 的安装 以上技术自行了解安装 一:创建前端项目 采用vue-cli 脚手架 1:终端执行如下命令 vue init webpa ...

  7. GStreamer基础教程06 - 获取媒体信息

    摘要 在常见的媒体文件中,通常包含一些数据(例如:歌手,专辑,编码类型等),用于描述媒体文件.通常称这些数据为元数据(Metadata:data that provides information a ...

  8. 常用服务部署脚本(nodejs,pyenv,go,redis,)

    根据工作总结的常用安装脚本,要求linux-64系统 #!/bin/bash path=/usr/local/src node () { cd $path #wget https://nodejs.o ...

  9. PHP验证身份证格式

    互联网公司对身份证验证的需求越来越多,然而普通的小公司是无法对接公安部门的身份认证系统的.几乎都是在网上买一些大的互联网公司的一些认证服务.即使是便宜一些的认证价格也达到了10万次/万元.也就是一角钱 ...

  10. 2019前端面试系列——HTTP、浏览器面试题

    浏览器存储的方式有哪些 特性 cookie localStorage sessionStorage indexedDB 数据生命周期 一般由服务器生成,可以设置过期时间 除非被清理,否则一直存在 页面 ...