Quartz 笔记

从http://www.quartz-scheduler.org/documentation 习来的笔记,多是文档上面的原话,很清楚,也不想去译了,记下来。

Quartz Scheduler is licensed under the Apache License, Version 2.0 (the "License")

用处

Driving Process Workflow:(schedule a Job to fire in exactly 2 hours)

System Maintenance

Providing reminder services within an application.

Job Scheduling 的方式

at a certain time of day (to the millisecond)

on certain days of the week

on certain days of the month

on certain days of the year

not on certain days listed within a registered Calendar (such as business holidays)

repeated a specific number of times

repeated until a specific time/date

repeated indefinitely

repeated with a delay interval 

Clustering

Fail-over.

Load balancing.

Quartz's built-in clustering features rely upon database persistence via JDBCJobStore (described above).

Terracotta extensions to Quartz provide clustering capabilities without the need for a backing database.

主要API

Scheduler - the main API for interacting with the scheduler.

Job - an interface to be implemented by components that you wish to have executed by the scheduler.

A Scheduler's life-cycle is bounded by it's creation, via a SchedulerFactory and a call to its shutdown() method. Once created the Scheduler interface can be used add, remove, and list Jobs and Triggers, and perform other scheduling-related operations (such as pausing a trigger). However, the Scheduler will not actually act on any triggers (execute jobs) until it has been started with the start() method,

JobDetail - used to define instances of Jobs.

Trigger - a component that defines the schedule upon which a given Job will be executed.

SimpleTrigger is handy if you need 'one-shot' execution (just single execution of a job at a given moment in time), or if you need to fire a job at a given time, and have it repeat N times, with a delay of T between executions.

on the exactly specified intervals of SimpleTrigger. 

CronTrigger is useful if you wish to have triggering based on calendar-like schedules - such as "every Friday, at noon" or "at 10:15 on the 10th day of every month."

With CronTrigger, you can specify firing-schedules such as "every Friday at noon", or "every weekday and 9:30 am", or even "every 5 minutes between 9:00 am and 10:00 am on every Monday, Wednesday and Friday during January".

JobBuilder - used to define/build JobDetail instances, which define instances of Jobs.

TriggerBuilder - used to define/build Trigger instances.

使用

1.quartz.properties  不是必须的,但是可以提供一些基本的配置.

2.many triggers can be associated with the same job. 

3.Jobs and Triggers are given identifying keys(unique within the group) as they are registered with the Quartz scheduler. The keys of Jobs and Triggers (JobKey and TriggerKey) allow them to be placed into 'groups' which can be useful for organizing your jobs and triggers into categories such as "reporting jobs" and "maintenance jobs". 

4.Quartz needs to be informed about various attributes that you may wish an instance of that job to have. This is done via the JobDetail class

5.JobDetail instances are built using the JobBuilder class. import static org.quartz.JobBuilder.*;

JobDataMap, which is part of the JobDetail object.

6.The JobDataMap can be used to hold any amount of (serializable) data objects which you wish to have made available to the job instance when it executes. JobDataMap is an implementation of the Java Map interface, and has some added convenience methods for storing and retrieving data of primitive types.

triggers contain a variety of customizable options that you need to be aware of and understand before you can make full use of Quartz. 

Cron Triggers.

like SimpleTrigger, CronTrigger has a startTime which specifies when the schedule is in force, and an (optional) endTime that specifies when the schedule should be discontinued.

Cron-Expressions are used to configure instances of CronTrigger.

Cron-Expressions are strings that are actually made up of seven sub-expressions, separated with white-space

Seconds numbers 0 to 59 for seconds and minutes

Minutes numbers 0 to 59 for seconds and minutes

Hours values 0 to 23 for hours.

Day-of-Month Day-of-Month can be any value 1-31

Month Months can be specified as values between 0 and 11, or by using the strings JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC

Day-of-Week values between 1 and 7 (1 = Sunday) or by using the strings SUN, MON, TUE, WED, THU, FRI and SAT.

Year (optional field)

"0 0 12 ? * WED" -  means "every Wednesday at 12:00:00 pm".  WED->"MON-FRI", "MON,WED,FRI", or even "MON-WED,SAT".

The '/' character can be used to specify increments to values. 

