Quartz detailed 2:quartz

Source: Internet
Author: User
Tags require time interval

http://blog.itpub.net/11627468/viewspace-1763498/

First, quartz core concept

Let's take a look at a picture:

Scheduler

Task Scheduler

Trigger

triggers, which define task scheduling time rules

Job

Tasks, which are scheduled tasks

Misfire

A task scheduled to be executed but not actually executed.



Job: is an interface with only one method void execute (Jobexecutioncontext context), the developer implements the interface definition to run the task, and the Jobexecutioncontext class provides various information about the scheduling context. The job runtime information is stored in the Jobdatamap instance;Jobdetail: Quartz re-creates a job instance every time the job is executed, so it does not directly accept an instance of the job, instead it receives a job implementation class so that the job is instantiated by the reflection mechanism of newinstance () at runtime. Therefore, a class is needed to describe the job implementation class and other related static information, such as job name, description, Association Listener and other information, jobdetail assume this role.Trigger: Is a class that describes the time-triggered rules that trigger job execution. There are mainly two subclasses of Simpletrigger and Crontrigger. Simpletrigger is the most suitable choice when only one or a fixed time interval is required, while Crontrigger can define scheduling schemes for various complex time rules through cron expressions: 5:0 per 9:00, Monday, Wednesday, Friday pm 0 implementation, etc.;Calendar: Unlike Org.quartz.Calendar and Java.util.Calendar, it is a collection of some calendar-specific points of time (you can simply consider Org.quartz.Calendar as a collection of Java.util.Calendar- Java.util.Calendar represents a calendar point in time, without special instructions the calendar that follows refers to Org.quartz.Calendar). A trigger can be associated with more than one calendar to exclude or include certain points in time. Let's say we schedule a task for Monday 10:00 every week, but if you encounter a legal holiday and the task does not execute, then you need to use the calendar for point exclusion on the basis of the trigger trigger mechanism.Scheduler: Represents a quartz independent run container, trigger and Jobdetail can be registered to scheduler, both have their own group and name in scheduler, and the group and name are the basis for scheduler to find an object in the positioning container. The trigger group and name must be unique, and the Jobdetail group and name must also be unique (but can be the same as the trigger group and name, because they are of different types).   Scheduler defines multiple interface methods that allow external access and control of trigger and jobdetail in the container through groups and names. Scheduler can bind trigger to a jobdetail so that the corresponding job is executed when the trigger is triggered. A job can correspond to multiple trigger, but one trigger can only correspond to one job. You can create a scheduler instance from Schedulerfactory. Scheduler has a schedulercontext that is similar to ServletContext, holds scheduler contextual information, and the job and trigger can access information within Schedulercontext. The Schedulercontext internally uses a map to maintain these contextual data in a key-value pair, Schedulercontext provides multiple put () and getxxx () methods for saving and retrieving data. The corresponding Schedulercontext instance can be obtained by scheduler# GetContext ();ThreadPool: Scheduler uses a thread pool as the infrastructure for the task to run, and the task increases efficiency by sharing threads in the thread pool.

Second, how to use
For simple use, you can refer to Quartz's example, the links below are some introductory help.
http://blog.csdn.net/ychatou1220/article/details/5806871
http://blog.csdn.net/ychatou1220/article/details/5806914
http://blog.csdn.net/ychatou1220/article/details/5806946


Three, quartz design analysis

quartz.properties File

Quartz has a configuration file called Quartz.properties that allows you to modify the framework runtime environment. The default is to use the Quartz.properties file inside the Quartz.jar. Of course, you should create a copy of the quartz.properties file and put it in your project's classes directory so that the class loader can find it.

Once you add the Quartz.jar file and the third-party library to your project and the Quartz.properties file is in the classes directory of your project, you can create the job. However, before we do this, let's take a moment to briefly discuss the quartz architecture.

Quartz Internal Architecture

In terms of size, quartz is similar to most open source frameworks. There are about 300 Java classes and interfaces, and are organized into 12 packages. This can be compared to Apache struts, which takes about 325 classes and interfaces and organizes them into 11 packages. Although scale is hardly used as a feature to measure the quality of the framework, the key here is that quarts contains many features, whether these features and feature sets become, or should be, factors that judge the quality of an open source or non-open source framework.

