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

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

 更新時間:2023年02月24日 11:51:52   作者:陳鋆  
ShedLock是一個鎖,官方解釋是他永遠只是一個鎖,并非是一個分布式任務(wù)調(diào)度器。一般shedLock被使用的場景是,你有個任務(wù),你只希望他在單個節(jié)點執(zhí)行,而不希望他并行執(zhí)行,而且這個任務(wù)是支持重復(fù)執(zhí)行的

一、背景

在項目服務(wù)是集群部署的時候,代碼在每個人都會有定時任務(wù),但是如果讓每個節(jié)點都去跑定時任務(wù)是不大合適的。SpringBoot 中的 ShedLock 可以很好解決這個問題,下面我將為大家詳細介紹 SpringBoot 如何集成 ShedLock,而 ShedLock 又是如何實現(xiàn)分布式定時的。

二、ShedLock是什么

官方地址

以下是ShedLock鎖提供者,通過外部存儲實現(xiàn)鎖,由下圖可知外部存儲集成的庫還是很豐富:

本篇教程我們基于JdbcTemplate存儲為例來使用ShedLock鎖。

三、落地實現(xiàn)

3.1 引入依賴包

shedlock所需依賴包:

<!-- web工程依賴包 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-spring</artifactId>
    <version>4.2.0</version>
</dependency>
 <!--每個外部存儲實例所需依賴包不一樣,這里是jdbc-->
<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-provider-jdbc-template</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

依賴包樹形圖:

3.2 配置數(shù)據(jù)庫連接信息

server:
  port: 8105
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/testjdbc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.mysql.cj.jdbc.MysqlDataSource

3.3 創(chuàng)建Mysql數(shù)據(jù)表

CREATE TABLE `shedlock` (
	`name`  varchar(64) NOT NULL COMMENT 'name' ,
	`lock_until`  timestamp(3) NULL DEFAULT NULL ,
	`locked_at`  timestamp(3) NULL DEFAULT NULL ,
	`locked_by`  varchar(255) NULL DEFAULT NULL ,
	PRIMARY KEY (`name`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
ROW_FORMAT=DYNAMIC
;

3.4 配置LockProvider

ShedLockConfig.java:

import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.sql.DataSource;
/**
 * @description: Shedlock集成Jdbc配置類
 */
@Component
public class ShedLockConfig {
    @Resource
    private DataSource dataSource;
    @Bean
    private LockProvider lockProvider() {
        return new JdbcTemplateLockProvider(dataSource);
    }
}

springboot主啟動類MerakQuartzApplication:

import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
/**
 * @version 1.0
 * @ClassName: MerakQuartzApplication
 * @description: 工單任務(wù)調(diào)度
 */
// 開啟定時器
@EnableScheduling
// 開啟定時任務(wù)鎖,指定一個默認的鎖的時間30秒
@EnableSchedulerLock(defaultLockAtMostFor = "PT30S")
@EnableAsync
@MapperScan(basePackages = {"com.merak.hyper.automation.persist.**.mapper"})
@SpringBootApplication(scanBasePackages = {"com.merak.hyper.automation.**"}, exclude = {SecurityAutoConfiguration.class})
public class MerakQuartzApplication {
    public static final Logger log = LoggerFactory.getLogger(MerakQuartzApplication.class);
    public static void main(String[] args) {
        SpringApplication.run(MerakQuartzApplication.class, args);
    }
    private int taskSchedulerCorePoolSize = 15;
    private int awaitTerminationSeconds = 60;
    private String threadNamePrefix = "taskExecutor-";
    /**
     * @description: 實例化ThreadPoolTaskScheduler對象,用于創(chuàng)建ScheduledFuture<?> scheduledFuture
     */
    @Bean
    public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(taskSchedulerCorePoolSize);
        taskScheduler.setThreadNamePrefix(threadNamePrefix);
        taskScheduler.setWaitForTasksToCompleteOnShutdown(false);
        taskScheduler.setAwaitTerminationSeconds(awaitTerminationSeconds);
        /**需要實例化線程*/
        taskScheduler.initialize();
//        isinitialized = true;
        log.info("初始化ThreadPoolTaskScheduler ThreadNamePrefix=" + threadNamePrefix + ",PoolSize=" + taskSchedulerCorePoolSize
                + ",awaitTerminationSeconds=" + awaitTerminationSeconds);
        return taskScheduler;
    }
    /**
     * @description: 實例化ThreadPoolTaskExecutor對象,管理線程
     */
    @Bean("asyncTaskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(5);
        taskExecutor.setMaxPoolSize(50);
        taskExecutor.setQueueCapacity(200);
        taskExecutor.setKeepAliveSeconds(60);
        taskExecutor.setThreadNamePrefix("asyncTaskExecutor-");
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        taskExecutor.setAwaitTerminationSeconds(60);
        //修改拒絕策略為使用當(dāng)前線程執(zhí)行
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //初始化線程池
        taskExecutor.initialize();
        return taskExecutor;
    }
}

3.5 創(chuàng)建定時Job

DigitalEmpTask:

package com.merak.hyper.automation.quartz.task;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
/**
 * @version 1.0
 * @ClassName: BizOrderTask
 * @description: 任務(wù)隊列服務(wù)調(diào)度
 */
@Component
public class DigitalEmpTask {
    public static final Logger log = LoggerFactory.getLogger(DigitalEmpTask.class);
    @Scheduled(cron = "0/30 * * * * ?")
    @SchedulerLock(name = "digitalEmpTaskScheduler", lockAtMostFor = "PT25S", lockAtLeastFor = "PT25S")
    protected void digitalEmpTaskScheduler() {
        log.info("云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:" + DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD_HH_MM_SS));
        try { 
        } catch (Exception e) {
            log.error("云執(zhí)行調(diào)度中心1調(diào)度失敗,原因:" + e.getMessage());
        }  
    }
}