0/15' in the Minutes field, it means 'every 15th minute of the hour, starting at minute zero'. 

'3/20' in the Minutes field, it would mean 'every 20th minute of the hour, starting at minute three' - or in other words it is the same as specifying '3,23,43' in the Minutes field. 

"/35" does *not mean "every 35 minutes" - it mean "every 35th minute of the hour, starting at minute zero" - or in other words the same as specifying '0,35'.

The '?' character is allowed for the day-of-month and day-of-week fields. It is used to specify "no specific value". 

The 'L' character is allowed for the day-of-month and day-of-week fields. This character is short-hand for "last",

"L" in the day-of-month field means "the last day of the month" - day 31 for January, day 28 for February on non-leap years.

day-of-week field by itself, it simply means "7" or "SAT".

"6L" or "FRIL" both mean "the last friday of the month". 

"L-3" which would mean the third-to-last day of the calendar month. 

'W' is used to specify the weekday (Monday-Friday) 

"15W" as the value for the day-of-month field, the meaning is: "the nearest weekday to the 15th of the month".

'#' is used to specify "the nth" XXX weekday of the month. 

"6#3" or "FRI#3" in the day-of-week field means "the third Friday of the month".

"0 0/5 * * * ?" create a trigger that simply fires every 5 minutes

"10 0/5 * * * ?" create a trigger that fires every 5 minutes, at 10 seconds after the minute (i.e. 10:00:10 am, 10:05:10 am, etc

"0 30 10-13 ? * WED,FRI" create a trigger that fires at 10:30, 11:30, 12:30, and 13:30, on every Wednesday and Friday.

"0 0/30 8-9 5,20 * ?" fires every half hour between the hours of 8 am and 10 am on the 5th and 20th of every month. Note that the trigger will NOT fire at 10:00 am, just at 8:00, 8:30, 9:00 and 9:30

Field Name     Mandatory      Allowed Values      Allowed Special Characters

Seconds           YES 0-59 , - * /

Minutes YES 0-59 , - * /

Hours YES 0-23 , - * /

Day of month YES 1-31 , - * ? / L W

Month YES 1-12 or JAN-DEC , - * /

Day of week YES 1-7 or SUN-SAT , - * ? / L #

Year NO empty, 1970-2099 , - * /

So cron expressions can be as simple as this: * * * * ? *

or more complex, like this: 0/5 14,18,3-39,52 * ? JAN,MAR,SEP MON-FRI 2002-2010

* ("all values") - used to select all values within a field. For example, "" in the minute field means *"every minute".

? ("no specific value") - useful when you need to specify something in one of the two fields in which the character is allowed, but not the other. For example, if I want my trigger to fire on a particular day of the month (say, the 10th), but don't care what day of the week that happens to be, I would put "10" in the day-of-month field, and "?" in the day-of-week field. See the examples below for clarification.

- - used to specify ranges. For example, "10-12" in the hour field means "the hours 10, 11 and 12".

, - used to specify additional values. For example, "MON,WED,FRI" in the day-of-week field means "the days Monday, Wednesday, and Friday".

/ - used to specify increments. For example, "0/15" in the seconds field means "the seconds 0, 15, 30, and 45". And "5/15" in the seconds field means "the seconds 5, 20, 35, and 50". You can also specify '/' after the '' character - in this case '' is equivalent to having '0' before the '/'. '1/3' in the day-of-month field means "fire every 3 days starting on the first day of the month".

**Expression** **Meaning**

0 0 12 * * ? Fire at 12pm (noon) every day

0 15 10 ? * * Fire at 10:15am every day

0 15 10 * * ? Fire at 10:15am every day

0 15 10 * * ? * Fire at 10:15am every day

0 15 10 * * ? 2005 Fire at 10:15am every day during the year 2005

0 * 14 * * ? Fire every minute starting at 2pm and ending at 2:59pm, every day

0 0/5 14 * * ? Fire every 5 minutes starting at 2pm and ending at 2:55pm, every day

0 0/5 14,18 * * ? Fire every 5 minutes starting at 2pm and ending at 2:55pm, AND fire every 5 minutes starting at 6pm and ending at 6:55pm, every day

0 0-5 14 * * ? Fire every minute starting at 2pm and ending at 2:05pm, every day

0 10,44 14 ? 3 WED Fire at 2:10pm and at 2:44pm every Wednesday in the month of March.

0 15 10 ? * MON-FRI Fire at 10:15am every Monday, Tuesday, Wednesday, Thursday and Friday

0 15 10 15 * ? Fire at 10:15am on the 15th day of every month

0 15 10 L * ? Fire at 10:15am on the last day of every month

0 15 10 L-2 * ? Fire at 10:15am on the 2nd-to-last last day of every month

0 15 10 ? * 6L Fire at 10:15am on the last Friday of every month

0 15 10 ? * 6L Fire at 10:15am on the last Friday of every month

0 15 10 ? * 6L 2002-2005 Fire at 10:15am on every last friday of every month during the years 2002, 2003, 2004 and 2005

0 15 10 ? * 6#3 Fire at 10:15am on the third Friday of every month

0 0 12 1/5 * ? Fire at 12pm (noon) every 5 days every month, starting on the first day of the month.

0 11 11 11 11 ? Fire every November 11th at 11:11am.

jobKey

startTime

endTime

Priority default priority of 5(same fire time. )

Quartz Calendar objects (not java.util.Calendar objects) can be associated with triggers at the time the trigger is defined and stored in the scheduler. Calendars are useful for excluding blocks of time from the the trigger's firing schedule. 

Calendars must be instantiated and registered with the scheduler via the addCalendar(..) method.

RAMJobStore is the simplest JobStore to use, it is also the most performant (in terms of CPU time). RAMJobStore gets its name in the obvious way: it keeps all of its data in RAM. 

JDBCJobStore is also aptly named - it keeps all of its data in a database via JDBC. 

JDBCJobStore works with nearly any database, it has been used widely with Oracle, PostgreSQL, MySQL, MS SQLServer, HSQLDB, and DB2. 

TerracottaJobStore is new with Quartz 1.7.

最佳实践

FROM:http://www.quartz-scheduler.org/documentation/best-practices

Skip Update Check

(Quartz contains an "update check" feature that connects to a server to check if there is a new version of Quartz available for download. )

org.quartz.scheduler.skipUpdateCheck: true   org.quartz.scheduler.skipUpdateCheck: true

Only Store Primitive Data Types (including Strings) In the JobDataMap

Use TriggerUtils

TriggerUtils:offers a simpler way to create triggers (schedules)

Has various methods for creating triggers with schedules that meet particular descriptions, 

Offers a simple way to create Dates (for start/end dates)

Offers helpers for analyzing triggers (e.g. calculating future fire times)

JDBC JobStore

Never Write Directly To Quartz's Tables

Never Point A Non-Clustered Scheduler At the Same Database As Another Scheduler With The Same Scheduler Name

Ensure Adequate Datasource Connection Size

Daylight Savings Time

Avoid Scheduling Jobs Near the Transition Hours of Daylight Savings Time

SimpleTriggers are not affected by Daylight Savings Time as they always fire at an exact millisecond in time, and repeat an exact number of milliseconds apart.

Because CronTriggers fire at given hours/minutes/seconds, they are subject to some oddities when DST transitions occur.

Waiting For Conditions

Throwing Exceptions

If a job throws an exception, Quartz will typically immediately re-execute it (and it will likely throw the same exception again). It's better if the job catches all exception it may encounter, handle them, and reschedule itself, or other jobs. to work around the issue.

org.quartz.scheduler.instanceName = Job-Scheduler
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.scheduler.skipUpdateCheck=true
import java.util.Date;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;

public class HelloSchedulerJob implements Job
{
	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException
	{
		JobKey key = context.getJobDetail().getKey();
		JobDataMap dataMap = context.getJobDetail().getJobDataMap();
		String key1 = dataMap.getString("key1");
		float key2 = dataMap.getFloat("key2");
		System.out.println(key+"_"+key1 + "_" + key2 + new Date());
	}
}
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;

import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;

public class HelloScheduler
{

	public static void main(String[] args) throws SchedulerException
	{
		Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
		//StdSchedulerFactory.getScheduler();

		JobKey jk = new JobKey("Job-Hello");
		// define the job and tie it to our HelloJob class
		JobDetail job = newJob(HelloSchedulerJob.class)
				.withIdentity(jk)
				.withIdentity("job1", "group1") // name "job1", group "group1"
				.usingJobData("key1", "Hello World!")
			    .usingJobData("key2", 3.141f)
				.build();

		// Trigger the job to run now, and then repeat every 5 seconds
		Trigger trigger = newTrigger()
				.withIdentity("trigger1", "group1")
				.startNow()
				.withSchedule(simpleSchedule()
						.withIntervalInSeconds(5)
						.repeatForever())
				.build();

		// Tell quartz to schedule the job using our trigger
		scheduler.scheduleJob(job, trigger);
		scheduler.start(); //the Scheduler will not actually act on any triggers (execute jobs) until it has been started with the start() method, 
		 
		JobDetail jd =  scheduler.getJobDetail(jk);
		System.out.println(jd);
		//scheduler.shutdown();
	}

}
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;

public class HelloSchedulerCron
{

	public static void main(String[] args) throws SchedulerException
	{
		Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); 
		JobDetail job = newJob(HelloSchedulerJob.class).withIdentity("job1", "group1").build();
		Trigger trigger = newTrigger()
			    .withIdentity("trigger3", "group1")
			    .withSchedule(cronSchedule("0 0/5 * * * ?"))
			    .forJob("job1", "group1")
			    .build();
		  
		// .withSchedule(dailyAtHourAndMinute(10, 42))
		// .withSchedule(cronSchedule("0 42 10 * * ?"))
		// .withSchedule(weeklyOnDayAndHourAndMinute(DateBuilder.WEDNESDAY, 10, 42))
		// .inTimeZone(TimeZone.getTimeZone("America/Los_Angeles"))
		
		scheduler.scheduleJob(job, trigger);
		scheduler.start();
		// scheduler.shutdown();
	}

}
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;

