springboot使用quartz集羣定時任務

簡介

Quartz是一個徹底由java編寫的開源做業調度框架。不要讓做業調度這個術語嚇着你。儘管Quartz框架整合了許多額外功能, 但就其簡易形式看,你會發現它易用得簡直讓人受不了!。簡單地建立一個實現org.quartz.Job接口的java類。Job接口包含惟一的方法:java

public void execute(JobExecutionContext context) throws JobExecutionException;mysql

在你的Job接口實現類裏面,添加一些邏輯到execute()方法。一旦你配置好Job實現類並設定好調度時間表,Quartz將密切注意剩餘時間。當調度程序肯定該是通知你的做業的時候,Quartz框架將調用你Job實現類(做業類)上的execute()方法並容許作它該作的事情。無需報告任何東西給調度器或調用任何特定的東西。僅僅執行任務和結束任務便可。若是配置你的做業在隨後再次被調用,Quartz框架將在恰當的時間再次調用它。linux

單機部署問題

單機模式下的定時任務調用很簡單,有不少可實現的方案,這裏很少說了,例如spring schedule,java timer等。web

這裏說一下集羣部署的狀況下,定時任務的使用。這種狀況下,quartz是一個比較好的選擇。簡單,穩定。spring

想象一下,如今有 A , B , C  3 臺機器同時做爲集羣服務器對外統一提供 SERVICE :sql

A , B , C   3 臺機器上各有一個 QUARTZ  Job,它們會按照即定的 SCHEDULE 自動執行各自的任務。數據庫

先不說實現什麼功能,這樣的架構有點像多線程。因爲三臺SERVER 裏都有 QUARTZ ,所以會存在重複處理 TASK 的現象。apache

通常外面的解決方案是隻在一臺 服務器上裝 QUARTZ ,其它兩臺不裝,這樣的話其實就是單機了,quartz存在單點問題,一旦裝有quartz的服務器宕了。服務就沒法提供了。json

固然還有其餘一些解決方案,無非就是改 QUARTZ JOB 的代碼了,這對程序開發人員來講比較痛苦;windows

而quartz自己提供了很好的集羣方案。下面咱們來講一下在spring boot下的集成:

quartz集羣須要數據庫的支持(JobStore TX或者JobStoreCMT),從本質上來講,是使集羣上的每個節點經過共享同一個數據庫來工做的

1 準備quartz基本環境

到quartz官網下載最新的包:http://www.quartz-scheduler.org/downloads/

解壓後,能夠看到結構目錄。在\docs\dbTables下選擇合適你數據庫的SQL執行文件,建立quartz集羣須要的表(共11張表)

找到本身使用的數據庫腳本文件執行

數據庫中對應表,注意:默認狀況,在windows環境下,mysql表名不區分大小寫,linux下區分大小寫

2 集成springboot(這裏是1.5.3版本)

2.1引入依賴jar包

        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
            <version>2.2.3</version>
        </dependency>

