欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Boot 整合 ShedLock 處理定時任務重復執(zhí)行的問題小結

 更新時間:2025年02月06日 11:37:35   作者:Micro麥可樂  
ShedLock是解決分布式系統(tǒng)中定時任務重復執(zhí)行問題的Java庫,通過在數據庫中加鎖,確保只有一個節(jié)點在指定時間執(zhí)行任務,它與SpringScheduler、Quartz等框架結合使用,本文介紹Spring Boot 整合 ShedLock 處理定時任務重復執(zhí)行的問題,感興趣的朋友一起看看吧

前言

在分布式系統(tǒng)中,定時任務的執(zhí)行往往需要考慮到多個實例的并發(fā)執(zhí)行問題。假設一個定時任務會在多個節(jié)點上并發(fā)執(zhí)行,可能導致重復執(zhí)行,甚至引發(fā)數據異常或系統(tǒng)不一致問題。為了解決這一問題,ShedLock 是一個簡單而有效的解決方案,它可以確保在分布式環(huán)境中,只有一個節(jié)點在某一時刻執(zhí)行指定的定時任務。

什么是 ShedLock?

ShedLock 是一個輕量級的 Java 庫,用于解決分布式系統(tǒng)中定時任務的重復執(zhí)行問題。它的核心思想是在數據庫中加鎖,確保在分布式環(huán)境下,只有一個節(jié)點能夠在指定時間執(zhí)行某個任務。ShedLock 可以與 Spring SchedulerQuartz 等定時任務框架結合使用。

github開源地址:https://github.com/lukas-krecan/ShedLock 目前擁有 3.7K Star,小伙伴們也可以針對文檔更系統(tǒng)性的學習如何應用ShedLock。

ShedLock 的工作原理:

? 定時任務執(zhí)行時,ShedLock 會嘗試在數據庫中為該任務獲取鎖。
? 如果當前節(jié)點成功獲取到鎖,則執(zhí)行定時任務。
? 如果當前節(jié)點未能獲取到鎖(其他節(jié)點已獲取鎖),則該任務跳過執(zhí)行,等待下次調度。

定時任務重復執(zhí)行的問題

在分布式應用中,定時任務往往通過多個實例運行,每個實例都會按照自己的調度計劃執(zhí)行任務。例如,假設有一個定時任務負責同步某個外部系統(tǒng)的數據。如果該任務在多個實例上同時執(zhí)行,就會導致重復的數據同步,進而造成數據不一致、重復處理等問題。

典型場景
我們來模擬一個場景,假設在一個電商系統(tǒng)中,定時任務負責將庫存數據同步到第三方庫存管理系統(tǒng)。如果該任務在多個節(jié)點上同時執(zhí)行,可能會導致:

1、重復的庫存更新請求。
2、數據不同步或數據丟失。
3、系統(tǒng)負載過高,造成性能瓶頸。

使用 ShedLock 解決定時任務重復執(zhí)行問題

接下來,博主將通過 Spring Boot 和 ShedLock 來演示如何解決定時任務的重復執(zhí)行問題。希望能給大家一個參考!

? 添加依賴

首先確保我們的的 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.x17Spring 6.2, 6.1
Spring Boot 3.4, 3.3
Micronaut 4
5.x.x17Spring 6.1, 6.0
Spring Boot 3.4, 3.3, 3.2
Micronaut 3, 4
4.x.x8Spring 6.0, 5.3
Spring Boot 3.0, 2.7, 2.6
3.x.x8Spring 5.2, 5.1
Spring Boot 2.2, 2.1
2.x.x8Spring 5.1, 5.0
Spring Boot 2.1
1.x.x8Spring 5.0
Spring Boot 2.0

? 配置數據庫

ShedLock 需要在數據庫中存儲鎖的信息。這里博主使用 MySQL 來存儲鎖。首先,創(chuàng)建一個名為 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: 鎖的名稱,用于區(qū)分不同的任務。
  • lock_until: 鎖的過期時間,任務完成后應釋放鎖。
  • locked_at: 鎖的創(chuàng)建時間。
  • locked_by: 鎖被哪個節(jié)點持有。

? 配置 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 參數指定鎖的最大過期時間。如果任務執(zhí)行超過此時間,鎖將會被釋放。

@EnableScheduling: 啟用 Spring 的調度功能。

? 創(chuàng)建定時任務

接下來我們創(chuàng)建一個定時任務,并為其添加 ShedLock 鎖,確保在分布式環(huán)境中只有一個實例會執(zhí)行該任務。

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 注解來確保該任務只會在一個節(jié)點上執(zhí)行
     */
    @Scheduled(fixedRate = 5000)  // 每 5 秒執(zhí)行一次
    @SchedulerLock(name = "syncInventoryTask", lockAtMostFor = "5m", lockAtLeastFor = "5m")
    public void syncInventory() {
        System.out.println("同步庫存數據...");
        // 模擬庫存同步操作
        try {
            Thread.sleep(3000);  // 模擬執(zhí)行耗時 3 秒
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println("庫存同步完成!");
    }
}