import org.quartz.DateBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import org.quartz.impl.StdSchedulerFactory;

public class HelloSchedulerSimpleTrigger
{

	public static void main(String[] args) throws SchedulerException
	{
		Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
		// define the job and tie it to our HelloJob class
		JobDetail job = newJob(HelloSchedulerJob.class).withIdentity("job1", "group1").build();

		/*--
		 // 方式一 Build a trigger for a specific moment in time, with no repeats:
		 // SimpleTrigger trigger = (SimpleTrigger) newTrigger().withIdentity("trigger1", "group1").startAt(new Date()).forJob("job1", "group1").build();

		// 方式二 Build a trigger for a specific moment in time, then repeating every ten seconds ten times:
		SimpleTrigger trigger = newTrigger().withIdentity("trigger3", "group1").startAt(new Date()).withSchedule(simpleSchedule().withIntervalInSeconds(10).withRepeatCount(10)).forJob(job).build();

		//方式三  Build a trigger that will fire once, five minutes in the future:
		SimpleTrigger trigger = (SimpleTrigger) newTrigger().withIdentity("trigger5", "group1").startAt(DateBuilder.futureDate(5, IntervalUnit.MINUTE)).forJob(job) .build();
		
		//方式四  Build a trigger that will fire now, then repeat every five minutes, until the hour 22:00:
		SimpleTrigger trigger = (SimpleTrigger) newTrigger().withIdentity("trigger5", "group1").withSchedule(simpleSchedule().withIntervalInMinutes(5).repeatForever()).endAt(DateBuilder.dateOf(22, 0, 0)).build();
		
		//方式五Build a trigger that will fire at the top of the next hour, then repeat every 2 hours, forever:
		SimpleTrigger trigger = (SimpleTrigger) newTrigger().withIdentity("trigger5", "group1").startAt(DateBuilder.evenHourDate(null)).withSchedule(simpleSchedule().withIntervalInMinutes(2).repeatForever()).build();
		
		 */
		
		//Build a trigger that will fire at the top of the next hour, then repeat every 2 hours, forever:
		SimpleTrigger trigger = (SimpleTrigger) newTrigger().withIdentity("trigger5", "group1").startAt(DateBuilder.evenHourDate(null)).withSchedule(simpleSchedule().withIntervalInMinutes(2).repeatForever()).build();
		
		// Tell quartz to schedule the job using our trigger
		scheduler.scheduleJob(job, trigger);
		scheduler.start();

		// scheduler.shutdown();
	}

}

猜你喜欢

转载自zhengchao123.iteye.com/blog/1876126