Quartz Scheduler

The core of the quartz framework is the scheduler. The scheduler is responsible for managing the Quartz Application Runtime environment. The scheduler does not do all the work by itself, but relies on some very important parts within the framework. Quartz is not just thread and thread management. To ensure scalability, the quartz uses a multithreaded-based architecture.

At startup, the framework initializes a set of worker threads that are used by the scheduler to execute scheduled jobs. This is how quartz can run multiple jobs concurrently. Quartz relies on a loosely coupled thread pool management component to manage the threading environment. In this article, we will refer to thread pool management several times, but each object inside the quartz is configurable or customizable. So, for example, if you want to plug in your own thread pool management facility, I guess you'll be able to.



Job

In quartz jargon, a job is a simple Java class that performs tasks. The task can be any Java code. You only need to implement the Org.quartz.Job interface and throw the jobexecutionexception exception in case of a critical error.

The job interface contains a unique method, execute (), from which jobs are executed. Once the job interface and the Execute () method are implemented, when Quartz determines that the job is running, it will call your job. The Execute () method is exactly what you want to do.

Job Management and storage

Once the job is dispatched, the scheduler needs to remember and track the jobs and the number of times they are executed. This is not very useful if your job is called after 30 minutes or every 30 seconds. In fact, job execution requires very accurate and immediate invocation of the Execute () method on the scheduled job. Quartz uses a concept called job storage (Jobstore) to do job storage and management.

Active Job Storage

Quartz provides two types of basic job storage. The first type is called Ramjobstore, which uses the usual memory to persist scheduler information. This type of job store is most easily configured, constructed, and run. For many applications, this kind of job storage is sufficient.

However, because dispatcher information is stored in the memory that is allocated to the JVM, all scheduling information is lost when the application stops running. If you need to persist scheduling information between reboots, you will need a second type of job store.

The second type of job store actually provides two different implementations, but both implementations are generally referred to as the JDBC job store. Both JDBC Job stores require both the JDBC driver and the background database to persist dispatcher information. The difference between the two types is whether you want to control the database transaction or this release control to the application server such as Bea's WebLogic or JBoss. (This is similar to the difference between bean-managed transactions and container-managed transactions in the Java EE domain), which are the two JDBC job stores:

· JOBSTORETX: When you want to control transactions or work in a non-application server environment is used

· JOBSTORECMT: Used when you work in an application server environment and want the container to control transactions.

The JDBC Job store is designed for users who need the scheduler to maintain scheduling information.

jobs and triggers

The quartz designer made a design choice to leave the job from the dispatch. Triggers in quartz are used to tell the scheduler when a job is triggered. The framework provides a trigger type, but the two most commonly used are Simpletrigger and Crontrigger. The Simpletrigger is designed to require simple ignition and dispatch.

Typically, if you need the number of seconds to wait between a given time and number of times or two times to spark a job, then Simpletrigger is right for you. On the other hand, if you have a lot of complex job scheduling, you may need to crontrigger.

The Crontrigger is based on calendar-like scheduling. You should use Crontrigger when you need to do your homework 10:30 A.M. every day except Saturday and Sunday. As its name implies, Crontrigger is based on the UNIX cloning expression.

As an example, the following quartz cloning expression will execute a job 10:15 A.M. every day from Monday to Friday.

0 15 10? * Mon-fri

The following expression

0 15 10? * 6L 2002-2005

The job will be executed in the last Friday 10:15 A.M. of each month from 2002 to 2005. You can't use Simpletrigger to do these things. You can use either of the two, but whichever is appropriate depends on your scheduling needs.

missed Trigger (misfire)

Trigger also has an important attribute misfire; If scheduler is turned off, or if there are no threads available in the quartz thread pool to perform the job, the persistence trigger misses (MISS) its trigger time, which is the missed trigger (misfire). Different types of trigger have different misfire mechanisms. They use smart policy by default, which dynamically adjusts behavior based on the type and configuration of the trigger. When the scheduler is started, query the persistence trigger for all missed triggers (misfire). The trigger information is then updated according to their respective misfire mechanisms. When you use quartz in your project, you should be familiar with the misfire mechanisms of various types of trigger, which are described in Javadoc. Details of the misfire mechanism will be introduced in the context of specific trigger.