上述代碼中,我們在在 syncInventory 方法上,我們使用了 @SchedulerLock 注解,指定鎖的名稱 syncInventoryTask,并設置鎖的最大持續(xù)時間為 5 秒。

  • name: 鎖的名稱,確保每個定時任務有唯一的名稱。
  • lockAtMostFor: 鎖的最大過期時間,防止任務因為異常而無法釋放鎖。
  • lockAtLeastFor: 鎖的最小持續(xù)時間,確保鎖至少保持一定時間。

? 配置數據庫連接

最后 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 秒鐘執(zhí)行一次,但只有一個節(jié)點能夠在任何時刻成功執(zhí)行該任務,避免了多節(jié)點并發(fā)執(zhí)行造成的問題。

總結

相信小伙伴們通過本文的示例,我們演示了如何使用 ShedLock 解決分布式系統(tǒng)中定時任務重復執(zhí)行的問題。ShedLock 提供了一種簡單有效的方式來確保在多實例部署的環(huán)境中,定時任務不會被重復執(zhí)行,避免了數據不一致等問題。

  • 應用場景: 分布式定時任務、任務調度、數據同步等場景。
  • 優(yōu)勢: 簡單易用、無需復雜配置、適配多種存儲方式(如 JDBC、MongoDB、Redis等)

到此這篇關于Spring Boot 整合 ShedLock 處理定時任務重復執(zhí)行的問題的文章就介紹到這了,更多相關Spring Boot ShedLock 定時任務重復執(zhí)行內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java數據結構之HashMap和HashSet

    Java數據結構之HashMap和HashSet

    這篇文章主要介紹了HashMap和HashSet,什么是哈希表以及HashMap的部分源碼解讀,想了解更多的小伙伴,可以參考閱讀本文
    2023-03-03
  • 利用Java實現(xiàn)網站聚合工具

    利用Java實現(xiàn)網站聚合工具

    互聯(lián)網上有數以萬億計的網站,每個網站大都具有一定的功能。搜索引擎雖然對互聯(lián)網上的部分網站建立了索引,但是其作為一個大而全的搜索系統(tǒng),無法很好的定位到一些特殊的需求。因此本文將介紹一個用java實現(xiàn)的網站數據聚合工具,需要的可以參考一下
    2022-01-01
  • Java解碼H264格式視頻流中的圖片

    Java解碼H264格式視頻流中的圖片

    這篇文章主要為大家詳細介紹了Java解碼H264格式視頻流中的圖片,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • SpringBoot JPA實現(xiàn)查詢多值

    SpringBoot JPA實現(xiàn)查詢多值

    這篇文章主要為大家詳細介紹了SpringBoot JPA實現(xiàn)查詢多值,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • java實現(xiàn)用戶簽到BitMap功能實現(xiàn)demo

    java實現(xiàn)用戶簽到BitMap功能實現(xiàn)demo

    這篇文章主要為大家介紹了java實現(xiàn)用戶簽到BitMap功能實現(xiàn)demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • 如何實用Java實現(xiàn)合并、拆分PDF文檔

    如何實用Java實現(xiàn)合并、拆分PDF文檔

    這篇文章主要介紹了如何實用Java實現(xiàn)合并、拆分PDF文檔,處理PDF文檔時,這樣的好處是對文檔的存儲、管理很方便。下面將通過Java程序代碼介紹具體的PDF合并、拆分的方法,需要的朋友可以參考下
    2019-07-07
  • Java數據結構學習之樹

    Java數據結構學習之樹

    這篇文章主要介紹了Java數據結構學習之樹,文中有非常詳細的代碼示例,對正在學習java數據結構的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-05-05
  • SpringBoot記錄Http請求日志的方法

    SpringBoot記錄Http請求日志的方法

    這篇文章主要介紹了SpringBoot記錄Http請求日志的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • 詳解SpringBoot Schedule配置

    詳解SpringBoot Schedule配置

    本篇文章主要介紹了詳解SpringBoot Schedule配置 ,可以實現(xiàn)定時任務,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • springboot訪問404問題的解決辦法

    springboot訪問404問題的解決辦法

    工作中遇到url404問題,解決問題的進程比較崎嶇,寫篇文章記錄,下面這篇文章主要給大家介紹了關于springboot訪問404問題的解決辦法,文中通過圖文介紹的非常詳細,要的朋友可以參考下
    2023-03-03

最新評論