Loading...
My Blog 我的工作和学习笔记

org.quartz.SchedulerException: Couldn't get host name! [See nested exception: java.net.UnknownHostException:

程序员笔记 2016/01/12 Quartz , Linux , Nginx

hostname没有指向IP地址,编辑/etc/hosts,将hostname指向127.0.0.1即可

vi /etc/hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
127.0.0.1   ticket.centerB


Spring集成分布式Quartz框架之二:动态添加、修改、删除任务

Spring专题 2015/12/23 Spring Framework , Quartz

在上一篇关于《Spring集成配置分布式Quartz框架之一:常规整合》的基础之上实现动态添加、修改、删除任务


通常我们将Quartz整合到Spring是通过配置文件的方式配置任务Job和触发器Trigger,每次更改或者添加配置,都需要重新启动项目,为了解决该问题,在网络上翻阅了一些资料后,整理了动态添加、修改和删除任务的功能。

主要封装了三个类:QuartzJob(任务信息类)、QuartzJobFactory(任务执行类)、DynamicQuartzJobFactory(动态执行任务工厂类)。


废话少说,上菜~~


1、任务信息类:QuartzJob

package cn.imethan.admin.quartz.dynamic;

import java.io.Serializable;

/**

 * ScheduleJob.java

 * 

 * @author Ethan Wong

 * @since JDK 1.7

 * @datetime 2015年12月22日下午3:42:38

 */

public class QuartzJob implements Serializable {

    //需要实现序列化接口,否则没办法持久化到数据库

    private static final long serialVersionUID = -1800494926172862932L;

    private String jobId;//任务id

    private String jobName;//任务名称

    private String jobGroup;//任务分组

    private String jobStatus;//任务状态 0禁用 1启用 2删除

    private String cronExpression;//任务运行时间表达式

    private String description;//任务描述    

    

public String getJobId() {

return jobId;

}

public void setJobId(String jobId) {

this.jobId = jobId;

}

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 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 getDescription() {

return description;

}

public void setDescription(String description) {

this.description = description;

}

}


2、任务执行工厂类:QuartzJobFactory

package cn.imethan.admin.quartz.dynamic;

import java.io.Serializable;

import java.text.SimpleDateFormat;

import java.util.Date;


import org.quartz.DisallowConcurrentExecution;

import org.quartz.Job;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;


/**

 * QuartzJobFactory.java

 *

 * @author Ethan Wong

 * @since JDK 1.7

 * @datetime 2015年12月21日下午5:36:08

 */

@DisallowConcurrentExecution