scheduling a job

Let's go into the actual discussion by looking at an example. It is assumed that you are managing a department and that whenever a customer stores a file on its FTP server, it must be notified by e-mail. Our job will log on to the remote server with FTP and download all the files found.

It then sends an e-mail message containing the number of files found and downloaded. It's easy to help people get out of this task all day long, even at night without thinking about it. We can set the job cycle to check every 60 seconds continuously and work in 7x24 mode. This is the full purpose of the quartz framework.

First create a job class that will execute FTP and email logic. The following example shows the Quartz job class, which implements the Org.quartz.Job interface.


invoking a job with the scheduler

Create a job first, but for the job to be called by the Scheduler, you have to explain to the scheduler the time and frequency of the call to your job. This is done by the trigger associated with the job. We intend to use simpletrigger because we are only interested in looping the job about every 60 seconds.

Jobs and triggers are dispatched through the Quartz scheduler interface. We need to get an instance of the scheduler from the Scheduler factory class. The easiest way to do this is to call the static method Getdefaultscheduler () on the Stdschedulerfactory class.

Using the quartz framework, you need to call the start () method to start the scheduler. The code in example 3 follows the general pattern of most quartz applications: create one or more jobs, create and set triggers, schedule jobs and triggers with the scheduler, and start the scheduler.

programming scheduling with declarative scheduling

We are programmed to dispatch our scanftpsitejob operations. That is, we use Java code to set up jobs and triggers. The quartz framework also supports the declaration of set job scheduling within an XML file. The Declaration method allows us to modify which job is executed more quickly.

The quartz framework has a plug-in that is responsible for reading the XML configuration file. The XML configuration file contains job and trigger information about starting the Quartz app. Jobs in all XML files are added to the scheduler along with related triggers. You still need to write the job class, but the scheduler that configures those job classes is very dynamic. You can compare elements in an XML file with example 3 code, which is conceptually the same. The benefit of using the declaration method is that maintenance becomes extremely simple, simply by changing the XML configuration file and restarting the Quartz application. No code changes, no recompilation, no redeployment.

stateful and stateless jobs

Job to be stateless. This means that between two job executions, there is no maintenance of jobdatamap state changes during job execution. If you need to be able to increase, delete, change the value of Jobdatamap, and can let the job at the next execution to see this state change, you need to use quartz stateful job.

The quartz stateful job implements the Org.quartz.StatefulJob interface.

The key difference between stateless and stateful jobs is that stateful jobs have only one instance per execution. In most cases, a stateful job does not bring back big problems. However, if you have a job that requires frequent execution or a job that takes a long time to complete, stateful jobs can cause scalability problems.



Listeners and plugins

Everyone loves listening and plugins. Today, almost any open source framework is downloaded, and you will certainly find support for both concepts. Listening is the Java class you create, and you receive a callback from the framework when a critical event occurs. For example, these can be set up to notify your listener when a job is dispatched, without scheduling, or when a trigger terminates and no longer has a spark. The quartz framework includes scheduler monitoring, job, and trigger snooping. You can configure jobs and triggers to listen for global listening or for job and trigger-specific monitoring.

Once one of your specific listeners is invoked, you can use this technique to do something you want to do in a listening class. For example, if you want to send an e-mail message each time the job is completed, you can write the logic into the job or joblistener it inside. Writing into the Joblistener method forces the use of loose coupling in favor of better design.

The quartz plugin is a new feature that can be created and added to the quartz framework without modifying the quartz source code. He is designed for developers who want to extend the quartz framework without time to commit changes to the Quartz development team and wait for a new version. If you are familiar with the struts plugin, then you can fully understand the use of the quartz plugin.

Rather than providing a limited extension point that doesn't meet your needs, it's better to have a quartz extension point by using a plug-in.

Cluster Quartz applications

Whether the quartz application can be clustered, horizontal or vertical, depends on your own needs. Clustering provides the following benefits:

· Elasticity of

· High Availability

· Load Balancing

Currently, quartz can only support clusters with relational databases and JDBC job stores. Future versions of this restriction will disappear and with ramjobstore clusters will be possible and will not require the support of the database.



IV. Structure and Process analysis

1, the start of the timer
Reference: http://seanhe.iteye.com/blog/691835