2.2 quartz配置

  1. #quartz集羣配置  
  2. # ===========================================================================    
  3. # Configure Main Scheduler Properties 調度器屬性    
  4. # ===========================================================================  
  5. #調度標識名 集羣中每個實例都必須使用相同的名稱    
  6. org.quartz.scheduler.instanceName=DefaultQuartzScheduler  
  7. #ID設置爲自動獲取 每個必須不一樣  
  8. org.quartz.scheduler.instanceid=AUTO    
  9. #============================================================================  
  10. # Configure ThreadPool    
  11. #============================================================================  
  12. #線程池的實現類(通常使用SimpleThreadPool便可知足幾乎全部用戶的需求)  
  13. org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool  
  14. #指定線程數,至少爲1(無默認值)(通常設置爲1-100直接的整數合適)  
  15. org.quartz.threadPool.threadCount = 25  
  16. #設置線程的優先級(最大爲java.lang.Thread.MAX_PRIORITY 10,最小爲Thread.MIN_PRIORITY 1,默認爲5)   
  17. org.quartz.threadPool.threadPriority = 5  
  18. #============================================================================  
  19. # Configure JobStore    
  20. #============================================================================  
  21. # 信息保存時間 默認值60秒   
  22. org.quartz.jobStore.misfireThreshold = 60000  
  23. #數據保存方式爲數據庫持久化  
  24. org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX  
  25. #數據庫代理類,通常org.quartz.impl.jdbcjobstore.StdJDBCDelegate能夠知足大部分數據庫  
  26. org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate  
  27. #JobDataMaps是否都爲String類型  
  28. org.quartz.jobStore.useProperties = false  
  29. #數據庫別名 隨便取  
  30. org.quartz.jobStore.dataSource = myDS  
  31. #表的前綴,默認QRTZ_  
  32. org.quartz.jobStore.tablePrefix = QRTZ_  
  33. #是否加入集羣  
  34. org.quartz.jobStore.isClustered = true  
  35. #調度實例失效的檢查時間間隔  
  36. org.quartz.jobStore.clusterCheckinInterval = 20000  
  37. #============================================================================  
  38. # Configure Datasources    
  39. #============================================================================  
  40. #數據庫引擎  
  41. org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver  
  42. #數據庫鏈接  
  43. org.quartz.dataSource.myDS.URL = jdbc:mysql://172.30.12.14:7001/rbl_test?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true  
  44. #數據庫用戶  
  45. org.quartz.dataSource.myDS.user = root  
  46. #數據庫密碼  
  47. org.quartz.dataSource.myDS.password = 123456  
  48. #容許最大鏈接  
  49. org.quartz.dataSource.myDS.maxConnections = 5  
  50. #驗證查詢sql,能夠不設置  
  51. org.quartz.dataSource.myDS.validationQuery=select 0 from dual 

注:若是嫌須要額外配置quart數據源很煩,也能夠共用你項目配置的數據庫連接,這樣每次更換數據庫鏈接,就不須要額外在修改。

2.3 springboot configuration 配置

直接使用springboot注入的的datasource的內容配置quartz的數據庫鏈接

quartz屬性配置能夠讀取配置文件讀取,我這裏沒在配置文件讀取,直接寫在代碼裏測試的,直接新建一個配置文件裏面寫quartz的配置內容,而後經過springboot注入屬性進來。

package com.kerry.config;


import java.io.IOException;
import java.util.Properties;

import javax.sql.DataSource;

import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;


/**
 * 分佈式定時任務管理配置
 * @author kerry
 * @date 2018-05-09 11:36:21
 */
@Configuration
//@ConditionalOnProperty(prefix = "qybd", name = "quartz-open", havingValue = "true")
public class QuartzConfig{
	
	@Autowired
	DataSource dataSource;
	
	@Bean  
    public SchedulerFactoryBean schedulerFactoryBean(QuartzJobFactory myJobFactory) throws Exception {  
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();  
        schedulerFactoryBean.setDataSource(dataSource);  
        //使job實例支持spring 容器管理
        schedulerFactoryBean.setOverwriteExistingJobs(true);  
        schedulerFactoryBean.setJobFactory(myJobFactory);  
        schedulerFactoryBean.setQuartzProperties(quartzProperties());  
        // 延遲10s啓動quartz  
        schedulerFactoryBean.setStartupDelay(10);  
  
        return schedulerFactoryBean;  
    }
	
	
	
	@Bean
	public Scheduler scheduler(SchedulerFactoryBean schedulerFactoryBean) throws IOException, SchedulerException {
//		SchedulerFactory schedulerFactory = new StdSchedulerFactory(quartzProperties());
//		Scheduler scheduler = schedulerFactory.getScheduler();
//		scheduler.start();//初始化bean並啓動scheduler
		 Scheduler scheduler = schedulerFactoryBean.getScheduler();  
		 scheduler.start();
		return scheduler;
	}
	
	
	
	
	
	/**
	 * 設置quartz屬性
	 */
	public Properties quartzProperties() throws IOException {
		Properties prop = new Properties();
		prop.put("quartz.scheduler.instanceName", "ServerScheduler");
		prop.put("org.quartz.scheduler.instanceId", "AUTO");
		prop.put("org.quartz.scheduler.skipUpdateCheck", "true");
		prop.put("org.quartz.scheduler.instanceId", "NON_CLUSTERED");
		prop.put("org.quartz.scheduler.jobFactory.class", "org.quartz.simpl.SimpleJobFactory");
		prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
		prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate");
		prop.put("org.quartz.jobStore.dataSource", "quartzDataSource");
		prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
		prop.put("org.quartz.jobStore.isClustered", "true");
		prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        prop.put("org.quartz.threadPool.threadCount", "5");

//		prop.put("org.quartz.dataSource.quartzDataSource.driver", druidProperties.getDriverClassName());
//		prop.put("org.quartz.dataSource.quartzDataSource.URL", druidProperties.getUrl());
//		prop.put("org.quartz.dataSource.quartzDataSource.user", druidProperties.getUsername());
//		prop.put("org.quartz.dataSource.quartzDataSource.password", druidProperties.getPassword());
//		prop.put("org.quartz.dataSource.quartzDataSource.maxConnections", druidProperties.getMaxActive());
		return prop;
	}
	
}