public class QuartzJobFactory  implements Job,Serializable{


private static final long serialVersionUID = 3352853281096701664L;


@Override

public void execute(JobExecutionContext context) throws JobExecutionException {

// TODO Auto-generated method stub

System.out.println("★★★★★★★★★★★QuartzJob★★★★★★★★★★★:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));    

        System.out.println("QuartzJob Name = [" + context.getJobDetail().getKey() + "]");

        

        try {

Thread.sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}


}


3、动态执行任务工厂类:DynamicQuartzJobFactory

package cn.imethan.admin.quartz.dynamic;

import java.util.ArrayList;

import java.util.List;

import java.util.Set;


import javax.transaction.Transactional;


import org.quartz.CronScheduleBuilder;

import org.quartz.CronTrigger;

import org.quartz.JobBuilder;

import org.quartz.JobDetail;

import org.quartz.JobExecutionContext;

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.scheduling.quartz.SchedulerFactoryBean;

import org.springframework.stereotype.Component;


/**

 * DynamicQuartzJobFactory.java

 *

 * @author Ethan Wong

 * @since JDK 1.7

 * @datetime 2015年12月21日下午5:32:50

 */

@Component

@Transactional//必须添加事务注释,否则任务没办法持久化到数据库

public class DynamicQuartzJobFactory {

@Autowired

private SchedulerFactoryBean quartzScheduler;//将配置文件的注册的bean注入

/**

* 获取任务调度

* @return

*

* @author Ethan Wong

* @datetime 2015年12月23日上午11:23:49

*/

private Scheduler getScheduler(){

return quartzScheduler.getScheduler();

}

/**

* 准备任务数据

* @return

*

* @author Ethan Wong

* @datetime 2015年12月23日上午11:23:41

*/

private List<QuartzJob> getAllJob(){

List<QuartzJob> list = new ArrayList<QuartzJob>();

for (int i = 0; i < 5; i++) {

QuartzJob job = new QuartzJob();

job.setJobId("10001" + i);

job.setJobName("TESTJOB" + i);

job.setJobGroup("DEFAULT");

job.setJobStatus("1");

job.setCronExpression("0/5 * * * * ?");

job.setDescription("测试任务");

list.add(job);

}

return list;

}

/**

* 测试入口

*

* @author Ethan Wong

* @datetime 2015年12月23日上午11:24:11

*/

public void testOne(){

try {

List<QuartzJob> jobList = getAllJob();//这里获取任务信息数据

for (QuartzJob job : jobList) {

this.addJob(job.getJobName(), job.getJobGroup(), job.getCronExpression());

// this.deleteJob(job.getJobName(), job.getJobGroup());

}

} catch (SchedulerException e) {

e.printStackTrace();

}

}

/**

* 获取计划中的任务列表

* @return

* @throws SchedulerException

*

* @author Ethan Wong

* @datetime 2015年12月23日上午10:55:44

*/

public List<QuartzJob> getTriggersOfJob() throws SchedulerException{

Scheduler scheduler = this.getScheduler();

GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();

Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);

List<QuartzJob> jobList = new ArrayList<QuartzJob>();

for (JobKey jobKey : jobKeys) {

   List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);

   for (Trigger trigger : triggers) {

    QuartzJob job = new QuartzJob();

       job.setJobName(jobKey.getName());

       job.setJobGroup(jobKey.getGroup());

       job.setDescription("触发器:" + trigger.getKey());

       Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());

       job.setJobStatus(triggerState.name());

       if (trigger instanceof CronTrigger) {

           CronTrigger cronTrigger = (CronTrigger) trigger;

           String cronExpression = cronTrigger.getCronExpression();

           job.setCronExpression(cronExpression);

       }

       jobList.add(job);

   }

}

return jobList;

}


/**

* 获取正在执行的任务列表

* @return

* @throws SchedulerException

*

* @author Ethan Wong

* @datetime 2015年12月23日上午10:56:02

*/

public List<QuartzJob> getCurrentlyExecutingJobs() throws SchedulerException{

Scheduler scheduler = this.getScheduler();

List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();

List<QuartzJob> jobList = new ArrayList<QuartzJob>(executingJobs.size());

for (JobExecutionContext executingJob : executingJobs) {

QuartzJob job = new QuartzJob();

   JobDetail jobDetail = executingJob.getJobDetail();

   JobKey jobKey = jobDetail.getKey();

   Trigger trigger = executingJob.getTrigger();

   job.setJobName(jobKey.getName());

   job.setJobGroup(jobKey.getGroup());

   job.setDescription("触发器:" + trigger.getKey());

   Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());

   job.setJobStatus(triggerState.name());

   if (trigger instanceof CronTrigger) {

       CronTrigger cronTrigger = (CronTrigger) trigger;

       String cronExpression = cronTrigger.getCronExpression();

       job.setCronExpression(cronExpression);

   }

   jobList.add(job);

}

return jobList;

}

/**

* 添加任务

* @param jobName

* @param jobGroup

* @param timeExpression

* @return

* @throws SchedulerException

*

* @author Ethan Wong

* @datetime 2015年12月23日上午10:03:02

*/

public boolean addJob(String jobName,String jobGroup,String timeExpression) throws SchedulerException{

Scheduler scheduler = this.getScheduler();

//获取trigger,即在spring配置文件中定义的 bean id="myTrigger"

TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);

CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

if (trigger == null) {

//不存在,创建一个

JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class).withIdentity(jobName, jobGroup).storeDurably().build();

jobDetail.getJobDataMap().put("scheduleJob", "job");

scheduler.addJob(jobDetail, true);

//表达式调度构建器

CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(timeExpression);

//按新的cronExpression表达式构建一个新的trigger

trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup).forJob(jobDetail).withSchedule(scheduleBuilder).build();

boolean isExists = scheduler.checkExists(jobDetail.getKey());

if(!isExists){

scheduler.scheduleJob(jobDetail, trigger);

}else{

}

scheduler.scheduleJob(trigger);

} else {

// Trigger已存在,那么更新相应的定时设置

//表达式调度构建器

CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(timeExpression);

//按新的cronExpression表达式重新构建trigger

trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

//按新的trigger重新设置job执行

scheduler.rescheduleJob(triggerKey, trigger);

}

