Spring Boot 整合 ShedLock 处理定时任务重复执行的问题

🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~
Spring Boot 整合 ShedLock 处理定时任务重复执行的问题
- 前言
- 什么是 ShedLock?
- ShedLock 的工作原理:
- 定时任务重复执行的问题
- 使用 ShedLock 解决定时任务重复执行问题
- ❶ 添加依赖
- ❷ 配置数据库
- ❸ 配置 ShedLock
- ❹ 创建定时任务
- ❺ 配置数据库连接
- ❻ 启动应用测试
- 总结
前言
在分布式系统中,定时任务的执行往往需要考虑到多个实例的并发执行问题。假设一个定时任务会在多个节点上并发执行,可能导致重复执行,甚至引发数据异常或系统不一致问题。为了解决这一问题,ShedLock 是一个简单而有效的解决方案,它可以确保在分布式环境中,只有一个节点在某一时刻执行指定的定时任务。
什么是 ShedLock?
ShedLock 是一个轻量级的 Java 库,用于解决分布式系统中定时任务的重复执行问题。它的核心思想是在数据库中加锁,确保在分布式环境下,只有一个节点能够在指定时间执行某个任务。ShedLock 可以与 Spring Scheduler、Quartz 等定时任务框架结合使用。
github开源地址:https://github.com/lukas-krecan/ShedLock 目前拥有 3.7K Star,小伙伴们也可以针对文档更系统性的学习如何应用ShedLock。
ShedLock 的工作原理:
❶ 定时任务执行时,ShedLock 会尝试在数据库中为该任务获取锁。
❷ 如果当前节点成功获取到锁,则执行定时任务。
❸ 如果当前节点未能获取到锁(其他节点已获取锁),则该任务跳过执行,等待下次调度。
定时任务重复执行的问题
在分布式应用中,定时任务往往通过多个实例运行,每个实例都会按照自己的调度计划执行任务。例如,假设有一个定时任务负责同步某个外部系统的数据。如果该任务在多个实例上同时执行,就会导致重复的数据同步,进而造成数据不一致、重复处理等问题。
典型场景
我们来模拟一个场景,假设在一个电商系统中,定时任务负责将库存数据同步到第三方库存管理系统。如果该任务在多个节点上同时执行,可能会导致:
1、重复的库存更新请求。
2、数据不同步或数据丢失。
3、系统负载过高,造成性能瓶颈。
使用 ShedLock 解决定时任务重复执行问题
接下来,博主将通过 Spring Boot 和 ShedLock 来演示如何解决定时任务的重复执行问题。希望能给大家一个参考!
❶ 添加依赖
首先确保我们的的 pom.xml 中包含必要的依赖。需要添加 Spring Boot Starter、Spring Scheduling 和 ShedLock 相关的依赖。
其中博主使用的是Mysql作为ShedLock初始化数据库,引入shedlock-provider-jdbc-template,大家可以根据自己的实际情况,根据作者的文档选择,如下图:

