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

SpringBoot集成ShedLock實現(xiàn)分布式定時任務(wù)

 更新時間:2024年11月20日 08:38:56   作者:HBLOG  
ShedLock 是一個 Java 庫,通常用于分布式系統(tǒng)中,確保定時任務(wù)(Scheduled Tasks)在集群環(huán)境下只被某一個實例執(zhí)行一次,它通過在共享資源中添加鎖的方式,本文給大家介紹了SpringBoot集成ShedLock實現(xiàn)分布式定時任務(wù),需要的朋友可以參考下

1.什么是ShedLock?

ShedLock 是一個 Java 庫,通常用于分布式系統(tǒng)中,確保定時任務(wù)(Scheduled Tasks)在集群環(huán)境下只被某一個實例執(zhí)行一次。它通過在共享資源(例如數(shù)據(jù)庫或分布式緩存)中添加鎖的方式,避免多個實例同時執(zhí)行相同的任務(wù)

ShedLock 的工作原理

  • 分布式鎖
    • 在任務(wù)開始時,ShedLock 會嘗試在數(shù)據(jù)庫(或其他存儲)中創(chuàng)建一個鎖。
    • 如果某個實例成功獲取鎖,則只有它能執(zhí)行該任務(wù)。
  • 鎖的生命周期
    • 鎖會有一個明確的過期時間(鎖的持有時間,lockAtLeastForlockAtMostFor 參數(shù)配置)。
    • 鎖過期后,即使任務(wù)異常終止,其他實例也可以重新獲取鎖。
  • 支持的存儲
    • 支持多種鎖存儲,包括數(shù)據(jù)庫(如 MySQL、PostgreSQL)、Redis、MongoDB 等。

應(yīng)用場景

1. 分布式定時任務(wù)控制

  • 在分布式環(huán)境中,多個實例會同時調(diào)度定時任務(wù)。如果沒有控制,可能導(dǎo)致任務(wù)重復(fù)執(zhí)行。ShedLock 確保只有一個實例能運行任務(wù)。
  • 例如:
    • 生成日報表的定時任務(wù)。
    • 清理過期數(shù)據(jù)的批處理任務(wù)。

2. 避免重復(fù)任務(wù)執(zhí)行

  • 即使在單實例環(huán)境中,也可以使用 ShedLock 避免因意外重啟或配置錯誤導(dǎo)致同一任務(wù)被多次觸發(fā)。

3. 事件驅(qū)動任務(wù)的冪等性

  • 當(dāng)某些任務(wù)需要對同一事件觸發(fā)處理時,使用 ShedLock 可以確保一個事件只被處理一次。

4. 任務(wù)重試機制

  • 如果任務(wù)需要重試(例如在發(fā)生錯誤時),ShedLock 能避免多個實例同時重試相同任務(wù)。

2.代碼工程

實驗?zāi)康?/h3>

使用ShedLock 來確保在分布式環(huán)境中只有一個實例能運行任務(wù)

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.1</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>shedlock</artifactId>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-spring</artifactId>
            <version>5.5.0</version>
        </dependency>
        <dependency>
            <groupId>net.javacrumbs.shedlock</groupId>
            <artifactId>shedlock-provider-jdbc-template</artifactId>
            <version>5.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
    </dependencies>
</project>

config

package com.demo.config;

import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

@Configuration
public class ShedLockConfig {

    @Bean
    public LockProvider lockProvider(DataSource dataSource) {
        return new JdbcTemplateLockProvider(
            JdbcTemplateLockProvider.Configuration.builder()
                .withJdbcTemplate(new JdbcTemplate(dataSource))
                .usingDbTime() // Works with PostgreSQL, MySQL, MariaDb, MS SQL, Oracle, HSQL, H2, DB2, and others
                .build()
        );
    }
}

cron

package com.demo.cron;

import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

@Configuration
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
public class SchedulerConfig {

    @Scheduled(cron = "0 0/1 * * * ?")
    @SchedulerLock(name = "scheduledTaskName", lockAtMostFor = "PT10M", lockAtLeastFor = "PT1M")
    public void scheduledTask() {
        //  some logic code
        System.out.println("Executing scheduled task");
    }

}
  • @Scheduled(cron = "0 0/1 * * * ?")
    • 定義定時任務(wù)的調(diào)度時間。
    • 表達式含義:任務(wù)每分鐘的整點觸發(fā),例如 12:00、12:01、12:02。
    • 注意:多個實例(分布式環(huán)境)都會在同一時間調(diào)度到此任務(wù),但通過 ShedLock 確保只有一個實例能真正執(zhí)行。
  • @SchedulerLock
    • 使用 ShedLock 來管理分布式鎖。
    • name = "scheduledTaskName":
      • 定義鎖的唯一標(biāo)識。共享存儲(如數(shù)據(jù)庫或 Redis)中會記錄此鎖的狀態(tài)。
    • lockAtMostFor = "PT10M":
      • 鎖的最長持有時間為 10分鐘。
      • 如果任務(wù)運行超出 10 分鐘,即使沒有主動釋放鎖,也會自動過期,其他實例可以繼續(xù)獲取鎖。
    • lockAtLeastFor = "PT1M":
      • 鎖的最短持有時間為 1分鐘。
      • 即使任務(wù)提前完成,鎖仍會持有至少 1 分鐘,防止其他實例快速重復(fù)執(zhí)行任務(wù)。
  • 任務(wù)邏輯
    • System.out.println("Executing scheduled task"); 是任務(wù)的業(yè)務(wù)邏輯。
    • 此邏輯只會在獲得鎖的實例上執(zhí)行。