四、結(jié)果分析

1.分別啟動兩個服務(wù)節(jié)點,配置如下:

server:
  port: 12105
  servlet:
    context-path: /automation-quartz-one

server:
  port: 12106
  servlet:
    context-path: /automation-quartz-two

2.運行日志(片斷)

節(jié)點automation-quartz-one 運行日志:
2023-02-22 12:01:00.143 [taskExecutor-1] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:01:00
2023-02-22 12:05:00.114 [taskExecutor-3] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:05:00
2023-02-22 12:05:30.122 [taskExecutor-6] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:05:30
2023-02-22 12:19:30.110 [taskExecutor-3] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:19:30

節(jié)點automation-quartz-two運行日志:
2023-02-22 12:01:30.109 [taskExecutor-3] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:01:30
2023-02-22 12:02:00.101 [taskExecutor-1] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:02:00
2023-02-22 12:02:30.105 [taskExecutor-2] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:02:30
2023-02-22 12:03:00.118 [taskExecutor-3] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:03:00
2023-02-22 12:03:30.101 [taskExecutor-4] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:03:30
2023-02-22 12:04:00.110 [taskExecutor-1] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:04:00
2023-02-22 12:04:30.111 [taskExecutor-5] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:04:30
2023-02-22 12:06:00.114 [taskExecutor-13] INFO <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:06:00
2023-02-22 12:06:30.108 [taskExecutor-14] INFO <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:06:30
2023-02-22 12:07:00.114 [taskExecutor-15] INFO <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:07:00
2023-02-22 12:07:30.115 [taskExecutor-1] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:07:30
2023-02-22 12:08:00.102 [taskExecutor-5] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:08:00
2023-02-22 12:08:30.103 [taskExecutor-11] INFO <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:08:30
2023-02-22 12:09:00.099 [taskExecutor-6] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:09:00
2023-02-22 12:09:30.113 [taskExecutor-3] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:09:30
2023-02-22 12:10:00.107 [taskExecutor-7] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:10:00
2023-02-22 12:10:30.110 [taskExecutor-15] INFO <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:10:30
2023-02-22 12:11:00.111 [taskExecutor-1] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:11:00
2023-02-22 12:11:30.100 [taskExecutor-5] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:11:30
2023-02-22 12:12:00.112 [taskExecutor-11] INFO <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:12:00
2023-02-22 12:12:30.102 [taskExecutor-6] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:12:30
2023-02-22 12:13:00.097 [taskExecutor-3] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:13:00
2023-02-22 12:13:30.107 [taskExecutor-14] INFO <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:13:30
2023-02-22 12:14:00.111 [taskExecutor-4] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:14:00
2023-02-22 12:14:30.106 [taskExecutor-8] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:14:30
2023-02-22 12:15:00.095 [taskExecutor-9] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:15:00
2023-02-22 12:15:30.101 [taskExecutor-10] INFO <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:15:30
2023-02-22 12:16:00.105 [taskExecutor-2] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:16:00
2023-02-22 12:16:30.130 [taskExecutor-12] INFO <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:16:30
2023-02-22 12:17:00.107 [taskExecutor-13] INFO <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:17:00
2023-02-22 12:17:30.113 [taskExecutor-7] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:17:30
2023-02-22 12:18:00.104 [taskExecutor-15] INFO <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:18:00
2023-02-22 12:18:30.112 [taskExecutor-1] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:18:30
2023-02-22 12:19:00.103 [taskExecutor-5] INFO  <DigitalEmpTask:46> - 云執(zhí)行調(diào)度中心1:任務(wù)開始執(zhí)行,時間:2023-02-22 12:19:00

