SpringBoot(二)集成 Quartz:2.5.4

这篇具有很好参考价值的文章主要介绍了SpringBoot(二)集成 Quartz:2.5.4。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Quartz是一个广泛使用的开源任务调度框架,用于在Java应用程序中执行定时任务和周期性任务。它提供了强大的调度功能,允许您计划、管理和执行各种任务,从简单的任务到复杂的任务。

以下是Quartz的一些关键特点和功能:

  • 灵活的调度器:Quartz提供了一个高度可配置的调度器,允许您根据不同的时间表执行任务,包括固定的时间、每日、每周、每月、每秒等。您可以设置任务执行的时间和频率。
  • 多任务支持:Quartz支持同时管理和执行多个任务。您可以定义多个作业和触发器,并将它们添加到调度器中。
  • 集群和分布式调度:Quartz支持集群模式,可以在多台机器上协调任务的执行。这使得Quartz非常适合大规模和分布式应用,以确保任务的高可用性和负载均衡。
  • 持久化:Quartz可以将任务和调度信息持久化到数据库中,以便在应用程序重启时不会丢失任务信息。这对于可靠性和数据保持非常重要。
  • 错过任务处理:Quartz可以配置在任务错过执行时如何处理,例如,是否立即执行、延迟执行或丢弃任务。
  • 监听器:Quartz提供了各种监听器,可以用来监视任务的执行,以及在任务执行前后执行自定义操作。
  • 多种作业类型:Quartz支持不同类型的作业,包括无状态作业(Stateless Job)和有状态作业(Stateful
    Job)。这允许您选择最适合您需求的作业类型。
  • 插件机制:Quartz具有灵活的插件机制,可以扩展其功能。您可以创建自定义插件,以满足特定需求。
  • 丰富的API:Quartz提供了丰富的Java API,使任务调度的配置和管理非常方便。

依赖

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
            <version>2.5.4</version>
        </dependency>

配置

spring.quartz.job-store-type=jdbc
# The first boot uses ALWAYS
spring.quartz.jdbc.initialize-schema=never
spring.quartz.auto-startup=true
spring.quartz.startup-delay=5s
spring.quartz.overwrite-existing-jobs=true
spring.quartz.properties.org.quartz.scheduler.instanceName=ClusterQuartz
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
spring.quartz.properties.org.quartz.jobStore.class=org.springframework.scheduling.quartz.LocalDataSourceJobStore
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_
spring.quartz.properties.org.quartz.jobStore.isClustered=true
spring.quartz.properties.org.quartz.jobStore.acquireTriggersWithinLock=true
spring.quartz.properties.org.quartz.jobStore.misfireThreshold=12000
spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=5000
spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
spring.quartz.properties.org.quartz.threadPool.threadCount=1
spring.quartz.properties.org.quartz.threadPool.threadPriority=5
spring.quartz.properties.org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true


配置解释

spring.quartz.job-store-type=jdbc:指定使用数据库作为Quartz的作业存储。

spring.quartz.jdbc.initialize-schema=never:此属性设置为"never",表示不会自动初始化Quartz数据库架构。这意味着您需要手动创建Quartz数据库表,以便Quartz正常运行。您可以使用Quartz提供的SQL脚本来创建这些表。

spring.quartz.auto-startup=true:设置为true,表示Quartz在Spring Boot应用程序启动时自动启动。

spring.quartz.startup-delay=5s:Quartz启动延迟时间,设置为5秒。

spring.quartz.overwrite-existing-jobs=true:设置为true,表示如果任务已经存在,则覆盖现有的任务。

spring.quartz.properties.org.quartz.scheduler.instanceName=ClusterQuartz:为Quartz调度器设置实例名称。

spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO:Quartz调度器实例ID设置为"AUTO",这意味着它会自动分配一个唯一的实例ID。

spring.quartz.properties.org.quartz.jobStore.class=org.springframework.scheduling.quartz.LocalDataSourceJobStore:指定使用org.springframework.scheduling.quartz.LocalDataSourceJobStore作为作业存储。

spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate:指定使用PostgreSQL数据库的委托类。

spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_:为Quartz数据库表添加前缀,以避免与其他表冲突。

spring.quartz.properties.org.quartz.jobStore.isClustered=true:启用Quartz集群模式。

spring.quartz.properties.org.quartz.jobStore.acquireTriggersWithinLock=true:设置为true,以确保在获取触发器时使用锁来处理并发。