return false;

}

/**

* 暂停任务

* @param jobName

* @param jobGroup

* @throws SchedulerException

*

* @author Ethan Wong

* @datetime 2015年12月23日上午10:17:00

*/

public void pauseJob(String jobName,String jobGroup) throws SchedulerException{

Scheduler scheduler = this.getScheduler();

JobKey jobKey = JobKey.jobKey(jobName, jobName);

scheduler.pauseJob(jobKey);

}

/**

* 恢复任务

* @param jobName

* @param jobGroup

* @throws SchedulerException

*

* @author Ethan Wong

* @datetime 2015年12月23日上午10:17:41

*/

public void resumeJob(String jobName,String jobGroup) throws SchedulerException{

Scheduler scheduler = this.getScheduler();

JobKey jobKey = JobKey.jobKey(jobName, jobGroup);

scheduler.resumeJob(jobKey);

}

/**

* 删除任务

* @param jobName

* @param jobGroup

* @throws SchedulerException

*

* @author Ethan Wong

* @datetime 2015年12月23日上午10:18:38

*/

public void  deleteJob(String jobName,String jobGroup) throws SchedulerException{

Scheduler scheduler = this.getScheduler();

JobKey jobKey = JobKey.jobKey(jobName, jobGroup);

scheduler.deleteJob(jobKey);

}

/**

* 触发任务

* @param jobName

* @param jobGroup

* @throws SchedulerException

*

* @author Ethan Wong

* @datetime 2015年12月23日上午10:19:49

*/

public void  triggerJob(String jobName,String jobGroup) throws SchedulerException{

Scheduler scheduler = this.getScheduler();

JobKey jobKey = JobKey.jobKey(jobName, jobGroup);

scheduler.triggerJob(jobKey);

}

/**

* 更新任务触发器时间

* @param jobName

* @param jobGroup

* @param timeExpression

* @throws SchedulerException

*

* @author Ethan Wong

* @datetime 2015年12月23日上午10:21:55

*/

public void modifyTimeExpression(String jobName,String jobGroup,String timeExpression) throws SchedulerException{

Scheduler scheduler = this.getScheduler();

TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);

//获取trigger,即在spring配置文件中定义的 bean id="myTrigger"

CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

//表达式调度构建器

CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(timeExpression);

//按新的cronExpression表达式重新构建trigger

trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

//按新的trigger重新设置job执行

scheduler.rescheduleJob(triggerKey, trigger);

}


}



参考文档

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

http://www.dexcoder.com/selfly/article/308

Spring集成分布式Quartz框架之一:常规整合

Spring专题 2015/12/18 Spring Framework , Quartz

该配置为了解决WEB项目分布式部署时定时任务的并发冲突问题。

配置环境如下:

JDK 1.7

Spring 4.0.2

Quartz 2.2.1

首先要导入quartz涉及到11张表

从官网http://www.quartz-scheduler.org下载“quartz-2.2.1-distribution.tar.gz”,解压,从“quartz-2.2.1-distribution\quartz-2.2.1\docs\dbTables”目录下找到合适的您项目的脚本


两个主要配置文件:quartz.properties和applicationContext-quartz.xml,文件内容如下:

quartz.properties文件内容:

# Using Spring datasource in quartzJobsConfig.xml

# Spring uses LocalDataSourceJobStore extension of JobStoreCMT

org.quartz.jobStore.useProperties=true

org.quartz.jobStore.tablePrefix=QRTZ_

org.quartz.jobStore.isClustered=true

# 1 mins

org.quartz.jobStore.clusterCheckinInterval=15000

org.quartz.scheduler.skipUpdateCheck=true


# Change this to match your DB vendor

org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate

# Needed to manage cluster instances

org.quartz.scheduler.instanceId=AUTO

org.quartz.scheduler.instanceName=quartzInstanceName

 

org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool

org.quartz.threadPool.threadCount=10

org.quartz.threadPool.threadPriority=5

org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true


# Configure Plugins

org.quartz.plugin.triggHistory.class=org.quartz.plugins.history.LoggingJobHistoryPlugin

#org.quartz.plugin.triggHistory.class=org.quartz.plugins.history.LoggingTriggerHistoryPlugin