Referring to this picture, the first quartz load can be in two ways:
Mode 1: Through the servlet, refer to: http://blog.csdn.net/ychatou1220/article/details/5806914
Mode 2: Through spring, for example:

Click (here) to collapse or open <bean id= "Scheduler" class= "Org.springframework.scheduling.quartz.SchedulerFactoryBean" >
<property name= "DataSource" >
<ref bean= "Scheduledatasource"/>
</property>
<property name= "Autostartup" value= "true"/>
<property name= "Schedulerfactoryclass" value= "Org.quartz.impl.StdSchedulerFactory" ></property>
<property name= "configlocation" value= "Classpath:quartz.properties"/>
<property name= "Globaljoblisteners" >
<list>
<ref bean= "Joblistener"/>
</list>
</property>
</bean> Springcontext will load his Afterpropertiesset method when loading Schedulerfactorybean.
Reference: http://www.cnblogs.com/java-boy/archive/2012/12/21/2827729.html
And Schedulerfactorybean will go with the quartz stdschedulerfactory the initial configuration, Stdschedulerfactory will create class Quartzscheduler
Quartzscheduler,quartzscheduler will start the total control thread quartzschedulerthread the nonstop round robin.

The code for round robin is:

Click (here) to collapse or open the public void run () {
Boolean lastacquirefailed = false;
while (!halted.get ()) {
......

int availthreadcount = Qsrsrcs.getthreadpool (). Blockforavailablethreads ();
if (Availthreadcount > 0) {

......

The scheduler looks for a certain number of trigger within 30 seconds in the trigger queue (need to ensure that the cluster node's system time is consistent)
triggers = Qsrsrcs.getjobstore (). Acquirenexttriggers (
Now + Idlewaittime, Math.min (Availthreadcount, Qsrsrcs.getmaxbatchsize ()), Qsrsrcs.getbatchtimewindow ());

......

Trigger Trigger
list<triggerfiredresult> res = Qsrsrcs.getjobstore (). triggersfired (triggers);

......

Release Trigger
for (int i = 0; i < triggers.size (); i++) {
Qsrsrcs.getjobstore (). Releaseacquiredtrigger (Triggers.get (i));
}

}
The picture is like this:


Just look at the picture on the left: normal thread
1, whether the thread halt live, no words continue;
2, wait until the line constructor thread can be processed;
3, the scheduler in the trigger queue to find a certain number of trigger in 30s batch execution, 1.8.6 is 1, 2.2. The 1 version defaults to 1, but this value can be adjusted.
The trigger will be saved to the Fired_trigger table by Insertfiredtrigger.
4, wait until the time.
5, lock, batch execution >1 only lock, so that the cluster other service node can not operate. Then take the trigger that need to be triggered and then unlock it.
6, ignition, the thread pool executes the threads, takes the trigger, the JOB, and then executes on this thread.
7. Modify the database status to be executing.



Let's summarize the structure of the class:


1, Stdschedulerfactory is factory class, there is a factory class directschedulerfactory is relatively simple, and stdschedulerfactory can be loaded with various properties.
The load initialize method of the property, contants inside are parameters, can be added as described in Quartz.properties.
2, Stdschedule is just a quartzschedule packaging class, the method is clearer.
3, Quartzscheduler is the core class of the whole time task framework work, the above class diagram shows only a few core members of the Quartzscheduler.
4. Quartzschedulerresources can be considered as a container for storing all configurations and some of the resources initialized by configuration, including the storage job definition Jobstor
5, Jobstore can have a variety of implementations, we are using the default Ramjobstore;
6. ThreadPool, another very important object is ThreadPool, which manages all the threads required to execute the job we define. The size of this thread pool is configured by the "Org.quartz.threadPool.threadCount" I mentioned above. Quartzscheduler Another important member is quartzschedulerthread, without this thread, all of our defined tasks will not be triggered, that is, it is the "daemon" of the quartz daemon, It constantly goes to find the right job and triggers these job executions.
7. The main business logic of Quartzschedulerthread has been mentioned above.

2. Trigger Ignition

Click (here) to collapse or open if (goahead)  {
                             try {
                                 //Trigger Trigger
                                  List<TriggerFiredResult>  res = qsrsrcs.getjobstore ().

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.