ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpringBoot 集成 Qurtz 集群

2022-03-29 15:03:27  阅读:148  来源: 互联网

标签:exception Qurtz SpringBoot getName 集群 scheduler jobKey getGroup log


添加依赖

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

SQL Scheme 可以打开依赖项 org.quartz-scheduler.quartzorg.quartz.impl.jdbcjobstore 下找到。

yml 配置

spring:
  quartz:
    job-store-type: jdbc
    jdbc:
      initialize-schema: never
    startup-delay: 120S
    wait-for-jobs-to-complete-on-shutdown: true
    overwrite-existing-jobs: false
    properties:
      org.quartz:
        scheduler:
          instanceName: task-scheduler
          instanceId: AUTO
          batchTriggerAcquisitionMaxCount: 1
        jobStore:
          class: org.quartz.impl.jdbcjobstore.JobStoreTX
          driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
          tablePrefix: QRTZ_
          isClustered: true
          clusterCheckinInterval: 15000
          useProperties: false
        threadPool:
          class: org.quartz.simpl.SimpleThreadPool
          threadCount: 100
          threadPriority: 5

代码

package com.ibmp.quartz.service.impl;

import com.ibmp.common.exception.CustomException;
import com.ibmp.quartz.domain.dto.CronTriggerDTO;
import com.ibmp.quartz.domain.dto.JobInfoDTO;
import com.ibmp.quartz.service.TaskService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.*;

/**
 * Task 任务 Service 实现
 *
 * @author seliote
 * @version 2021-10-20
 */
@Slf4j
@Service
public class TaskServiceImpl implements TaskService {

    private final Scheduler scheduler;

