quartz数据库分布式创建定时任务,出现任务状态error,这些任务无法执行

在配置spring-quartz.xml时,遇到使用quartz数据库分布式创建定时任务后,任务状态显示为error,导致任务无法执行。配置中包括了任务工厂声明、数据源设置、quartz配置文件引用以及通过quartz上下文获取spring上下文的配置。问题可能出在数据源连接、配置文件读取或任务实现上。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我当时配置的方式是,可能大部分人的配置方式和我类似,如:

1、配置spring-quartz.xml的配置文件,内容如下

        <!-- 声明任务工厂 -->  

<bean id="scheduler" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
        <property name="dataSource" ref="dataSource" />
		<property name="configLocation" value="classpath:quartz.properties" />
		
		<property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>    
    </bean>  

可以看到  scheduler的对象来源是spring的类 org.springframework.scheduling.quartz.SchedulerFactoryBean
 配置数据源 ref="dataSource" ,加载quartz的配置文件 
<property name="configLocation" value="classpath:quartz.properties" />
通过quartz的上下文获取spring上下文的配置
<property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>    
 2、quartz的任务实现方式ScheduleJobServiceImpl



package com.credithc.accent.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.credithc.accent.model.ScheduleJob;
import com.credithc.accent.service.ScheduleJobService;



/**
 * 定时任务 service
 * @author ty
 * @date 2015年1月13日
 */
@Service("scheduleJobService")
public class ScheduleJobServiceImpl implements ScheduleJobService{
	

	@Autowired
	private Scheduler scheduler;
	