注意上面的schedulerFactoryBean.setJobFactory(myJobFactory);  //這個myJobFactory是自定義配置的一個類,若是這裏不配置這個jobFactory,下面的那個CtripScenicTask會爲空,獲取不了注入對象

@Component
public class CtripScenicJob implements Job{
    
    private Logger logger = LoggerFactory.getLogger(CtripScenicJob.class);

    @Autowired
    private CtripScenicTask ctripScenicTask; 

這個類主要解決spring管理的Quartz job裏面注入不了其餘bean

package com.kerry.config;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;

@Component
public class QuartzJobFactory extends AdaptableJobFactory {
	
	//這個對象Spring會幫咱們自動注入進來,也屬於Spring技術範疇.
    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;
    
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        //調用父類的方法
        Object jobInstance = super.createJobInstance(bundle);
        //進行注入,這屬於Spring的技術,不清楚的能夠查看Spring的API.
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }

}

2.4 動態配置管理quartz

接口類

package com.kerry.modular.biz.service;

import java.util.List;





import org.quartz.SchedulerException;

import com.kerry.modular.biz.model.TaskInfo;

public interface TaskService {

	List<TaskInfo> list();
	
	void addJob(TaskInfo info);
	
	void edit(TaskInfo info);
	
	void delete(String jobName, String jobGroup);
	
	void pause(String jobName, String jobGroup);
	
	void resume(String jobName, String jobGroup);
	
	boolean checkExists(String jobName, String jobGroup)throws SchedulerException;
}

實現類

package com.kerry.modular.biz.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kerry.modular.biz.model.TaskInfo;

@Service
public class TaskServiceImpl implements TaskService {
	private Logger logger = LoggerFactory.getLogger(TaskServiceImpl.class);
	
	@Autowired(required=false)
	private Scheduler scheduler;
	
	/**
	 * 全部任務列表
	 */
	public List<TaskInfo> list(){
		List<TaskInfo> list = new ArrayList<>();
		
		try {
			for(String groupJob: scheduler.getJobGroupNames()){
				for(JobKey jobKey: scheduler.getJobKeys(GroupMatcher.<JobKey>groupEquals(groupJob))){
					List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
					for (Trigger trigger: triggers) {
						Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
						JobDetail jobDetail = scheduler.getJobDetail(jobKey);
						
						String cronExpression = "", createTime = "";
						
						if (trigger instanceof CronTrigger) {
				            CronTrigger cronTrigger = (CronTrigger) trigger;
				            cronExpression = cronTrigger.getCronExpression();
				            createTime = cronTrigger.getDescription();
				        }
						TaskInfo info = new TaskInfo();
						info.setJobName(jobKey.getName());
						info.setJobGroup(jobKey.getGroup());
						info.setJobDescription(jobDetail.getDescription());
						info.setJobStatus(triggerState.name());
						info.setCronExpression(cronExpression);
						info.setCreateTime(createTime);
						list.add(info);
					}					
				}
			}			
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
		
		return list;
	}
	
	/**
	 * 保存定時任務
	 * @param info
	 */
	@SuppressWarnings("unchecked")
	public void addJob(TaskInfo info) {
		String jobName = info.getJobName(), 
			   jobGroup = info.getJobGroup(), 
			   cronExpression = info.getCronExpression(),
			   jobDescription = info.getJobDescription(),
			   createTime = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
		try {
			if (checkExists(jobName, jobGroup)) {
		        logger.info("add job fail, job already exist, jobGroup:{}, jobName:{}", jobGroup, jobName);
		    }
			
			TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
			JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
			
			CronScheduleBuilder schedBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
			CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withDescription(createTime).withSchedule(schedBuilder).build();
		
		
			Class<? extends Job> clazz = (Class<? extends Job>)Class.forName(jobName);
			JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(jobKey).withDescription(jobDescription).build();
			scheduler.scheduleJob(jobDetail, trigger);
		} catch (SchedulerException | ClassNotFoundException e) {
			logger.error("類名不存在或執行表達式錯誤,exception:{}",e.getMessage());
		}
	}
	
	/**
	 * 修改定時任務
	 * @param info
	 */
	public void edit(TaskInfo info) {
		String jobName = info.getJobName(), 
			   jobGroup = info.getJobGroup(), 
			   cronExpression = info.getCronExpression(),
			   jobDescription = info.getJobDescription(),
			   createTime = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
		try {
			if (!checkExists(jobName, jobGroup)) {
				logger.info("edit job fail, job is not exist, jobGroup:{}, jobName:{}", jobGroup, jobName);
			}
			TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
	        JobKey jobKey = new JobKey(jobName, jobGroup);
	        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression).withMisfireHandlingInstructionDoNothing();
	        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withDescription(createTime).withSchedule(cronScheduleBuilder).build();
	        
	        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
	        jobDetail.getJobBuilder().withDescription(jobDescription);
	        HashSet<Trigger> triggerSet = new HashSet<>();
	    	triggerSet.add(cronTrigger);
	        
	    	scheduler.scheduleJob(jobDetail, triggerSet, true);
		} catch (SchedulerException e) {
			logger.error("類名不存在或執行表達式錯誤,exception:{}",e.getMessage());
		}
	}
	