配置文件

node1節(jié)點

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
server.port=8081

node2節(jié)點

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
server.port=8082

以上只是一些關(guān)鍵代碼。

3.測試

啟動node1節(jié)點

java -jar myapp.jar --spring.profiles.active=node1

啟動node2節(jié)點

java -jar myapp.jar --spring.profiles.active=node2

通過控制臺觀察日志,可以發(fā)現(xiàn),2個實例交替獲取到鎖執(zhí)行,而不是同一時刻一起執(zhí)行

4.注意事項

  • 任務(wù)時間控制: 確保任務(wù)的實際執(zhí)行時間小于 lockAtMostFor,否則任務(wù)可能被其他實例重復(fù)執(zhí)行。
  • 冪等性: 任務(wù)邏輯應(yīng)盡量設(shè)計為冪等的(重復(fù)執(zhí)行不會產(chǎn)生副作用),以應(yīng)對鎖機制的潛在異常情況。
  • 存儲配置: 確保使用高可用的鎖存儲(如數(shù)據(jù)庫或 Redis),否則鎖機制可能失效。

以上就是SpringBoot集成ShedLock實現(xiàn)分布式定時任務(wù)的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot ShedLock定時任務(wù)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring Boot中使用 Spring Security 構(gòu)建權(quán)限系統(tǒng)的示例代碼

    Spring Boot中使用 Spring Security 構(gòu)建權(quán)限系統(tǒng)的示例代碼

    本篇文章主要介紹了Spring Boot中使用 Spring Security 構(gòu)建權(quán)限系統(tǒng)的示例代碼,具有一定的參考價值,有興趣的可以了解一下
    2017-08-08
  • 快速上手Mybatis-plus結(jié)構(gòu)構(gòu)建過程

    快速上手Mybatis-plus結(jié)構(gòu)構(gòu)建過程

    這篇文章主要介紹了快速上手Mybatis-plus結(jié)構(gòu)構(gòu)建過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Java 字符數(shù)組轉(zhuǎn)字符串的常用方法

    Java 字符數(shù)組轉(zhuǎn)字符串的常用方法

    文章總結(jié)了在Java中將字符數(shù)組轉(zhuǎn)換為字符串的幾種常用方法,包括使用String構(gòu)造函數(shù)、String.valueOf()方法、StringBuilder以及Arrays.toString()方法,每種方法都有其適用的場景和性能特點,感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • SpringBoot中靜態(tài)訪問配置屬性的解決方案對比

    SpringBoot中靜態(tài)訪問配置屬性的解決方案對比

    在SpringBoot開發(fā)中,靜態(tài)訪問配置信息是一個常見需求,尤其是在工具類中直接獲取配置值,下面我們就來看看幾個常用的方法,大家可以根據(jù)需要選擇
    2025-03-03
  • MyBatis-Plus 分頁插件配置的兩種方式實現(xiàn)

    MyBatis-Plus 分頁插件配置的兩種方式實現(xiàn)

    本文主要介紹了MyBatis-Plus 分頁插件配置的兩種方式實現(xiàn),包括使用PaginationInterceptor和MybatisPlusInterceptor兩種方式,具有一定的參考價值,感興趣的可以了解一下
    2025-03-03
  • 使用Maven中的scope總結(jié)

    使用Maven中的scope總結(jié)

    這篇文章主要介紹了使用Maven中的scope總結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • easyexcel讀取excel合并單元格數(shù)據(jù)的操作代碼

    easyexcel讀取excel合并單元格數(shù)據(jù)的操作代碼

    這篇文章主要介紹了easyexcel讀取excel合并單元格數(shù)據(jù)的操作代碼,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • Spring的嵌套事務(wù)(Propagation.NESTED)到底是個啥案例代碼講解

    Spring的嵌套事務(wù)(Propagation.NESTED)到底是個啥案例代碼講解

    SavePoint是數(shù)據(jù)庫事務(wù)中的一個概念,?可以將整個事務(wù)切割為不同的小事務(wù),可以選擇將狀態(tài)回滾到某個小事務(wù)發(fā)生時的樣子,本文通過案例代碼講解Spring的嵌套事務(wù)(Propagation.NESTED)到底是個啥,感興趣的朋友跟隨小編一起看看吧
    2023-01-01
  • java面向?qū)ο笤O(shè)計原則之接口隔離原則示例詳解

    java面向?qū)ο笤O(shè)計原則之接口隔離原則示例詳解

    這篇文章主要為大家介紹了java面向?qū)ο笤O(shè)計原則之接口隔離原則的示例詳解,有需要的朋友可以借鑒參考下希望能夠有所幫助,祝大家多多進步早日升職加薪
    2021-10-10
  • JDK8?中Arrays.sort()?排序方法詳解

    JDK8?中Arrays.sort()?排序方法詳解

    這篇文章主要介紹了JDK8?中Arrays.sort()?排序方法解讀,本文先行介紹Arrays.sort()中影響排序方式的幾個因素,影響因素主要為數(shù)組類型、數(shù)組大小,結(jié)合閾值對排序方式進行選擇,需要的朋友可以參考下
    2023-05-05

最新評論