天天看點

spring booth整合quartz架構前言一、提前準備工作二、使用步驟總結

引入quartz# 系列文章目錄

提示:這裡可以添加系列文章的所有文章的目錄,目錄需要自己手動添加

例如:第一章 Python 機器學習入門之pandas的使用

提示:寫完文章後,目錄可以自動生成,如何生成可參考右邊的幫助文檔

文章目錄

  • 前言
  • 一、提前準備工作
  • 二、使用步驟
    • 1.引入庫
    • 2.讀入資料
    • 3.踩過的坑
  • 總結

前言

提示:這裡可以添加本文要記錄的大概内容:

例如:随着人工智能的不斷發展,機器學習這門技術也越來越重要,很多人都開啟了學習機器學習,本文就介紹了機器學習的基礎内容。

提示:以下是本篇文章正文内容,下面案例可供參考

一、提前準備工作

1.到quartz官網下載下傳自己需要的版本

http://www.quartz-scheduler.org/downloads/

2.我下載下傳的是2.3.0版本,解壓之後如下

spring booth整合quartz架構前言一、提前準備工作二、使用步驟總結

3.在解壓之後的如下檔案夾下,有quartz所需要的建表語句,選擇跟你的資料庫相一緻的sql執行

quartz-2.3.0-SNAPSHOT\src\org\quartz\impl\jdbcjobstore。我選擇的是tables_mysql_innodb.sql

spring booth整合quartz架構前言一、提前準備工作二、使用步驟總結

4.執行之後再自己的資料庫中即得到如下這些表格

spring booth整合quartz架構前言一、提前準備工作二、使用步驟總結

5.quartz表格的作用,如下:

QRTZ_CALENDARS 以 Blob 類型存儲 Quartz 的 Calendar 資訊

QRTZ_CRON_TRIGGERS 存儲 Cron Trigger,包括 Cron表達式和時區資訊

QRTZ_FIRED_TRIGGERS 存儲與已觸發的 Trigger 相關的狀态資訊,以及相聯 Job的執行資訊 QRTZ_PAUSED_TRIGGER_GRPS 存儲已暫停的 Trigger 組的資訊

QRTZ_SCHEDULER_STATE 存儲少量的有關 Scheduler 的狀态資訊,和别的 Scheduler執行個體(假如是用于一個叢集中)

QRTZ_LOCKS 存儲程式的悲觀鎖的資訊(假如使用了悲觀鎖)

QRTZ_JOB_DETAILS 存儲每一個已配置的 Job 的詳細資訊

QRTZ_JOB_LISTENERS 存儲有關已配置的 JobListener 的資訊

QRTZ_SIMPLE_TRIGGERS 存儲簡單的Trigger,包括重複次數,間隔,以及已觸的次數

QRTZ_BLOG_TRIGGERS Trigger 作為 Blob 類型存儲(用于 Quartz 使用者用 JDBC建立他們自己定制的 Trigger 類型,JobStore 并不知道如何存儲執行個體的時候)

QRTZ_TRIGGER_LISTENERS 存儲已配置的 TriggerListener 的資訊

QRTZ_TRIGGERS 存儲已配置的 Trigger 的資訊

二、使用步驟

1.引入庫

這裡是引用

pom檔案中添加如下依賴:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>
        <!--quartz的啟動資料源依賴c3p0,是以還需要引入該依賴,否則啟動時有問題,可自己驗證一下-->
         <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.5</version>
        </dependency>
           

2.讀入資料

定時處理器基本的增删改查,如下隻做參考:

@Slf4j
@RestController
@RequestMapping("/quartz")
public class QuartzJobController {
    @Autowired
    private JobExecuteDetailsService jobExecuteDetailsService ;
    @Autowired
    @Qualifier("CronScheduler")
    private Scheduler cronScheduler;
    @Autowired
    private JobExecuteDetailsMapper jobExecuteDetailsMapper;