	/**
	 * 刪除定時任務
	 * @param jobName
	 * @param jobGroup
	 */
	public void delete(String jobName, String jobGroup){
		TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
        try {
			if (checkExists(jobName, jobGroup)) {
				scheduler.pauseTrigger(triggerKey);
			    scheduler.unscheduleJob(triggerKey);
			    logger.info("delete job, triggerKey:{},jobGroup:{}, jobName:{}", triggerKey ,jobGroup, jobName);
			}
		} catch (SchedulerException e) {
			logger.error(e.getMessage());
		}
	}
	
	/**
	 * 暫停定時任務
	 * @param jobName
	 * @param jobGroup
	 */
	public void pause(String jobName, String jobGroup){
		TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
		try {
			if (checkExists(jobName, jobGroup)) {
				scheduler.pauseTrigger(triggerKey);
			    logger.info("pause job success, triggerKey:{},jobGroup:{}, jobName:{}", triggerKey ,jobGroup, jobName);
			}
		} catch (SchedulerException e) {
			logger.error(e.getMessage());
		}
	}
	
	/**
	 * 從新開始任務
	 * @param jobName
	 * @param jobGroup
	 */
	public void resume(String jobName, String jobGroup){
		TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
        
        try {
			if (checkExists(jobName, jobGroup)) {
				scheduler.resumeTrigger(triggerKey);
			    logger.info("resume job success,triggerKey:{},jobGroup:{}, jobName:{}", triggerKey ,jobGroup, jobName);
			}
		} catch (SchedulerException e) {
			logger.error(e.getMessage());
		}
	}
	
	/**
	 * 驗證是否存在
	 * @param jobName
	 * @param jobGroup
	 * @throws SchedulerException
	 */
	public boolean checkExists(String jobName, String jobGroup) throws SchedulerException{
		TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
		return scheduler.checkExists(triggerKey);
	}
}

taskinfo實體類

package com.kerry.modular.biz.model;

import java.io.Serializable;

public class TaskInfo implements Serializable{
	private static final long serialVersionUID = -8054692082716173379L;
	private int id = 0;

	/**任務名稱*/
	private String jobName;
	
	/**任務分組*/
	private String jobGroup;
	
	/**任務描述*/
	private String jobDescription;
	
	/**任務狀態*/
	private String jobStatus;
	
	/**任務表達式*/
	private String cronExpression;
	
	private String createTime;

	public String getJobName() {
		return jobName;
	}

	public void setJobName(String jobName) {
		this.jobName = jobName;
	}

	public String getJobGroup() {
		return jobGroup;
	}

	public void setJobGroup(String jobGroup) {
		this.jobGroup = jobGroup;
	}

	public String getJobDescription() {
		return jobDescription;
	}

	public void setJobDescription(String jobDescription) {
		this.jobDescription = jobDescription;
	}