3、shedlock表記錄信息:

到此這篇關(guān)于SpringBoot集成ShedLock實現(xiàn)分布式定時任務(wù)流程詳解的文章就介紹到這了,更多相關(guān)SpringBoot ShedLock內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Boot基礎(chǔ)學(xué)習(xí)之Mybatis操作中使用Redis做緩存詳解

    Spring Boot基礎(chǔ)學(xué)習(xí)之Mybatis操作中使用Redis做緩存詳解

    這篇文章主要給大家介紹了關(guān)于Spring Boot基礎(chǔ)學(xué)習(xí)之Mybatis操作中使用Redis做緩存的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧
    2018-11-11
  • 詳解MyBatis Plus中分頁插件的使用

    詳解MyBatis Plus中分頁插件的使用

    這篇文章主要為大家詳細介紹了MyBatis Plus中分頁插件使用的相關(guān)知識,文中的示例代碼講解詳細,具有一定的學(xué)習(xí)價值,感興趣的小伙伴可以了解一下
    2023-02-02
  • 新版SpringSecurity安全配置說明

    新版SpringSecurity安全配置說明

    這篇文章主要介紹了新版SpringSecurity安全配置說明,在 Spring Security 5.7.0-M2 中,我們棄用了WebSecurityConfigurerAdapter,因為我們鼓勵用戶轉(zhuǎn)向基于組件的安全配置,需要的朋友可以參考下
    2023-07-07
  • Java學(xué)習(xí)之緩沖流的原理詳解

    Java學(xué)習(xí)之緩沖流的原理詳解

    為了提高其數(shù)據(jù)的讀寫效率,Java中又定義了四種緩沖流,分別是:字節(jié)緩沖輸入流、字節(jié)緩沖輸出流、字符緩沖輸入流和字符緩沖輸出流。本文主要來和大家聊聊這些緩沖流的原理,希望對大家有所幫助
    2023-01-01
  • Java基礎(chǔ)類Class使用指南

    Java基礎(chǔ)類Class使用指南

    關(guān)于通過類名訪問class屬性,我朋友問過好幾次了,一直沒明白這個東西到底是什么?對此,我參照網(wǎng)友們的博客,總結(jié)了一些小知識,如發(fā)現(xiàn)錯誤,希望糾正,謝謝
    2015-12-12
  • Java日常練習(xí)題,每天進步一點點(58)

    Java日常練習(xí)題,每天進步一點點(58)

    下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-08-08
  • SpringBoot結(jié)合FreeMarker視圖渲染的實現(xiàn)

    SpringBoot結(jié)合FreeMarker視圖渲染的實現(xiàn)

    FreeMarker它允許開發(fā)人員使用模板和數(shù)據(jù)來生成輸出文本,如HTML網(wǎng)頁、電子郵件、配置文件和源代碼等,本文主要介紹了SpringBoot結(jié)合FreeMarker視圖渲染的實現(xiàn),感興趣的可以了解一下
    2024-03-03
  • 最新評論