    @Autowired
    public TaskServiceImpl(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

    @Override
    public JobDataMap createJobData(Map<?, ?> map) {
        return new JobDataMap(map);
    }

    @Override
    public JobDetail createJobDetail(Class<? extends Job> jobClass, JobKey jobKey, String desc,
                                     JobDataMap jobDataMap, boolean requestRecovery) {
        return JobBuilder.newJob(jobClass)
                .withIdentity(jobKey)
                .withDescription(desc)
                .usingJobData(jobDataMap)
                .requestRecovery(requestRecovery)
                .storeDurably(true)
                .build();
    }

    @Override
    public CronTrigger createCronTrigger(TriggerKey triggerKey, String cronExpression,
                                         String desc, JobDataMap jobDataMap) {
        if (!CronExpression.isValidExpression(cronExpression)) {
            log.error("{} - {} cron {} is illegal", triggerKey.getGroup(), triggerKey.getName(), cronExpression);
            throw new CustomException("Illegal cron trigger");
        }
        return TriggerBuilder.newTrigger()
                .withIdentity(triggerKey)
                .withDescription(desc)
                .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
                .usingJobData(jobDataMap)
                .build();
    }

    @Override
    @SneakyThrows
    public void addTask(JobDetail jobDetail, CronTrigger cronTrigger) {
        try {
            scheduler.scheduleJob(jobDetail, cronTrigger);
            log.info("Add task {} - {}", jobDetail.getKey().getGroup(), jobDetail.getKey().getName());
        } catch (SchedulerException exception) {
            log.error("Failed create {} - {}, {}",
                    jobDetail.getKey().getGroup(), jobDetail.getKey().getName(), exception.getMessage());
            throw exception;
        }
    }

    @Override
    @SneakyThrows
    public void deleteTask(JobKey jobKey) {
        try {
            scheduler.deleteJob(jobKey);
            log.info("Delete task {} -{}", jobKey.getGroup(), jobKey.getName());
        } catch (SchedulerException exception) {
            log.error("Failed delete task {} -{}, {}", jobKey.getGroup(), jobKey.getName(), exception.getMessage());
            throw exception;
        }
    }

    @Override
    @SneakyThrows
    public void pauseTask(JobKey jobKey) {
        try {
            scheduler.pauseJob(jobKey);
            log.info("Pause task {} -{}", jobKey.getGroup(), jobKey.getName());
        } catch (SchedulerException exception) {
            log.error("Failed pause task {} -{}, {}", jobKey.getGroup(), jobKey.getName(), exception.getMessage());
            throw exception;
        }
    }

    @Override
    @SneakyThrows
    public void resumeTask(JobKey jobKey) {
        try {
            scheduler.resumeJob(jobKey);
            log.info("Resume task {} -{}", jobKey.getGroup(), jobKey.getName());
        } catch (SchedulerException exception) {
            log.error("Failed resume task {} -{}, {}", jobKey.getGroup(), jobKey.getName(), exception.getMessage());
            throw exception;
        }
    }

    @Override
    @SneakyThrows
    public void rescheduleJob(TriggerKey triggerKey, CronTrigger cronTrigger) {
        try {
            scheduler.rescheduleJob(triggerKey, cronTrigger);
            log.info("Reschedule trigger {} -{}", triggerKey.getGroup(), triggerKey.getName());
        } catch (SchedulerException exception) {
            log.error("Failed reschedule trigger {} -{}, {}", triggerKey.getGroup(), triggerKey.getName(), exception.getMessage());
            throw exception;
        }
    }

    @Override
    @SneakyThrows
    public boolean exists(JobKey jobKey) {
        try {
            return scheduler.checkExists(jobKey);
        } catch (SchedulerException exception) {
            log.error("Failed check exists for task {} -{}, {}", jobKey.getGroup(), jobKey.getName(), exception.getMessage());
            throw exception;
        }
    }

    @Override
    public List<JobInfoDTO> listAll() {
        try {
            List<JobInfoDTO> all = new ArrayList<>();
            Set<JobKey> allJobs = scheduler.getJobKeys(GroupMatcher.anyGroup());
            for (JobKey job : allJobs) {
                JobInfoDTO dto = new JobInfoDTO();
                dto.setJobName(job.getName());
                dto.setJobGroupName(job.getGroup());
                JobDetail jobDetail;
                try {
                    jobDetail = scheduler.getJobDetail(job);
                } catch (JobPersistenceException e) {
                    log.warn("Task {}-{} not persistence!", job.getGroup(), job.getName());
                    continue;
                }
                dto.setDescription(jobDetail.getDescription());
                List<? extends Trigger> triggers = scheduler.getTriggersOfJob(job);
                for (Trigger t : triggers) {
                    CronTriggerDTO cronTriggerDTO = new CronTriggerDTO();
                    TriggerKey triggerKey = t.getKey();
                    cronTriggerDTO.setTriggerName(triggerKey.getName());
                    cronTriggerDTO.setTriggerGroup(triggerKey.getGroup());
                    if (t instanceof CronTrigger) {
                        cronTriggerDTO.setCronExpr(((CronTrigger) t).getCronExpression());
                    }
                    dto.getCron().add(cronTriggerDTO);
                }
                if (triggers.size() != 0) {
                    // 最近一次触发时间
                    triggers.sort((v1, v2) -> {
                        Date v1Pre = v1.getPreviousFireTime() == null ?
                                new Date(Instant.now().toEpochMilli()) : v1.getPreviousFireTime();
                        Date v2Pre = v2.getPreviousFireTime() == null ?
                                new Date(Instant.now().toEpochMilli()) : v2.getPreviousFireTime();
                        return v1Pre.compareTo(v2Pre);
                    });
                    Trigger preTrigger = triggers.get(triggers.size() - 1);
                    dto.setPreFire(preTrigger.getPreviousFireTime());
                    // 最近一次的执行状态
                    Trigger.TriggerState state = scheduler.getTriggerState(preTrigger.getKey());
                    dto.setStatus(state == null ? Trigger.TriggerState.ERROR.name() : state.name());
                    // 下一次触发时间
                    triggers.sort(Comparator.comparing(Trigger::getNextFireTime));
                    dto.setNextFire(triggers.get(0).getNextFireTime());
                }
                all.add(dto);
            }
            all.sort(Comparator.comparing(JobInfoDTO::getJobGroupName));
            return all;
        } catch (SchedulerException exception) {
            log.error("Can not list all job", exception);
            throw new CustomException("查找触发器失败");
        }
    }

    @Override
    @SneakyThrows
    public void trigger(JobKey jobKey) {
        try {
            scheduler.triggerJob(jobKey);
        } catch (SchedulerException exception) {
            log.error("Failed trigger for task {} -{}, {}", jobKey.getGroup(), jobKey.getName(), exception.getMessage());
            throw exception;
        }
    }

    @SneakyThrows
    @Override
    public void cleanTask() {
        Set<JobKey> allJobs = scheduler.getJobKeys(GroupMatcher.anyGroup());
        for (JobKey job : allJobs) {
            if (!exists(job)) {
                deleteTask(job);
            }
        }
    }
}

标签:exception,Qurtz,SpringBoot,getName,集群,scheduler,jobKey,getGroup,log
来源: https://www.cnblogs.com/seliote/p/16071785.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有