	public String getJobStatus() {
		return jobStatus;
	}

	public void setJobStatus(String jobStatus) {
		this.jobStatus = jobStatus;
	}

	public String getCronExpression() {
		return cronExpression;
	}

	public void setCronExpression(String cronExpression) {
		this.cronExpression = cronExpression;
	}

	public String getCreateTime() {
		return createTime;
	}

	public void setCreateTime(String createTime) {
		this.createTime = createTime;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
}

 

任務管理Controller類

package com.kerry.modular.biz.controller;


import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.kerry.modular.biz.model.TaskInfo;
import com.kerry.modular.biz.service.TaskService;

/**
 * 任務管理
 */
@Controller
@RequestMapping("/qy/api/task/")
public class TaskManageController {
	
	@Autowired(required=false)
	private TaskService taskService;

	/**
	 * Index.jsp
	 */
	@RequestMapping(value={"", "/", "index"})
	public String info(){
		return "index.jsp";
	}
	
	/**
	 * 任務列表
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="list")
	public String list(){
		Map<String, Object> map = new HashMap<>();
		List<TaskInfo> infos = taskService.list();
		map.put("rows", infos);
		map.put("total", infos.size());
		return JSON.toJSONString(map);
	}
	
	/**
	 * 保存定時任務
	 * @param info
	 */
	@ResponseBody
	@RequestMapping(value="save", produces = "application/json; charset=UTF-8")
	public String save(TaskInfo info){
		try {
			if(info.getId() == 0) {
				taskService.addJob(info);
			}else{
				taskService.edit(info);
			}
		} catch (Exception e) {
			return e.getMessage();
		}
		return "成功";
	}
	
	/**
	 * 刪除定時任務
	 * @param jobName
	 * @param jobGroup
	 */
	@ResponseBody
	@RequestMapping(value="delete/{jobName}/{jobGroup}", produces = "application/json; charset=UTF-8")
	public String delete(@PathVariable String jobName, @PathVariable String jobGroup){
		try {
			taskService.delete(jobName, jobGroup);
		} catch (Exception e) {
			return e.getMessage();
		}
		return "成功";
	}
	
	/**
	 * 暫停定時任務
	 * @param jobName
	 * @param jobGroup
	 */
	@ResponseBody
	@RequestMapping(value="pause/{jobName}/{jobGroup}", produces = "application/json; charset=UTF-8")
	public String pause(@PathVariable String jobName, @PathVariable String jobGroup){
		try {
			taskService.pause(jobName, jobGroup);
		} catch (Exception e) {
			return e.getMessage();
		}
		return "成功";
	}
	
	/**
	 * 從新開始定時任務
	 * @param jobName
	 * @param jobGroup
	 */
	@ResponseBody
	@RequestMapping(value="resume/{jobName}/{jobGroup}", produces = "application/json; charset=UTF-8")
	public String resume(@PathVariable String jobName, @PathVariable String jobGroup){
		try {
			taskService.resume(jobName, jobGroup);
		} catch (Exception e) {
			return e.getMessage();
		}
		return "成功";
	}
}

 

任務實現類實現job接口,重寫execute方法

package com.kerry.modular.biz.task.quartz;


import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.kerry.modular.biz.task.schedule.CtripScenicTask;

@Component
public class CtripScenicJob implements Job{
	
	private Logger logger = LoggerFactory.getLogger(CtripScenicJob.class);

	@Autowired
	private CtripScenicTask ctripScenicTask;
	
	@Override
	public void execute(JobExecutionContext context)
			throws JobExecutionException {
		logger.info("JobName: {}", context.getJobDetail().getKey().getName());
		ctripScenicTask.loadComment();
	}
	
	

}

 

此時能夠經過調用TaskManageController時間動態控制定時任務

 

3 測試,啓動springboot項目

輸入添加任務的url:

http://localhost:8080/qy/api/task/save?jobName=com.stylefeng.guns.modular.biz.task.quartz.CtripHotelJob&jobGroup=group1&jobDescription=job描述&cronExpression=0/10 * * * * ?

jobName爲job類的包名類名,jobGroup該任務所屬組,jobDescription 描述,cronExpression :core表達式

上面的請求會添加一個定時任務,每10秒執行一次  CtripHotelJob裏面的execute方法。

保存的定時任務會在quartz相關表裏保存數據

如:

相關文章
相關標籤/搜索