Several ways to implement timed tasks

Source: Internet
Author: User
Java Technology Stack 2016-10-22 11:04

Most systems will encounter functions related to timing tasks, such as regular backup database, regular modification of certain information, orders 30 minutes automatic cancellation, and so on, many functions can be based on the regular Linux command to complete, there are special business systems closely related to the task requires code to complete, There are many ways to implement this function, if your project is based on spring, through configuration can be implemented, or we can use the JDK with the timer, thread pool to do.

First of all, let's briefly review how to use the Timer and thread pool (scheduledexecutorservice) to achieve a simple scheduling task. Both timer and Scheduledexecutorservice can be used for timed tasks, with administrative tasks deferred execution ("Perform tasks like 1000ms") and periodic execution ("such as every 500ms of this task"). However, the latter was recommended after JDK1.5, for the following reasons:

1, timer on the scheduling support is based on absolute time, not relative time, this task on the system clock changes are sensitive; But scheduledthreadexecutor only supports relative time.

2. If TimerTask throws an unchecked exception, the timer will produce unpredictable behavior. The timer thread does not catch exceptions, so an unchecked exception thrown by TimerTask terminates the timer thread. At this point, TimerTask, which has been scheduled but not yet executed, will never be executed, and new tasks cannot be scheduled.

3, timer inside the task if the execution time is too long, will exclusive timer object, make the next task can not when the execution, Scheduledexecutorservice will not appear timer problem (unless you only engage in a single thread pool task area).

Let's take a look at how timer and Scheduledexecutorservice are used to create a timed task:



Today our protagonist is quartz, but it is necessary to declare that there is no explanation about the basic knowledge of quartz, because these knowledge is relatively simple, we can learn by ourselves Baidu. Official address is recommended here: http://www.quartz-scheduler.org/

Quartz is a opensymphony open source organization in the Job scheduling field another open source project, it can be combined with Java EE and J2SE applications can also be used alone. Quartz can be used to create complex programs that are simple or run for 10, hundred, or even tens of thousands of jobs. Jobs can be made into standard Java components or EJBs. The latest version of quartz is quartz 2.2.3.

Although we can use spring to implement timed scheduling with a simple configuration, in some cases we need to separate the services from time to time, so that they can be deployed separately, and scheduling services can be used as middleware to do other things. Today we'll see if we don't use spring, just use quartz How to implement task scheduling.

1. Service Architecture Design

The timer service, which runs as a stand-alone service, is a mutually reinforcing relationship with other systems, either synchronously or asynchronously. At the beginning of the design, I was going to do it as an asynchronous system, it is only responsible for task scheduling, and the specific execution is done through the call interface. and the task of storage, is currently based on memory, I tried to MySQL based on the database is not a big problem, but there are some differences in configuration.

2. Issues to be considered

(1) interface design

Generally we need to support Registe,delete,update,query interface. Here we define a Registe interface as a demo.

(2) Task parameters

Other systems to use this system, to invoke the Registe interface, we need to define an entity to store the task information, and some fields are required, such as where the task comes from, which group the task belongs to (such as the Order group), the type of task (a one-time or recurring task), the time the task starts, The end time of the task, the data (such as the order ID) that is required when the task is executed, and what the loop parameter is (once a day or once a week) if the task is a recurring task. Once a task is created, it will produce a unique key, as well as the current execution status (not started, executed, closed), and so on.

For task parameters I will focus on the classification of tasks, where I divide the task into two categories (1) one-time task, that is, after the completion of the second (2) Expression of the task, through the quartz supported conf expression to complete the task, Time is more flexible can be a one-time cycle, and so on. In addition here you may have a question as to why we are developing such an interface. Some tasks are built into the system, they are automatically registered when the service is started, and some tasks are generated later, such as orders to register the task. Below we will learn the specific code by an example.

3, the actual case

(1) Register interface definition

(2) Container instance creation

Before the container registers these tasks, we need to let our services start and create container instances. Quartz obtains the scheduler instance through the Schedulerfactory factory and invokes its Start method to complete the startup. After starting, we can put some key values in the context object and get used when the task executes.


When the service starts, it loads the quartz dispatch instance and calls the Loadsystemtasks method to load system-level tasks such as scheduled backup of the database, and then calls the Loadtaskfromdb method to load the unfinished tasks in the database (since the service is stopped, The task is not executed, so when the service starts, it loads the unfinished tasks first.

(3) Task Save logic

1, before saving, according to the parameters to obtain the task key.

2, first save to the database MySQL, to prevent service downtime, task loss can not find back.

3, and then save to the Quartz container, start the task.

You can place tasks in a container by using the scheduler Schedulerjob method.

(4) Task instance

The quartz container requires two core parameters (1) Jobdetail task Instance (2) Trigger time configuration when accepting the task, which means to indicate the execution information of the task, which indicates the beginning end time of the task, etc.

So when we design the interface, we need to pass two parameters, one is jobdetail and the other is trigger when we call Scheduler.schedulejob (Jobdetail, Trigger). We looked at how they were created through the code, and we did the encapsulation.

When creating a jobdetail, we associate an execution class, that is, Executejob, and tells the task container, the task's unique key value, to prevent duplication of tasks. When creating trigger, we are divided into one-off tasks and expression tasks. The way they are built is different.

schedulebuilder<?> Schedulebuilder = Simpleschedule ();

schedulebuilder<?> Schedulebuilder = Cronschedule (timejob.getconf ());

The expression task requires the client to pass in a string of expressions, and how the expression is written to learn separately, for example, for a simple example: 0 0/2 * *? Executes every two minutes.

(5) Task execution class

We've just set up our task execution class Executejob, which means that when a task gets to a point in time, it calls a Executejob method to complete a series of tasks.

Executejob implements the job interface and overrides the Execute method, in which we do our task, but it is also possible that we need to invoke the external interface to complete, but one problem is that the execution of this task is asynchronous and the spring container is independent, An instance that uses spring cannot be executed. There are several ways to get a container instance of spring:

(1) Use the Applicationutil tool class to obtain.

(2) Use Jobdatamap to obtain.

(3) Use context to obtain.

(6) Quartz configuration

Quartz supports memory and database-based storage of task samples, configured as follows:

Of course, if you choose to save the task based on the database, you also need to carry out a section of the database script, this can be found in Baidu. And if you're using a memory-based management task, you'll need to design your own database to store the information for those tasks. As far as my experience is concerned, if you have a higher system concurrency, the task is more recommended to use database based storage, if the task is relatively small, memory is fully adequate.

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.