    /**
     * 添加定時任務
     *
     * @param vo
     * @return
     */
    @PostMapping("/addQuartz")
    @ResponseBody
    public String addQuartz(@RequestBody @Valid JobExecuteDetailsVO vo) {
        log.info("新增任務:"+vo.getJobName());
        JobKey jobKey = new JobKey(vo.getJobName(), vo.getJobGroupName());
        vo.setJobCreated(new Date());
        try {
            if (null == cronScheduler.getJobDetail(jobKey)) {
                cronScheduler.deleteJob(jobKey);
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        try {
            Class clz = Class.forName(vo.getJobClassName());
            clz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        int tableId = jobExecuteDetailsMapper.insert(JobExecuteDetailsMapstruct.INSTANCE.voToDo(vo));
        JobDetail jobDetail = JobBuilder.newJob(QquartzJob.class)
                .usingJobData("command", vo.getCommand())
                .usingJobData("tableId", tableId)
                .withIdentity(vo.getJobName(), vo.getJobGroupName())
                .build();
        CronTrigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("trigger" + vo.getJobName(), "triggetGroup")
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule(vo.getCron()))
                .build();
        try {
            cronScheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return "新增定時任務"+vo.getJobName()+"成功";
    }
    /**
     * 立即執行一次定時任務
     */
    @PostMapping("/trigger")
    public  String trigger(@RequestBody @Valid JobExecuteDetailsVO vo) {
        log.info("單次觸發定時任務:"+vo.getJobName());
        try {
            JobKey key = new JobKey(vo.getJobName(),vo.getJobGroupName());
            cronScheduler.triggerJob(key);
        } catch (SchedulerException e) {
            e.printStackTrace();
             log.error("單次觸發定時任務:"+vo.getJobName()+"失敗");
        }
        return "ok";
    }

    /**
     * 檢視所有定時任務
     *
     * @param param
     * @return
     */
    @PostMapping(value = "/batchPageJobList")
    public AppResult<Page<JobExecuteDetailsVO>> batchPageJobList(@RequestBody JobExecuteDetailParam param) {
        try {
            return AppResultBuilder.success(jobExecuteDetailsService.batchPageJobList(param));
        } catch (Exception e) {
            log.error("分頁查詢任務清單,異常", e);
            return AppResultBuilder.fail("查詢失敗,系統異常");
        }
    }

    /**
     * 根據id删除定時任務  同時需要删除對應的觸發器
     *
     * @param vo
     */
    @PostMapping("/deleteJob")
    public void deleteJob(@RequestBody @Valid JobExecuteDetailsVO vo) {
        log.info("删除定時任務"+vo.getJobName());
        String jobName=vo.getJobName();
        String jobGroupGroupName=vo.getJobGroupName();
        TriggerKey triggerKey= TriggerKey.triggerKey(jobName,jobGroupGroupName);
        JobKey jobKey=new JobKey(jobName,jobGroupGroupName);
        try {
            cronScheduler.pauseTrigger(triggerKey);
            cronScheduler.unscheduleJob(triggerKey);
            cronScheduler.deleteJob(jobKey);
            jobExecuteDetailsMapper.deleteById(vo.getId());
        } catch (SchedulerException e) {
            e.printStackTrace();
            log.error("删除定時任務"+vo.getJobName()+"失敗");
        }
    }


    /**
     * 暫停/終止定時任務
     *
     * @param vo
     */
    @PostMapping("/pauseJob")
    public void pauseJob(@RequestBody @Valid JobExecuteDetailsVO vo) {
        log.info("停止任務"+vo.getJobName());
        JobKey jobKey=new JobKey(vo.getJobName(),vo.getJobGroupName());
        try {
            cronScheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
            log.error("停止任務"+vo.getJobName()+"失敗");
        }
    }

    /**
     * 繼續執行定時任務
     *
     * @param vo
     */
    @PostMapping("/resumeJob")
    public void resumeJob(@RequestBody @Valid JobExecuteDetailsVO vo) {
        log.info("恢複任務");
        JobKey jobKey=new JobKey(vo.getJobName(),vo.getJobGroupName());
        try {
            cronScheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
            log.error("恢複任務"+vo.getJobName()+"失敗");
        }
    }

}
           

3.踩過的坑

1.quartz的Job類不受spring管理,是以Job中如果想要注入對象,是需要單獨建立一個管理類進行引入。管理類如下

@Component

public class ApplicationContextUtil implements ApplicationContextAware {

private static ApplicationContext applicationContext;

public static ApplicationContext getApplicationContext() {
    return applicationContext;
}


@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    ApplicationContextUtil.applicationContext = applicationContext;

}


public static Object getBean(String beanName) {
    return applicationContext.getBean(beanName);
}
}
           

2.在Job中引用的時候可以參考如下代碼

private JobExecuteDetailsService jobExecuteDetailsService = (JobExecuteDetailsService) ApplicationContextUtil.getBean("jobExecuteDetailsServiceImpl");
           

3.因為quartz是不受spring管理的,是以quartz的配置檔案quartz.properties 中需要添加單獨資料源配置

參考如下:

org.quartz.threadPool.threadCount = 5
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = myDS

org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL =
org.quartz.dataSource.myDS.user =
org.quartz.dataSource.myDS.password =
org.quartz.dataSource.myDS.maxConnections =5
           

總結

到此為止就是我在spring boot整合quartz額過程,以及這個過程中踩過的一些坑,大家可以參考一下,完整的工程代碼稍後會更新到github上。可能版本不一緻,遇到的問題也不一樣,祝你們成功~