东营网站,百度权重高的网站有哪些,win7 添加asp网站,开发公司工程部年终工作总结#x1f337; 古之立大事者#xff0c;不惟有超世之才#xff0c;亦必有坚忍不拔之志 #x1f390; 个人CSND主页——Micro麦可乐的博客 #x1f425;《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程#xff0c;入门到实战 #x1f33a;《RabbitMQ》… 古之立大事者不惟有超世之才亦必有坚忍不拔之志 个人CSND主页——Micro麦可乐的博客 《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程入门到实战 《RabbitMQ》专栏主要介绍使用JAVA开发RabbitMQ的系列教程从基础知识到项目实战 《设计模式》专栏以实际的生活场景为案例进行讲解让大家对设计模式有一个更清晰的理解 《Jenkins实战》专栏主要介绍JenkinsDocker的实战教程让你快速掌握项目CI/CD是2024年最新的实战教程 《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧代码样例完整 如果文章能够给大家带来一定的帮助欢迎关注、评论互动 Spring Boot 整合 ShedLock 处理定时任务重复执行的问题 前言什么是 ShedLockShedLock 的工作原理 定时任务重复执行的问题使用 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 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- Spring Boot Scheduler --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-scheduled/artifactId/dependency!-- ShedLock Core --dependencygroupIdnet.javacrumbs.shedlock/groupIdartifactIdshedlock-spring/artifactIdversion6.2.0/version/dependency!-- ShedLock JDBC --dependencygroupIdnet.javacrumbs.shedlock/groupIdartifactIdshedlock-provider-jdbc-template/artifactIdversion6.2.0/version/dependency!-- MySQL JDBC Driver --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactId/dependency
/dependencies对应版本兼容性依赖
ShedLock版本最低JVM版本Tested with6.x.x17Spring 6.2, 6.1 Spring Boot 3.4, 3.3 Micronaut 45.x.x17Spring 6.1, 6.0 Spring Boot 3.4, 3.3, 3.2 Micronaut 3, 44.x.x8Spring 6.0, 5.3 Spring Boot 3.0, 2.7, 2.63.x.x8Spring 5.2, 5.1 Spring Boot 2.2, 2.12.x.x8Spring 5.1, 5.0 Spring Boot 2.11.x.x8Spring 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.urljdbc:mysql://localhost:3306/your_database
spring.datasource.usernameroot
spring.datasource.passwordyour_password
spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-autoupdate❻ 启动应用测试
最后我们启动 Spring Boot 应用查看控制台输出。你将会看到 syncInventory 任务每 5 秒钟执行一次但只有一个节点能够在任何时刻成功执行该任务避免了多节点并发执行造成的问题。 总结
相信小伙伴们通过本文的示例我们演示了如何使用 ShedLock 解决分布式系统中定时任务重复执行的问题。ShedLock 提供了一种简单有效的方式来确保在多实例部署的环境中定时任务不会被重复执行避免了数据不一致等问题。
应用场景: 分布式定时任务、任务调度、数据同步等场景。优势: 简单易用、无需复杂配置、适配多种存储方式如 JDBC、MongoDB、Redis等
如果本文对您有所帮助希望 一键三连 给博主一点点鼓励如果您有任何疑问或建议请随时留言讨论