#org.quartz.plugin.triggHistory.triggerFiredMessage=Trigger \{1\}.\{0\} fired job \{6\}.\{5\} at: \{4, date, HH:mm:ss MM/dd/yyyy}

#org.quartz.plugin.triggHistory.triggerCompleteMessage=Trigger \{1\}.\{0\} completed firing job \{6\}.\{5\} at \{4, date, HH:mm:ss MM/dd/yyyy\}


applicationContext-quartz.xml文件内容:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"

xmlns:task="http://www.springframework.org/schema/task"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.2.xsd

http://www.springframework.org/schema/task

http://www.springframework.org/schema/task/spring-task-3.2.xsd">


<description>quartz分布式配置文件</description>


<context:annotation-config />


<!-- 任务配置 -->

<bean id="jobDetail"

class="org.springframework.scheduling.quartz.JobDetailFactoryBean">

<property name="jobClass" value="cn.imethan.admin.quartz.job.TestJob" />

<property name="durability" value="true" />

<!-- <property name="requestsRecovery" value="true" /> -->

</bean>


<!-- 触发器 -->

<bean id="jobDetailTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">

<property name="jobDetail" ref="jobDetail" />

<property name="cronExpression">

<value>0/5 * * * * ?</value>

</property>

<property name="timeZone">

<value>GMT+8:00</value>

</property>

</bean>


<!-- 任务调度配置 -->

<bean id="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">

<property name="configLocation" value="classpath:/quartz/quartz.properties" />

<property name="dataSource" ref="myDataSource" />

<property name="transactionManager" ref="myTxManager" />


<!-- This name is persisted as SCHED_NAME in db. for local testing could 

change to unique name to avoid collision with dev server -->

<property name="schedulerName" value="quartzScheduler" />


<property name="startupDelay" value="5" />


<!-- Will update database cron triggers to what is in this jobs file on 

each deploy. Replaces all previous trigger and job data that was in the database. 

YMMV -->

<property name="overwriteExistingJobs" value="true" />

<property name="autoStartup" value="true" />

<property name="applicationContextSchedulerContextKey" value="applicationContext" />

<property name="jobFactory">

<bean class="cn.imethan.admin.quartz.common.AutowiringSpringBeanJobFactory" />

</property>


<!-- NOTE: Must add both the jobDetail and trigger to the scheduler! -->

<property name="triggers">

<list>

<ref bean="jobDetailTrigger" />

</list>

</property>

<property name="jobDetails">

<list>

<ref bean="jobDetail" />

</list>

</property>

</bean>

</beans>


两个主要的类,AutowiringSpringBeanJobFactory和TestJob,类内容如下:

AutowiringSpringBeanJobFactory类内容:

package cn.imethan.admin.quartz.common;


import org.quartz.spi.TriggerFiredBundle;

import org.springframework.beans.factory.config.AutowireCapableBeanFactory;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

import org.springframework.scheduling.quartz.SpringBeanJobFactory;


/**

 * AutowiringSpringBeanJobFactory.java

 *

 * @author Ethan Wong

 * @time 2015年9月19日下午3:33:22

 */

public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {


private transient AutowireCapableBeanFactory beanFactory;


public void setApplicationContext(final ApplicationContext context) {

beanFactory = context.getAutowireCapableBeanFactory();

}


@Override

protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {

final Object job = super.createJobInstance(bundle);

beanFactory.autowireBean(job);

return job;

}

}


TestJob类内容如下:

package cn.imethan.admin.quartz.job;

import org.quartz.DisallowConcurrentExecution;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

import org.springframework.scheduling.quartz.QuartzJobBean;


import cn.imethan.common.utils.DateUtil;


/**

 * TestJob.java

 *

 * @author Ethan Wong

 * @time 2015年9月19日下午3:36:40

 */

@DisallowConcurrentExecution

public class TestJob extends QuartzJobBean {

    protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException {

   

    System.out.println("[TestJob]Sleep 10s begin date:"+DateUtil.getDatetimeStr(DateUtil.DATE_PATTERN_01));

    try {

Thread.sleep(4000);

} catch (InterruptedException e) {

e.printStackTrace();

}

    System.out.println("[TestJob]Sleep 10s end   date:"+DateUtil.getDatetimeStr(DateUtil.DATE_PATTERN_01));

    }

    

}




参考文档

http://www.cnblogs.com/skyblue/p/3296350.html