	/**
	 * 添加定时任务
	 * @param ScheduleJob
	 */
	public void add(ScheduleJob scheduleJob){
		@SuppressWarnings("rawtypes")
		Class job = null;
		try {
			job = Class.forName(scheduleJob.getClassName());
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		}
		@SuppressWarnings("unchecked")
		JobDetail jobDetail = JobBuilder.newJob(job).withIdentity(scheduleJob.getName(), scheduleJob.getGroup()).build(); 
		//表达式调度构建器(可判断创建SimpleScheduleBuilder)
		CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
		jobDetail.getJobDataMap().put("scheduleJob", scheduleJob);
		//按新的cronExpression表达式构建一个新的trigger
		CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(scheduleJob.getName(), scheduleJob.getGroup()).withSchedule(scheduleBuilder).build();
		try {
			scheduler.scheduleJob(jobDetail, trigger);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}

	
	/**
	 * 获取所有计划中的任务
	 * @return 结果集合
	 */
	public List<ScheduleJob> getAllScheduleJob(){
		List<ScheduleJob> scheduleJobList=new ArrayList<ScheduleJob>();
		GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
		try {
			Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
			for (JobKey jobKey : jobKeys) {
			    List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
			    for (Trigger trigger : triggers) {
			        ScheduleJob scheduleJob = new ScheduleJob();
			        scheduleJob.setName(jobKey.getName());
			        scheduleJob.setGroup(jobKey.getGroup());
			        Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
			        scheduleJob.setStatus(triggerState.name());
			        //获取要执行的定时任务类名
			        JobDetail jobDetail=scheduler.getJobDetail(jobKey);
				    scheduleJob.setClassName(jobDetail.getJobClass().getName());
				  
					if (trigger instanceof CronTrigger) {
						CronTrigger cron = (CronTrigger) trigger;
						scheduleJob.setCronExpression(cron.getCronExpression());
					}
			        scheduleJobList.add(scheduleJob);
			    }
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return scheduleJobList;
	}
	

	/**
	 * 恢复任务
	 * @param name 任务名
	 * @param group 任务组
	 */
	public void restartJob(String[] name,String[] group){
		for(int i=0;i<name.length;i++){
			JobKey key = new JobKey(name[i], group[i]);
			try {
				scheduler.resumeJob(key);
			} catch (SchedulerException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 立马执行一次任务
	 * @param name 任务名
	 * @param group 任务组
	 */
	public void startNowJob(String[] name,String[] group){
		for(int i=0;i<name.length;i++){
			JobKey jobKey = JobKey.jobKey(name[i], group[i]);
			try {
				scheduler.triggerJob(jobKey);
			} catch (SchedulerException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 删除任务
	 * @param name 任务名
	 * @param group 任务组
	 */
	public void delJob(String[] name,String[] group){
		for(int i=0;i<name.length;i++){
			JobKey key = new JobKey(name[i], group[i]);
			try {
				scheduler.deleteJob(key);
			} catch (SchedulerException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	/**
	 * 修改触发器时间
	 * @param name 任务名
	 * @param group 任务组
	 * @param cron cron表达式
	 */
	public void modifyTrigger(ScheduleJob scheduleJob){
		try {  
            TriggerKey key = TriggerKey.triggerKey(scheduleJob.getName(), scheduleJob.getGroup());  
            //Trigger trigger = scheduler.getTrigger(key);  
              
            CronTrigger newTrigger = (CronTrigger) TriggerBuilder.newTrigger()  
                    .withIdentity(key)  
                    .withSchedule(CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()))  
                    .build();  
            scheduler.rescheduleJob(key, newTrigger);  
        } catch (SchedulerException e) {  
            e.printStackTrace();  
        }  
		
	}

	/**
	 * 暂停任务
	 * @param name 任务名
	 * @param group 任务组
	 */
	public void stopJob(String[] name,String[] group){
		for(int i=0;i<name.length;i++){
			JobKey key = new JobKey(name[i], group[i]);
			try {
				scheduler.pauseJob(key);
			} catch (SchedulerException e) {
				e.printStackTrace();
			}
		}
	}
}



上面代码可以看到Scheduler 是通过spring工厂类注入生成的,然后进行任务的调度。
这样运行的话,就会出现同时运行多个任务,然后可能只有一个任务执行,再或者一个都不允许(第一次正常,下一次就全部error
情况。

然后可以修改整体的方式:
只需要一个 quartz.properties配置文件在src下,内容
 
#==============================================================  
#Configure Main Scheduler Properties  
#==============================================================   
org.quartz.scheduler.instanceName = TestScheduler1
org.quartz.scheduler.instanceId = AUTO
#==============================================================  
#Configure ThreadPool  
#==============================================================   
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 5
org.quartz.threadPool.threadPriority = 5
#==============================================================  
#Configure JobStore  
#==============================================================   
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.dataSource = qzDS
  
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 15000
#==============================================================  
#Non-Managed Configure Datasource  
#==============================================================   
#JDBC
org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver  
org.quartz.dataSource.qzDS.URL:jdbc:mysql://10.100.19.157:3306/accent-sys-dev?useUnicode=true&characterEncoding=utf-8  
org.quartz.dataSource.qzDS.user:root  
org.quartz.dataSource.qzDS.password:root
org.quartz.dataSource.qzDS.maxConnection:10  



 

然后修改实现类
package com.credithc.accent.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.annotation.PostConstruct;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
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.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.stereotype.Service;
import com.credithc.accent.model.ScheduleJob;
import com.credithc.accent.service.ScheduleJobService;



/**
 * 定时任务 service
 * @author ty
 * @date 2015年1月13日
 */
@Service("scheduleJobService")
public class ScheduleJobServiceImpl implements ScheduleJobService{
	
	@PostConstruct
	public void initSchedule(){
		 Scheduler scheduler;
		try {
			scheduler = StdSchedulerFactory.getDefaultScheduler();
			scheduler.start();  
		} catch (SchedulerException e) {
			e.printStackTrace();
		}  
	}
	/**
	 * 添加定时任务
	 * @param ScheduleJob
	 */
	public void add(ScheduleJob scheduleJob){
		@SuppressWarnings("rawtypes")
		Class job = null;
		try {
			job = Class.forName(scheduleJob.getClassName());
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		}
		@SuppressWarnings("unchecked")
		JobDetail jobDetail = JobBuilder.newJob(job).withIdentity(scheduleJob.getName(), scheduleJob.getGroup()).build(); 
		//表达式调度构建器(可判断创建SimpleScheduleBuilder)
		CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
		jobDetail.getJobDataMap().put("scheduleJob", scheduleJob);
		//按新的cronExpression表达式构建一个新的trigger
		CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(scheduleJob.getName(), scheduleJob.getGroup()).withSchedule(scheduleBuilder).build();
		try {
	   // 3、创建Scheduler  
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();  
            scheduler.start();  
            // 4、调度执行  
            scheduler.scheduleJob(jobDetail, trigger);  
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}

	
	/**
	 * 获取所有计划中的任务
	 * @return 结果集合
	 */
	public List<ScheduleJob> getAllScheduleJob(){
		List<ScheduleJob> scheduleJobList=new ArrayList<ScheduleJob>();
		GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
		try {
			Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();  
			Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
			for (JobKey jobKey : jobKeys) {
			    List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
			    for (Trigger trigger : triggers) {
			        ScheduleJob scheduleJob = new ScheduleJob();
			        scheduleJob.setName(jobKey.getName());
			        scheduleJob.setGroup(jobKey.getGroup());
			        Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
			        scheduleJob.setStatus(triggerState.name());
			        //获取要执行的定时任务类名
			        JobDetail jobDetail=scheduler.getJobDetail(jobKey);
				    scheduleJob.setClassName(jobDetail.getJobClass().getName());
				  
					if (trigger instanceof CronTrigger) {
						CronTrigger cron = (CronTrigger) trigger;
						scheduleJob.setCronExpression(cron.getCronExpression());
					}
			        scheduleJobList.add(scheduleJob);
			    }
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return scheduleJobList;
	}
	

	/**
	 * 恢复任务
	 * @param name 任务名
	 * @param group 任务组
	 */
	public void restartJob(String[] name,String[] group){
		for(int i=0;i<name.length;i++){
			JobKey key = new JobKey(name[i], group[i]);
			try {
				Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();  
				scheduler.start();  
				scheduler.resumeJob(key);
			} catch (SchedulerException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 立马执行一次任务
	 * @param name 任务名
	 * @param group 任务组
	 */
	public void startNowJob(String[] name,String[] group){
		for(int i=0;i<name.length;i++){
			JobKey jobKey = JobKey.jobKey(name[i], group[i]);
			try {
				Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();  
				scheduler.start();  
				scheduler.triggerJob(jobKey);
			} catch (SchedulerException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 删除任务
	 * @param name 任务名
	 * @param group 任务组
	 */
	public void delJob(String[] name,String[] group){
		for(int i=0;i<name.length;i++){
			JobKey key = new JobKey(name[i], group[i]);
			try {
				Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
				scheduler.deleteJob(key);
			} catch (SchedulerException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	/**
	 * 修改触发器时间
	 * @param name 任务名
	 * @param group 任务组
	 * @param cron cron表达式
	 */
	public void modifyTrigger(ScheduleJob scheduleJob){
		try {  
            TriggerKey key = TriggerKey.triggerKey(scheduleJob.getName(), scheduleJob.getGroup());  
            //Trigger trigger = scheduler.getTrigger(key);  
              
            CronTrigger newTrigger = (CronTrigger) TriggerBuilder.newTrigger()  
                    .withIdentity(key)  
                    .withSchedule(CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression()))  
                    .build();  
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();  
            scheduler.start();  
            scheduler.rescheduleJob(key, newTrigger);  
        } catch (SchedulerException e) {  
            e.printStackTrace();  
        }  
		
	}

	/**
	 * 暂停任务
	 * @param name 任务名
	 * @param group 任务组
	 */
	public void stopJob(String[] name,String[] group){
		for(int i=0;i<name.length;i++){
			JobKey key = new JobKey(name[i], group[i]);
			try {
				Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); 
				scheduler.start();  
				scheduler.pauseJob(key);
			} catch (SchedulerException e) {
				e.printStackTrace();
			}
		}
	}
}



注意红色的代码(后面代码也有修改没有标记),通过quartz 的工厂方式生成,必须执行start();,默认这样工厂方式会直接加载 classpath下的quartz.properties配置文件

这样就完美解决了,多个任务执行会出现问题的情况。

其中蓝色代码 是解决,每次服务重启的话,定时任务不会自动起来执行的情况。







                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值