Heim  >  Artikel  >  Java  >  Wie SpringBoot ShedLock integriert, um verteilte geplante Aufgaben zu implementieren

Wie SpringBoot ShedLock integriert, um verteilte geplante Aufgaben zu implementieren

WBOY
WBOYnach vorne
2023-05-13 12:55:061011Durchsuche

    1. Hintergrund

    Wenn der Projektdienst in einem Cluster bereitgestellt wird, enthält der Code geplante Aufgaben für alle. Es ist jedoch nicht angebracht, jeden Knoten geplante Aufgaben ausführen zu lassen. ShedLock in SpringBoot kann dieses Problem sehr gut lösen. Im Folgenden werde ich detailliert vorstellen, wie SpringBoot ShedLock integriert und wie ShedLock verteiltes Timing implementiert.

    2. Was ist ShedLock?

    shedlock erforderliche Abhängigkeitspakete: #🎜🎜 #
    <!-- 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>

    Abhängigkeitspaketbaum:

    Wie SpringBoot ShedLock integriert, um verteilte geplante Aufgaben zu implementieren

    1.2 Datenbankverbindungsinformationen konfigurieren #🎜🎜 #

    Server :

    Port: 8105

    Spring:

    Datenquelle:

    URL: jdbc:mysql://127.0.0.1:3306/testjdbc? useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/ Shanghai

    Benutzername: root

    Passwort: 123456Wie SpringBoot ShedLock integriert, um verteilte geplante Aufgaben zu implementieren Treiberklassenname: com.mysql.cj.jdbc.Driver

    Typ: com.mysql.cj.jdbc.MysqlDataSource# 🎜🎜#

    1.3 MySQL-Datentabelle erstellen
    CREATE TABLE `shedlock` (
    	`name`  varchar(64) NOT NULL COMMENT &#39;name&#39; ,
    	`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
    ;

    1.4 LockProvider konfigurieren

    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 Hauptstartup-Klasse 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: 工单任务调度
     */
    // 开启定时器
    @EnableScheduling
    // 开启定时任务锁,指定一个默认的锁的时间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对象,用于创建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);
            //修改拒绝策略为使用当前线程执行
            taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            //初始化线程池
            taskExecutor.initialize();
            return taskExecutor;
        }
    }

    1.5 Geplanten Job erstellen

    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: 任务队列服务调度
     */
    @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("云执行调度中心1:任务开始执行,时间:" + DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD_HH_MM_SS));
            try { 
            } catch (Exception e) {
                log.error("云执行调度中心1调度失败,原因:" + e.getMessage());
            }  
        }
    }

    4. Ergebnis Analyse

    1 .Starten Sie jeweils zwei Dienstknoten, die Konfiguration ist wie folgt:

    server:

    Port: 12105

    Servlet:

    Kontextpfad: /automation-quartz -one

    server:

    Port: 12106

    Servlet:

    Kontextpfad: /automation-quartz- zwei

    #🎜🎜 #2. Laufprotokoll (Ausschnitt)

    Knotenautomatisierung-Quarz-eins Laufprotokoll:

    2023-02-22 12:01:00.143 [taskExecutor-1] INFO < ;DigitalEmpTask:46> :05:00.114 [taskExecutor-3] INFO 05:30.122 [taskExecutor-6] INFO – Cloud Execution Scheduling Center 1: Task beginnt mit der Ausführung, Zeit: 22.02.2023 12:05:30
    22.02.2023 12:19 :30.110 [taskExecutor-3] INFO

    Knotenautomatisierung-Quarz-Zwei-Laufprotokoll:
    2023-02-22 12:01:30.109 [taskExecutor-3] INFO <46>
    <46>
    <46>
    <46>
    <46><46>
    <46>
    <
    <46 cloud execution scheduling center aufgabe beginnt mit der ausf zeit:><46>
    <46>
    <46>
    <46>
    <46>
    <46>
    <46>
    <46>
    <46><46>
    <46>

    <46>
    <46>
    <46>
    <46>
    <46>
    <46>
    <46>
    <46>
    <46>
    <46 cloud execution scheduling center ausf der aufgabe gestartet zeit:><46>
    <46>
    <46>

    Wie SpringBoot ShedLock integriert, um verteilte geplante Aufgaben zu implementieren

    Das obige ist der detaillierte Inhalt vonWie SpringBoot ShedLock integriert, um verteilte geplante Aufgaben zu implementieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen