Use quartz for Job Scheduling)

Source: Internet
Author: User
Tags websphere application server

See http://www.ibm.com/developerworks/cn/java/j-quartz/

Quartz is an open source project that provides a wide range of Job Scheduling sets. In this article, Software Engineer Michael Lipton and IT architect soobaek Jang introduced the quartz API, starting from a general overview of the framework, end with a series of code examples that demonstrate basic features of quart. After reading this article and reading the sample code, you should be able to apply the basic features of quartz to any Java application.

Modern web application frameworks have developed in terms of scope and complexity. Each underlying component of an application must also develop accordingly. Job Scheduling is a general requirement for Java applications in modern systems and is also a consistent requirement for Java developers. Although the current scheduling technology has developed much more than the original database trigger mark and independent scheduler thread, Job Scheduling is still not a small problem. The most suitable solution for this problem is the quartz API of opensymphony.

Quartz is an open-source job scheduling framework that provides a simple but powerful mechanism for Job Scheduling in Java applications. Quartz allows developers to schedule jobs by time interval (or day. It realizes the many-to-many relationship between jobs and triggers, and can associate multiple jobs with different triggers. Applications integrated with quartz can reuse jobs from different events and combine multiple jobs for one event. You can configure quartz through the attribute file (in the attribute file, you can specify the data source, global job, and/or trigger listener, plug-in, thread pool, and more for JDBC transactions, however, it is not integrated with the context or reference of the application server at all. The result is that the job cannot access the internal functions of the Web server. For example, when using the WebSphere Application Server, Jobs scheduled by quartz cannot affect the dynamic cache and data sources of the server.

This article uses a series of code examples to introduce the quartz API and demonstrate its mechanism, such as job, trigger, job repository, and attributes.

Getting started

To start using quartz, you must use the quartz API to configure the project. The procedure is as follows:

  1. Download the quartz API.
  2. Decompress and place the quartz-x.x.x.jar in the project folder, or place the file in the project's class path.
  3. Place the jar files in the core and/or optional folders in the project folder or the class path of the project.
  4. If you useJDBCJobStorePut all the JDBC jar files in the project folder or the project class path.

To help readers, I have compiled all necessary files, including DB2 JDBC files, into a zip file. See the download section to download the code.

Now let's take a look at the main components of the quartz API.



Back to Top

Jobs and triggers

The two basic units of the quartz scheduling package are jobs and triggers.JobIs an executable task that can be scheduled,TriggerProvides job scheduling. Although these two entities are easily combined, there is a reason to separate them in quartz, and it is also helpful.

By separating the job to be executed from its scheduling, quartz allows you to modify the scheduling trigger without losing the context of the job itself or the job. In addition, any single job can have multiple triggers associated with it.



Back to Top

Example 1: Job

Implementationorg.quartz.jobInterface to make the Java class executable. Listing 1 provides an example of a quartz job. This class uses a very simple output statement to overwriteexecute(JobExecutionContext context)Method. This method can contain any code we want to execute (all code examples are based on quartz 1.5.2, which is the stable release version when writing this article ).

Listing 1. simplequartzjob. Java

            package com.ibm.developerworks.quartz;            import java.util.Date;            import org.quartz.Job;            import org.quartz.JobExecutionContext;            import org.quartz.JobExecutionException;            public class SimpleQuartzJob implements Job {            public SimpleQuartzJob() {            }            public void execute(JobExecutionContext context) throws JobExecutionException {            System.out.println("In SimpleQuartzJob - executing its JOB at "            + new Date() + " by " + context.getTrigger().getName());            }            }            

Note that the execute method accepts oneJobExecutionContextObject as a parameter. This object provides the runtime context of the job instance. In particular, it provides access to the scheduler and trigger, the two work together to start the job and the jobJobDetailObject execution. Quartz places the job status inJobDetailObject andJobDetailThe constructor starts a job instance and separates the execution of the job from the status around the job.JobDetailObject Storage job listeners, groups, data ing, descriptions, and other job attributes.



Back to Top

Example 2: simple trigger

A trigger can schedule a task. Quartz provides several different triggers with different levels of complexity. In Listing 2SimpleTriggerDemonstrate the trigger basics:

Listing 2. simpletriggerrunner. Java

            public void task() throws SchedulerException            {            // Initiate a Schedule Factory            SchedulerFactory schedulerFactory = new StdSchedulerFactory();            // Retrieve a scheduler from schedule factory            Scheduler scheduler = schedulerFactory.getScheduler();            // current time            long ctime = System.currentTimeMillis();            // Initiate JobDetail with job name, job group, and executable job class            JobDetail jobDetail =            new JobDetail("jobDetail-s1", "jobDetailGroup-s1", SimpleQuartzJob.class);            // Initiate SimpleTrigger with its name and group name            SimpleTrigger simpleTrigger =            new SimpleTrigger("simpleTrigger", "triggerGroup-s1");            // set its start up time            simpleTrigger.setStartTime(new Date(ctime));            // set the interval, how often the job should run (10 seconds here)            simpleTrigger.setRepeatInterval(10000);            // set the number of execution of this job, set to 10 times.            // It will run 10 time and exhaust.            simpleTrigger.setRepeatCount(100);            // set the ending time of this job.            // We set it for 60 seconds from its startup time here            // Even if we set its repeat count to 10,            // this will stop its process after 6 repeats as it gets it endtime by then.            //simpleTrigger.setEndTime(new Date(ctime + 60000L));            // set priority of trigger. If not set, the default is 5            //simpleTrigger.setPriority(10);            // schedule a job with JobDetail and Trigger            scheduler.scheduleJob(jobDetail, simpleTrigger);            // start the scheduler            scheduler.start();            }            

Listing 2 instantiatesSchedulerFactoryTo obtain the scheduler. As discussed earlierJobDetailObject, its constructor must acceptJobAs a parameter. As the name suggests,SimpleTriggerThe instance is quite primitive. After creating an object, set several basic attributes to schedule the task immediately and repeat the task every 10 seconds until the job is executed for 100 times.

There are many other ways to manipulateSimpleTrigger. In addition to specifying the number of repetitions and repetition interval, you can also specify the maximum execution time or priority of a job in a specific calendar time (discussed later ). The maximum execution time can overwrite the specified number of repetitions to ensure that the running of the job does not exceed the maximum time.



Back to Top

Example 3: cron trigger

CronTriggerSupport RatioSimpleTriggerMore specific scheduling is not very complex. Based on cron expressions,CronTriggerSupports repetition intervals similar to calendars, rather than a single interval.SimpleTriggerIt is a major improvement.

Cron expressions include the following seven fields:

  • Seconds
  • Minute
  • Hours
  • Date in month
  • Month
  • Week date
  • Year (optional)

Special characters

The cron trigger uses a series of special characters, as shown below:

  • The backslash (/) character indicates the increment value. For example, in the second field, "5/15" indicates that the value starts from 5th seconds, every 15 seconds.

  • Question mark (?) The characters and letters are only available in the Date Field of the month and the date field of the week. The question mark indicates that this field does not contain specific values. Therefore, if you specify a date in the month, you can insert "?" In the Date Field of the week, Indicates that the date value of the week is irrelevant. The letter L isLast. In the Date Field of the month, the task is executed on the last day of the month. In the week Date Field, if "L" exists separately, it is equal to "7". Otherwise, it represents the last instance of the week date in the current month. Therefore, "0l" indicates that it will be executed on the last Sunday of the month.
  • The letter (w) in the date field within the month is executed on the workday closest to the specified value. Place "1 W" in the Date Field of the month, which means that the execution is arranged within the first business day of the month.
  • The pound sign (#) specifies a specific workday instance for a given month. Put "Mon #2" in the Date Field of the week, indicating that the task is scheduled for the second Monday of the month.
  • The asterisk (*) character is a wildcard character, indicating that this field can accept any possible value.

All these definitions may seem a little scary, but after a few minutes of practice, the cron expression will look very simple.

Listing 3 showsCronTrigger. Note:SchedulerFactory,SchedulerAndJobDetailAndSimpleTriggerThe instantiation In the example is the same. In this example, the trigger is modified. The cron expression specified here ("0/5 ****?") Schedule task execution every 5 seconds.

Listing 3. crontriggerrunner. Java

            public void task() throws SchedulerException            {            // Initiate a Schedule Factory            SchedulerFactory schedulerFactory = new StdSchedulerFactory();            // Retrieve a scheduler from schedule factory            Scheduler scheduler = schedulerFactory.getScheduler();            // current time            long ctime = System.currentTimeMillis();            // Initiate JobDetail with job name, job group, and executable job class            JobDetail jobDetail =            new JobDetail("jobDetail2", "jobDetailGroup2", SimpleQuartzJob.class);            // Initiate CronTrigger with its name and group name            CronTrigger cronTrigger = new CronTrigger("cronTrigger", "triggerGroup2");            try {            // setup CronExpression            CronExpression cexp = new CronExpression("0/5 * * * * ?");            // Assign the CronExpression to CronTrigger            cronTrigger.setCronExpression(cexp);            } catch (Exception e) {            e.printStackTrace();            }            // schedule a job with JobDetail and Trigger            scheduler.scheduleJob(jobDetail, cronTrigger);            // start the scheduler            scheduler.start();            }            


Back to Top

Advanced quartz

As shown above, you can access a large number of features with only jobs and triggers. However, quartz is a rich and flexible scheduling package. For those who are willing to study it, it also provides more functions. The next section describes some advanced features of quartz.



Back to Top

Job warehouse

Quartz provides two different methods to store data related to jobs and triggers in the memory or database. The first method isRAMJobStoreClass, which is the default setting. This job repository is the easiest to use and provides the best performance because all data is stored in the memory. The main disadvantage of this method is the lack of data persistence. Because data is stored in Ram, all information is lost when an application or system crashes.

To solve this problem, quartz providesJDBCJobStore. As the name suggests, the job warehouse stores all data in the database through JDBC. The cost of data persistence is reduced performance and increased complexity.

Set jdbcjobstore

As shown in the previous exampleRAMJobStoreInstance status. Because it is the default job repository, it can be used without additional settings. HoweverJDBCJobStoreSome Initialization is required.

Set and use in the ApplicationJDBCJobStoreTwo steps are required: First, you must create a database table used by the job warehouse. JDBCJobStoreCompatible with all mainstream databases, and quartz provides a series of SQL scripts for creating tables, which can simplify the setting process. You can find the SQL script for creating a table in the "docs/dbtables" directory of the quartz release package. Second, some attributes must be defined, as shown in table 1:

Table 1. jdbcjobstore attributes

Attribute name Value
Org. Quartz. jobstore. Class Org. Quartz. impl. jdbcjobstore. jobstoretx (or jobstorecmt)
Org. Quartz. jobstore. tableprefix Qrtz _ (optional, customizable)
Org. Quartz. jobstore. driverdelegateclass Org. Quartz. impl. jdbcjobstore. stdjdbcdelegate
Org. Quartz. jobstore. datasource Qzds (customizable)
Org. Quartz. datasource. qzds. Driver Com. IBM. db2.jcc. db2driver (cocould be any other database driver)
Org. Quartz. datasource. qzds. url JDBC: DB2: // localhost: 50000/qz_smpl (customizable)
Org. Quartz. datasource. qzds. User Db2inst1 (place userid for your own dB)
Org. Quartz. datasource. qzds. Password Pass4dbadmin (place your own password for user)
Org. Quartz. datasource. qzds. maxconnections 30

Listing 4 showsJDBCJobStoreData persistence. As in the previous exampleSchedulerFactoryAndSchedulerStart. Then, you no longer need to initialize the job and trigger. Instead, you need to obtain the trigger group name list, and then obtain the trigger name list for each group name. Note that each existing job should useScheduler.reschedule()Method. Only re-initializing jobs terminated when the previous application was running does not correctly load the trigger attributes.

Listing 4. jdbcjobstorerunner. Java

            public void task() throws SchedulerException            {            // Initiate a Schedule Factory            SchedulerFactory schedulerFactory = new StdSchedulerFactory();            // Retrieve a scheduler from schedule factory            Scheduler scheduler = schedulerFactory.getScheduler();            String[] triggerGroups;            String[] triggers;            triggerGroups = scheduler.getTriggerGroupNames();            for (int i = 0; i < triggerGroups.length; i++) {            triggers = scheduler.getTriggerNames(triggerGroups[i]);            for (int j = 0; j < triggers.length; j++) {            Trigger tg = scheduler.getTrigger(triggers[j], triggerGroups[i]);            if (tg instanceof SimpleTrigger && tg.getName().equals("simpleTrigger")) {            ((SimpleTrigger)tg).setRepeatCount(100);            // reschedule the job            scheduler.rescheduleJob(triggers[j], triggerGroups[i], tg);            // unschedule the job            //scheduler.unscheduleJob(triggersInGroup[j], triggerGroups[i]);            }            }            }            // start the scheduler            scheduler.start();            }            

Run jdbcjobstore

In the first running example, the trigger is initialized in the database. Figure 1 shows the database status after the trigger initialization but before the trigger is triggered. Therefore, based onsetRepeatCount()Method, SetREPEAT_COUNTSet to 100, whileTIMES_TRIGGEREDIt is 0. After the application is running for a period of time, the application stops.

Figure 1. Data in the database when using jdbcjobstore (before running)

Figure 2 shows the status of the database after the application is stopped. In this figure,TIMES_TRIGGEREDSet to 19, indicating the number of job runs.

Figure 2. After 19 iterations of the same data

When you start the application again,REPEAT_COUNTUpdated. This is obvious in figure 3. As shown in figure 3REPEAT_COUNTIs updated to 81, so the newREPEAT_COUNTEqualREPEAT_COUNTValue minus the previousTIMES_TRIGGEREDValue. In addition, the newTIMES_TRIGGEREDThe value is 7, indicating that the job has been triggered seven times since the application was restarted.

Figure 3. Data after 7 iterations of 2nd running

After the application is stopped again,REPEAT_COUNTValue is updated again. 4. The application has stopped and has not restarted. Similarly,REPEAT_COUNTValue updated to the previous oneREPEAT_COUNTValue minus the previous oneTIMES_TRIGGEREDValue.

Figure 4. Initial data before the trigger is run again



Back to Top

Usage attributes

As in useJDBCJobStoreYou can use many attributes to adjust the quartz behavior. Should be inQuartz. PropertiesFile. See references for a list of configurable properties. Listing 5 showsJDBCJobStoreAttributes of the example:

Listing 5. Quartz. Properties

            org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool            org.quartz.threadPool.threadCount = 10            org.quartz.threadPool.threadPriority = 5            org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true            # Using RAMJobStore            ## if using RAMJobStore, please be sure that you comment out the following            ## - org.quartz.jobStore.tablePrefix,            ## - org.quartz.jobStore.driverDelegateClass,            ## - org.quartz.jobStore.dataSource            #org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore            # Using JobStoreTX            ## Be sure to run the appropriate script(under docs/dbTables) first to create tables            org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX            # Configuring JDBCJobStore with the Table Prefix            org.quartz.jobStore.tablePrefix = QRTZ_            # Using DriverDelegate            org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate            # Using datasource            org.quartz.jobStore.dataSource = qzDS            # Define the datasource to use            org.quartz.dataSource.qzDS.driver = com.ibm.db2.jcc.DB2Driver            org.quartz.dataSource.qzDS.URL = jdbc:db2://localhost:50000/dbname            org.quartz.dataSource.qzDS.user = dbuserid            org.quartz.dataSource.qzDS.password = password            org.quartz.dataSource.qzDS.maxConnections = 30            

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.