spring.quartz.properties.org.quartz.jobStore.misfireThreshold=12000:设置Quartz任务的超时时间,以确定任务是否错过执行。

spring.quartz.properties.org.quartz.jobStore.clusterCheckinInterval=5000:设置节点之间检查其状态的时间间隔。

spring.quartz.properties.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool:定义Quartz线程池的类型。

spring.quartz.properties.org.quartz.threadPool.threadCount=1:设置线程池中线程的数量。

spring.quartz.properties.org.quartz.threadPool.threadPriority=5:设置线程的优先级。

spring.quartz.properties.org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true:允许线程继承初始化线程的类加载器。

job


import cn.hutool.extra.spring.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.stereotype.Component;

/**
 * @author Wang
 */
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Slf4j
@Component
public class DealerJob implements Job {

    @Override
    public void execute(JobExecutionContext context) {
        log.info("start Quartz job name: {}", context.getJobDetail().getKey().getName());
        DealerImportFacade dealerImportFacade = SpringUtil.getBean(DealerImportFacade.class);

        log.info(" start import US dealer data ");
        RequestContext.current().set(RequestContextCons.REGION, DataSourceEnum.US.toString().toLowerCase());
        try {
//            dealerImportFacade.importUsDealerData();
            log.info(" end import US dealer data ");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
}

controller


import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

/**
 * @author Wang
 */
@RequiredArgsConstructor
@Slf4j
@RestController
@RequestMapping("/schedule/job")
public class ScheduleJobController {

    final ScheduleJobService scheduleJobService;
    final QuartzHelper quartzHelper;

    @PostMapping
    public AjaxRespData<ScheduleJobVO> addJob(@Valid @RequestBody AddScheduleJobDTO scheduleJobDTO) {
        ScheduleJobEntity scheduleJobEntity = BeanConvertUtils.convert(scheduleJobDTO, ScheduleJobEntity.class);
        scheduleJobEntity.init();
        scheduleJobEntity.setStatus(EnumScheduleJobStatus.RUN);
        ScheduleJobData data = scheduleJobService.save(scheduleJobEntity);
        quartzHelper.scheduleJob(data);
        return AjaxRespData.success(BeanConvertUtils.convert(data, ScheduleJobVO.class));
    }

    @DeleteMapping("/{jobId}")
    public AjaxRespData<Void> removeJob(@PathVariable("jobId") String jobId) {
        ScheduleJobEntity scheduleJobEntity = scheduleJobService.checkExist(jobId, EnumError.E30001);
        scheduleJobService.remove(jobId);
        quartzHelper.remove(scheduleJobEntity);
        return AjaxRespData.success();
    }

    @PutMapping("/{jobId}")
    public AjaxRespData<ScheduleJobVO> updateJob(@PathVariable String jobId, @Valid @RequestBody AddScheduleJobDTO scheduleJobDTO) {
        ScheduleJobEntity scheduleJobEntity = BeanConvertUtils.convert(scheduleJobDTO, ScheduleJobEntity.class);
        scheduleJobEntity.setId(jobId);
        ScheduleJobData data = scheduleJobService.update(scheduleJobEntity);
        quartzHelper.scheduleJob(data);
        return AjaxRespData.success(BeanConvertUtils.convert(data, ScheduleJobVO.class));
    }

    @GetMapping("/{jobId}")
    public AjaxRespData<ScheduleJobVO> getJob(@PathVariable("jobId") String jobId) {
        ScheduleJobEntity scheduleJobEntity = scheduleJobService.checkExist(jobId, EnumError.E30001);
        return AjaxRespData.success(BeanConvertUtils.convert(scheduleJobEntity, ScheduleJobVO.class));
    }


    @PutMapping("/operate")
    public void operateJob(@Valid @RequestBody AddScheduleJobDTO scheduleJobDTO) {
        ScheduleJobEntity scheduleJobEntity = scheduleJobService.checkExist(scheduleJobDTO.getId(), EnumError.E30001);
        scheduleJobEntity.setStatus(scheduleJobDTO.getStatus());
        scheduleJobService.update(scheduleJobEntity);
        quartzHelper.operateJob(scheduleJobDTO.getStatus(), scheduleJobEntity);
    }

}

service


import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author Wang
 */
@RequiredArgsConstructor
@Slf4j
@Service
public class ScheduleJobService extends BaseService<ScheduleJobEntity, ScheduleJobData> {

    final ScheduleJobRepository scheduleJobRepository;
    final QuartzHelper quartzHelper;

    @PostConstruct
    public void init(){
        log.info("init schedule job...");
        List<ScheduleJobEntity> jobs = this.getRepository().findAll();
        for (ScheduleJobEntity job : jobs) {
            quartzHelper.scheduleJob(job);
            quartzHelper.operateJob(EnumScheduleJobStatus.PAUSE, job);
            if (job.getStatus().equals(EnumScheduleJobStatus.RUN)) {
                quartzHelper.operateJob(EnumScheduleJobStatus.RUN, job);
            }
        }
        log.info("init schedule job completed...");
    }

    @Override
    public BaseRepository<ScheduleJobEntity> getRepository() {
        return scheduleJobRepository;
    }


}

helper


import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.stereotype.Component;

import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Objects;

/**
 * @author Wang
 */
@RequiredArgsConstructor
@Slf4j
@Component
public class QuartzHelper {

    final Scheduler scheduler;

    public void scheduleJob(ScheduleJobEntity jobInfo) {

        JobKey jobKey = JobKey.jobKey(jobInfo.getJobName(), jobInfo.getJobGroup());
        try {
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            if (Objects.nonNull(jobDetail)){
                scheduler.deleteJob(jobKey);
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

        JobDetail jobDetail = JobBuilder.newJob(getJobClass(jobInfo.getType()))
                .withIdentity(jobKey)
                .build();

        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(jobInfo.getTriggerName(), jobInfo.getTriggerGroup()).startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule(jobInfo.getCronExpression()))
                .build();

        try {
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            log.error(e.getMessage(), e);
        }
    }

    public void rescheduleJob(ScheduleJobEntity job) {

        TriggerKey triggerKey = new TriggerKey(job.getTriggerName(), job.getTriggerGroup());
        try {
            CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);

            CronTrigger newCronTrigger = cronTrigger.getTriggerBuilder()
                    .withIdentity(triggerKey)
                    .withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
                    .build();

            scheduler.rescheduleJob(triggerKey, newCronTrigger);
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

    public void remove(ScheduleJobEntity job) {
        TriggerKey triggerKey = new TriggerKey(job.getTriggerName(), job.getTriggerGroup());
        try {
            scheduler.pauseTrigger(triggerKey);
            scheduler.unscheduleJob(triggerKey);
            scheduler.deleteJob(JobKey.jobKey(job.getTriggerName(), job.getTriggerGroup()));
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

    public void unscheduleJob(ScheduleJobEntity job) {

        TriggerKey triggerKey = new TriggerKey(job.getTriggerName(), job.getTriggerGroup());
        try {
            scheduler.unscheduleJob(triggerKey);
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

    public void operateJob(EnumScheduleJobStatus status, ScheduleJobEntity job) {
        JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());
        try {
            switch (status) {
                case RUN:
                    scheduler.resumeJob(jobKey);
                    break;
                case PAUSE:
                    scheduler.pauseJob(jobKey);
                    break;
                default:
                    throw new IllegalArgumentException();
            }
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

    public String nextTime(ScheduleJobEntity job) {
        TriggerKey triggerKey = new TriggerKey(job.getTriggerName(), job.getTriggerGroup());
        try {
            Trigger trigger = scheduler.getTrigger(triggerKey);
            Date nextFireTime = trigger.getNextFireTime();
            return DateUtil.format(nextFireTime, DateTimeFormatter.ISO_DATE_TIME);
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

    private Class<? extends Job> getJobClass(EnumScheduleJobType type) {
        Class<? extends Job> clazz;
        switch (type) {
            case DEALER_IMPORT:
                clazz = DealerJob.class;
                break;
//            case SECONDARY_INVITING_EXPIRE:
//                clazz = MockDeviceReportJob.class;
//                break;
            default:
                throw new IllegalArgumentException();
        }
        return clazz;
    }
}

最终效果

实例1,8281
SpringBoot(二)集成 Quartz:2.5.4,分布式,spring boot,后端,java,Quartz
实例2,8282
SpringBoot(二)集成 Quartz:2.5.4,分布式,spring boot,后端,java,Quartz

踩坑

定时任务执行间隔,最低设置一分钟文章来源地址https://www.toymoban.com/news/detail-722283.html

到了这里,关于SpringBoot(二)集成 Quartz:2.5.4的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring Boot进阶(68):如何用SpringBoot轻松实现定时任务?集成Quartz来帮你!(附源码)

            Quartz是一个非常流行的开源调度框架,它提供了许多强大的功能,如定时任务调度、作业管理、任务持久化等。而SpringBoot是目前Java开发中非常流行的框架之一,其对各种开源框架集成非常方便。本篇文章将介绍如何在SpringBoot中集成Quartz,以便于更好的管理和调度

    2024年02月07日
    浏览(51)
  • Spring Boot 中的 Zookeeper 分布式锁

    分布式锁是分布式系统中常用的一个同步工具,它可以在多个进程之间协调访问共享资源,避免数据不一致或重复处理。在分布式环境中,由于网络通信的延迟和节点故障等原因,传统的锁机制无法满足需求。因此,分布式锁成为了实现分布式同步的常用方案之一。 Zookeepe

    2024年02月12日
    浏览(39)
  • spring boot + minio 分布式文件上传

    1、分布式文件系统 简单理解为:一个计算机无法存储海量的文件,通过网络将若干计算机组织起来共同去存储海量的文件,去接收海量用户的请求,这些组织起来的计算机通过网络进行通信。 好处: 一台计算机的文件系统处理能力扩充到多台计算机同时处理。 一台计算机

    2024年02月08日
    浏览(55)
  • Spring Boot 中的 Seata 分布式事务

    在分布式系统中,保证数据的一致性是一个非常重要的问题。传统的 ACID 事务模型虽然能够保证单个数据库的数据一致性,但是在分布式系统中却很难实现。因此,近年来出现了一些新的事务模型,其中 Seata 就是一种比较流行的模型。 在本文中,我们将介绍 Spring Boot 中的

    2024年02月09日
    浏览(33)
  • Spring Boot如何实现分布式消息队列

    在分布式系统中,消息队列是非常重要的一部分,可以帮助开发人员实现异步处理、解耦系统、提高系统可靠性等。本文将介绍如何使用 Spring Boot 实现分布式消息队列。 消息队列是一种存储消息的容器,可以缓存消息并在需要的时候按照一定的规则将消息发送给消费者。常

    2024年02月14日
    浏览(41)
  • 【Spring Boot 3】【Redis】分布式锁

    软件开发是一门实践性科学,对大多数人来说,学习一种新技术不是一开始就去深究其原理,而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中,每次学习新技术总是要花费或多或少的时间、检索不止一篇资料才能得出一个可工作的DEMO,这占用了我大量的时

    2024年01月18日
    浏览(32)
  • Spring Boot 中的 Redis 分布式锁

    在分布式系统中,多个进程同时访问共享资源时,很容易出现并发问题。为了避免这些问题,我们可以使用分布式锁来保证共享资源的独占性。Redis 是一款非常流行的分布式缓存,它也提供了分布式锁的功能。在 Spring Boot 中,我们可以很容易地使用 Redis 分布式锁来管理并发

    2024年02月11日
    浏览(40)
  • SpringBoot集成Skywalking实现分布式链路追踪

    官方网址:  Apache SkyWalking 官方文档:  SkyWalking 极简入门 | Apache SkyWalking 下载地址 :Downloads | Apache SkyWalking  Agent :以探针的方式进行请求链路的数据采集,并向管理服务上报; OAP-Service :接收数据,完成数据的存储和展示; Storage :数据的存储层,支持ElasticSearch、Mysql、

    2024年02月03日
    浏览(43)
  • 分布式任务调度(00)--Quartz

    调度器 :工厂类创建Scheduler,根据触发器定义的时间规则调度任务 任务:Job表示被调度的任务 触发器:Trigger 定义调度时间的元素,按啥时间规则执行任务。一个Job可被多个Trigger关联,但是一个Trigger 只能关联一个Job 执行任务调度核心类QuartzSchedulerThread: 调度线程从JobSt

    2024年02月05日
    浏览(53)
  • 分布式id生成方案及springboot进行集成

    UUID(Universally Unique Identifier) 即通用唯一识别码,是一种由网络软件使用的标识符,它是由IP地址、当前时间戳、随机数、节点等多个部分组成,具有唯一性。但是,UUID方案的缺点是,生成的id较长,不便于存储和使用。 Snowflake算法 它是Twitter公司开源的一个分布式唯一ID生成器

    2023年04月08日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包