<dependencies><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot Scheduler --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-scheduled</artifactId></dependency><!-- ShedLock Core --><dependency><groupId>net.javacrumbs.shedlock</groupId><artifactId>shedlock-spring</artifactId><version>6.2.0</version></dependency><!-- ShedLock JDBC --><dependency><groupId>net.javacrumbs.shedlock</groupId><artifactId>shedlock-provider-jdbc-template</artifactId><version>6.2.0</version></dependency><!-- MySQL JDBC Driver --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>
</dependencies>
对应版本兼容性依赖:
| ShedLock版本 | 最低JVM版本 | Tested with |
|---|---|---|
| 6.x.x | 17 | Spring 6.2, 6.1 Spring Boot 3.4, 3.3 Micronaut 4 |
| 5.x.x | 17 | Spring 6.1, 6.0 Spring Boot 3.4, 3.3, 3.2 Micronaut 3, 4 |
| 4.x.x | 8 | Spring 6.0, 5.3 Spring Boot 3.0, 2.7, 2.6 |
| 3.x.x | 8 | Spring 5.2, 5.1 Spring Boot 2.2, 2.1 |
| 2.x.x | 8 | Spring 5.1, 5.0 Spring Boot 2.1 |
| 1.x.x | 8 | Spring 5.0 Spring Boot 2.0 |
❷ 配置数据库
ShedLock 需要在数据库中存储锁的信息。这里博主使用 MySQL 来存储锁。首先,创建一个名为 shedlock 的表来存储锁数据。
CREATE TABLE shedlock (name VARCHAR(64) PRIMARY KEY,lock_until TIMESTAMP(3) NOT NULL,locked_at TIMESTAMP(3) NOT NULL,locked_by VARCHAR(255) NOT NULL
);
该表的字段意义如下:
- name: 锁的名称,用于区分不同的任务。
- lock_until: 锁的过期时间,任务完成后应释放锁。
- locked_at: 锁的创建时间。
- locked_by: 锁被哪个节点持有。
❸ 配置 ShedLock
接下来,我们在 Spring Boot 配置类中进行 ShedLock 的配置。以下是一个基本的配置类:
import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;@Configuration
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "30m") //默认锁最大过期时间为 30 秒
public class ShedLockConfig {
}
注解说明:
@EnableSchedulerLock: 启用 ShedLock 功能,defaultLockAtMostFor 参数指定锁的最大过期时间。如果任务执行超过此时间,锁将会被释放。
@EnableScheduling: 启用 Spring 的调度功能。
❹ 创建定时任务
接下来我们创建一个定时任务,并为其添加 ShedLock 锁,确保在分布式环境中只有一个实例会执行该任务。
package com.example;import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;@Service
public class DataSyncService {/*** 使用 @SchedulerLock 注解来确保该任务只会在一个节点上执行*/@Scheduled(fixedRate = 5000) // 每 5 秒执行一次@SchedulerLock(name = "syncInventoryTask", lockAtMostFor = "5m", lockAtLeastFor = "5m")public void syncInventory() {System.out.println("同步库存数据...");// 模拟库存同步操作try {Thread.sleep(3000); // 模拟执行耗时 3 秒} catch (InterruptedException e) {Thread.currentThread().interrupt();}System.out.println("库存同步完成!");}
}
上述代码中,我们在在 syncInventory 方法上,我们使用了 @SchedulerLock 注解,指定锁的名称 syncInventoryTask,并设置锁的最大持续时间为 5 秒。
- name: 锁的名称,确保每个定时任务有唯一的名称。
- lockAtMostFor: 锁的最大过期时间,防止任务因为异常而无法释放锁。
- lockAtLeastFor: 锁的最小持续时间,确保锁至少保持一定时间。
❺ 配置数据库连接
最后 application.properties 或 application.yml 配置我们的数据库连接信息
spring.datasource.url=jdbc:mysql://localhost:3306/your_database
spring.datasource.username=root
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
❻ 启动应用测试
最后我们启动 Spring Boot 应用,查看控制台输出。你将会看到 syncInventory 任务每 5 秒钟执行一次,但只有一个节点能够在任何时刻成功执行该任务,避免了多节点并发执行造成的问题。
总结
相信小伙伴们通过本文的示例,我们演示了如何使用 ShedLock 解决分布式系统中定时任务重复执行的问题。ShedLock 提供了一种简单有效的方式来确保在多实例部署的环境中,定时任务不会被重复执行,避免了数据不一致等问题。
- 应用场景: 分布式定时任务、任务调度、数据同步等场景。
- 优势: 简单易用、无需复杂配置、适配多种存储方式(如 JDBC、MongoDB、Redis等)
如果本文对您有所帮助,希望 一键三连 给博主一点点鼓励,如果您有任何疑问或建议,请随时留言讨论!

相关文章:
Spring Boot 整合 ShedLock 处理定时任务重复执行的问题
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Micro麦可乐的博客 🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战 🌺《RabbitMQ》…...
常见Arthas命令与实践
Arthas 官网:https://arthas.aliyun.com/doc/,官方文档对 Arthas 的每个命令都做出了介绍和解释,并且还有在线教程,方便学习和熟悉命令。 Arthas Idea 的 IDEA 插件。 这是一款能快速生成 Arthas命令的插件,可快速生成…...
Glide加载gif遇到的几个坑
Glide本身支持gif格式的动画加载,但是大多数情况下我们用Glide都是去加载一些静态图片,加载gif动态图的需求不是很多,因此这次使用Glide加载gif就遇到了一些令人匪夷所思的问题 问题一:加载gif图片会有明显的卡顿 通常情况下我们…...
STM32学习之通用定时器
1.1通用定时器介绍 通用定时器具有基本定时器的所有特征,基本定时器只能递增计数,而通用定时器可以递减计数,可以中心对齐计数;也可以触发ADC和DAC,同时在更新事件,触发事件,输入捕获ÿ…...
MiniMax-Text-01——模型详细解读与使用
MiniMax发布了最新的旗舰款模型,MiniMax-Text-01。这是一个456B参数的MOE模型,支持最大4M上下文。今天我们来解读一下这个模型,最后会讲一下模型的使用方式和价格。 先来看整体指标,以下图表分为三块指标,分别是文本能…...
Redis的Windows版本安装以及可视化工具
文章目录 redis安装redis安装包下载解压文件夹启动redis服务Redis路径配置环境变量打开redis客户端进行连接基础操作测试 redis可视化工具下载Redis Desktop Manager redis安装 redis安装包下载 windows版本readis下载:Releases tporadowski/redis 解压文件夹 我…...
tensorflow源码编译在C++环境使用
https://tensorflow.google.cn/install/source?hlzh-cn查看tensorflow和其他需要下载软件对应的版本,最好一模一样 1、下载TensorFlow源码 https://github.com/tensorflow/tensorflow 2、安装编译protobuf(3.9.2) protobuf版本要和TensorFlo…...
第四届机器学习、云计算与智能挖掘国际会议
一、会议信息 会议名称:第四届机器学习、云计算与智能挖掘国际会议(MLCCIM 2025) 会议地点:中国漠河 会议时间:2025年7月21-25日 支持单位:佛山市人工智能学会、佛山大学 二、大会主席 …...
#漏洞挖掘# 一文了解什么是Jenkins未授权访问!!!
免责声明 本教程仅为合法的教学目的而准备,严禁用于任何形式的违法犯罪活动及其他商业行为,在使用本教程前,您应确保该行为符合当地的法律法规,继续阅读即表示您需自行承担所有操作的后果,如有异议,请立即停…...
QT QListWidget控件 全面详解
本系列文章全面的介绍了QT中的57种控件的使用方法以及示例,包括 Button(PushButton、toolButton、radioButton、checkBox、commandLinkButton、buttonBox)、Layouts(verticalLayout、horizontalLayout、gridLayout、formLayout)、Spacers(verticalSpacer、horizontalSpacer)、…...
【Vim Masterclass 笔记25】S10L45:Vim 多窗口的常用操作方法及相关注意事项
文章目录 S10L45 Working with Multiple Windows1 水平分割窗口2 在水平分割的新窗口中显示其它文件内容3 垂直分割窗口4 窗口的关闭5 在同一窗口水平拆分出多个窗口6 关闭其余窗口7 让四个文件呈田字形排列8 光标在多窗口中的定位9 调节子窗口的尺寸大小10 变换子窗口的位置11…...
包文件分析器 Webpack Bundle Analyzer
webpack-bundle-analyzer 是一个非常有用的工具,用于可视化和分析 Webpack 打包生成的文件。这使得开发者能够更好地理解应用的依赖关系、包的大小,以及优化打包的机会。以下是关于 webpack-bundle-analyzer 的详细介绍,包括它的安装、使用以…...
代码随想录day14
二叉树的反转,采用迭代,只能用前序和后序遍历 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(i…...
react19新API之use()用法总结
React use() Hook 使用指南 概述 use() 是 React 19 引入的新 Hook,它允许你在组件内部直接使用 Promise、Context 和其他可订阅的值。它是一个更通用的数据获取和订阅机制。 基本语法 const value use(resource);主要用途 1. Promise 处理 function UserDet…...
67,【7】buuctf web [HarekazeCTF2019]Avatar Uploader 2(未完成版)
进入靶场 和上一题一母同胞,先把上一题的答案拖进去看看 区别在于上一题这块直接显示了flag,这里并没有 看看源码 加载不出来,ctrlu <!-- 上传头像的提示信息,说明上传要求 --><p>Please upload a PNG image less th…...
ANSYS HFSS 中的相控天线阵列仿真方法
概述 相控天线阵列系统广泛使用,从国防雷达应用到商业 5G 应用。设计这些天线阵列涉及复杂的数学运算,需要全波仿真。Ansys HFSS 全场 3D 电磁仿真软件可以在合理的时间内以较低的计算成本仿真复杂的相控阵天线系统,同时考虑复杂激励、环境&…...
stm32 L051 adc配置及代码实例解析
一 cude的设置: 1. 接口的基本设置: 2. 参数的设置: 二 代码的逻辑: 1. 上面的直接生成代码,然后使用下面源码即可读到adc的数据: void adc_battery_start(void) {uint32_t ADC_value 0;HAL_ADC_Start(&…...
KUKA示教器仿真软件OfficeLite8.6.2,EthernetKRL3.1.3通信
一、准备软件。 1、vmware17.6.1 2、OfficeLite8.6.2 3、EthernetKRL3.1.3 4、KUKA Router 5、EthernetKRL_Server 通过网盘分享的文件:库卡相关软件 链接: https://pan.baidu.com/s/1NwvR3RVP0edLBeZnnnCYvw 提取码: smys 二、安装vmware17.6.1 1、找到下载…...
Erlang语言的并发编程
Erlang语言的并发编程 引言 并发编程是现代软件开发中的一个重要领域,尤其是在面对需要高效处理大量任务的应用时。Erlang是一种专门设计用于并发编程的编程语言,由于其在电信和即时通信系统中的广泛应用,逐渐引起了开发者的关注。Erlang的…...
【数据挖掘实战】 房价预测
本次对kaggle中的入门级数据集,房价回归数据集进行数据挖掘,预测房屋价格。 本人主页:机器学习司猫白 机器学习专栏:机器学习实战 PyTorch入门专栏:PyTorch入门 深度学习实战:深度学习 ok,话不多…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
StarRocks 全面向量化执行引擎深度解析
StarRocks 全面向量化执行引擎深度解析 StarRocks 的向量化执行引擎是其高性能的核心设计,相比传统行式处理引擎(如MySQL),性能可提升 5-10倍。以下是分层拆解: 1. 向量化 vs 传统行式处理 维度行式处理向量化处理数…...
