Which is the best way to schedule jobs? Quartz was chosen

Posted by nigeledge on Fri, 10 Apr 2020 18:47:52 +0200

*With the advent of cloud platforms, big data, etc., users or potential visitors increasingly want to experience products for free, especially to apply for a system (such as turning on virtual machines, starting docker, etc.). However, the system hardware resources are limited. How can users actually operate cloud platform resources? That is a free three- or seven-day usage period (also a one-day usage period), if not expiredFor money renewal, the system will automatically clean up the resources requested by the cloud environment (for example, a cloud, a free trial expires, and an email reminder renewal is sent). Then the job scheduling function is used, which uses a timer (which can be used as a timed task and executed when it expires, like an alarm clock). There is a native timer Library in the java ecosystem, as well as the firstThree-way like Quartz,

Here's an example of how to use it

1. java's native timer components Timer and TimerTask

Timer is a timer tool that schedules a specified task to be executed in a background thread, which can schedule a task to be executed once or repeatedly.

Common methods in Timer classes

public class Timer {

    /**
    * task queue
    */
    private final TaskQueue queue = new TaskQueue();
    /**
     * The timer thread.
     */
    private final TimerThread thread = new TimerThread(queue);

    public Timer( );
    public Timer(boolean isDaemon);
    public Timer(String name);
    public Timer(String name, boolean isDaemon);

    //Execute the specified task after the specified delay
    public void schedule(TimerTask task, long delay);
    //Execute the specified task at the specified time
    public void schedule(TimerTask task, Date time);
    //The specified task starts with a specified delay and repeats with a fixed delay
    public void schedule(TimerTask task, long delay, long period);
    //The specified task starts repeated, fixed delays at the specified time
    public void schedule(TimerTask task, Date firstTime, long period);

    //The specified task starts repeating at a fixed rate after the specified delay
    public void scheduleAtFixedRate(TimerTask task, long delay, long period);
    //The specified task starts repeating at a fixed rate at a specified time
    public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period);

    //Terminate timer, discard all currently scheduled tasks
    public void cancel( );
    //Remove all canceled tasks from the timer's task queue
    public int purge( );

}

TimerTask, on the other hand, is an abstract class that implements the Runnable interface and therefore has the ability to multithreaded, its subclasses representing a task that Timer can schedule.

Here is a simple example of writing task code

/**
 * 
 * @author dgm
 * @describe "Test Print Timer
 * @date 2017 April 10, 2001
 */
public class PrintTimerTask extends TimerTask {

	private String name;
	
	public PrintTimerTask(String name) {
		super();
		this.name = name;
	}

	@Override
	public void run() {
       if (System.currentTimeMillis( ) - scheduledExecutionTime( ) > 5000) {
            return;
        }

        System.out.println("Threads:"+ name +"***** In execution."); 
	}
}

Write test code

/**
 * 
 * @author dgm
 * @describe "Test Timer
 * @date 2017 April 10, 2001
 */
public class TimeTaskTest {

	public static void main(String[] args) {
		Timer timer = new Timer();
		//Start the task after 3 seconds of setup
		timer.schedule(new PrintTimerTask("name-0"), 3000);
		PrintTimerTask secondTask = new PrintTimerTask("name-1");
		// Start the task after 1 second, then execute the thread every 3 seconds
		timer.schedule(secondTask, 1000, 3000);
		Date date = new Date();
		// Specify a point in time execution thread with date as parameter
		timer.schedule(new PrintTimerTask("name-3"), new Date(
				date.getTime() + 5000));
	}
}

The test results are shown in Fig.

Note this method:

Although jdk is natively capable of performing the required cleanup functions on a regular basis, after reviewing the data it finds that there are better ways to do this, and then look down.

2. ScheduledExecutorService (an interface)

ScheduledExecutorService is a timed task class designed based on a thread pool, where each dispatched task is assigned to a thread in the thread pool to execute, that is, tasks execute concurrently without interacting with each other.

A small example is as follows

Write thread tasks to execute

public class PrintScheduledExecutor implements Runnable {

	private String jobName;

	public PrintScheduledExecutor(String jobName) {
		this.jobName = jobName;
	}

	@Override
	public void run() {

		System.out.println(jobName + " Running!!!");
	}
}

Test Timer Task Execution

 	public static void main(String[] args) {
       
       ScheduledExecutorService service = Executors.newScheduledThreadPool(10);

		long initialDelay = 1;
		long period = 1;
		service.scheduleAtFixedRate(new PrintScheduledExecutor("job1"),
				initialDelay, period, TimeUnit.SECONDS);

		service.scheduleWithFixedDelay(new PrintScheduledExecutor("job2"),
				initialDelay, period, TimeUnit.SECONDS);
     }

Note scheduleAtFixedRate and scheduleWithFixedDelay:

:

This scheduledexecutorservice seems good, and I was wondering if there was a better scheduling framework, when I found Quartz (which is also my real-world timer scheduling library)

3. Quartz is coming on and is incredibly powerful

In a nutshell, Quarzt is an open source project that performs tasks on a regular basis within a project, and Quartz is another open source project for OpenSymphony Open Source Organizations in the Job Schduling field, which can be used in conjunction with or separately from J2EE and J2SE applications.Its structure is illustrated as follows:

job Task Class: A class that represents what tasks (such as custom types of tasks such as cleaning up resources for trial account requests) require regular code execution.

JobDetail: Configuring the details of a task class, i.e. the method of injecting a task class and specifying a task class, is an executable job that may itself be stateful.

Trigger: A trigger, which represents the configuration of a dispatch parameter, configures the time of the call, and indicates when the job task is triggered.

scheduler: A schedule dispatcher container that can hold many JobDetails and triggers. When the container is started, each JobDetail inside will be automatically executed on schedule according to the trigger.

The following is a case study of how to use it (since I'm not using it alone, it's integrated with spring)

Create a custom job class (pseudocode)

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;


/**
 * Destroy the docker cluster for trial account teachers
 * Created by dongguangming on 2017/4/14.
 */
public class DeTryTeacherAppJob implements Job 
{
    public static Logger logger = Logger.getLogger(DeTryTeacherAppJob.class);
    
    @Override
    public void execute(JobExecutionContext jobCtx) throws JobExecutionException 
    {
    logger.info("[" + currentTime + "]Decide Invalidity Trial Account Task Start");
        Map datamap = jobCtx.getJobDetail().getJobDataMap();
        ApplicationContext ctx = (ApplicationContext) datamap.get("applicationContext");
        UserService userService = (UserService) ctx.getBean("userService");
        AppService appService = (AppService) ctx.getBean("appService");
       // Perform business operations
        ...............
    }
}

Then spring configures the bean s of the task class and configures the triggers (time)

     <!--Destroying trial accounts docker colony job -->
    <bean  name="deTryTeacherAppJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"
    	p:jobClass="com.cstor.docker.job.DeTryTeacherAppJob"
    	p:applicationContextJobDataKey="applicationContext">
    </bean>
<!-- Reference resources http://www.cnblogs.com/ypf1989/p/5552426.html http://www.cnblogs.com/30go/p/5761917.html -->
    <bean id="deTryTeacherAppJob" class="org.springframework.scheduling.quartz.CronTriggerBean"
          p:jobDetail-ref="deTryTeacherAppJobDetail"
          p:cronExpression="0 0/3 * * * ?"
        />

Finally configure the dispatch factory and inject the configured triggers

 <bean id="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="triggers">
                <list>
                    <ref bean="deTryTeacherAppJob">
                </list>
            </property>
    </bean>

The test is now ready to start. You can adjust the trigger time (e.g. per minute) during the test. Here is a sample con expression

"0 0 12 * *?" Triggers every day at 12 noon
"0 1510?* *" Triggers every day at 10:15 a.m.
"0 1510 * *?" Triggers every day at 10:15 a.m.
"0 1510 * *?*" Triggers every day at 10:15 a.m.
"0 1510 * *? 2005" Triggered every morning at 10:15 a.m. in 2005
"0 * 14 * *?" Triggers every minute between 2 p.m. and 2:59 p.m. each day
"0/5 14 * *?" Triggers every 5 minutes between 2 p.m. and 2:55 p.m. each day
"0/5 14,18 * *?" Triggers every 5 minutes between 2 p.m. and 2:55 p.m. each day and between 6 p.m. and 6:55 p.m.
"0-5 14 * *?" Triggers every minute between 2 p.m. and 2:05 p.m. each day
"0 10,44 14? 3 WED" is triggered every March at 2:10 p.m. and 2:44 p.m.
"0 1510?* MON-FRI" Triggers from Monday to Friday at 10:15 a.m.
"0 15 10 15 *?" Triggered at 10:15 a.m. on the 15th of each month
"0 15 10 L *?" Triggered at 10:15 on the last day of each month
"0 1510?* 6L" Triggers at 10:15 a.m. on the last Friday of the month 
"0 1510?* 6L 2002-2005" Triggered at 10:15 a.m. on the last Friday of each month, 2002-2005
"0 1510?* 6#3" Triggers on the third Friday of the month at 10:15 a.m.

 

Summary:

1. Timer creates only one thread when performing a timed task.

2. Timer threads do not catch exceptions, and unchecked exceptions thrown by TimerTask terminate the timer thread, causing the remaining tasks to fail to execute (which is very bad).

3. ScheduledExecutorService inherits from ExecutorService. Inside ScheduledThreadPool is a thread pool that supports multiple tasks to execute concurrently.

4. Quartz is flexible and integrates well with spring.

d...........

 

Timer&TimerTask_ScheduledExecutor Service (Complex System)Quartz


Reference resources:

0.  Java Timer vs ExecutorService? 

1  https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html

2. Several Java implementations and comparisons of task scheduling: https://www.ibm.com/developerworks/cn/java/j-lo-taskschedule/

3. cron expression generation tool: http://cron.qqe2.com/

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

Topics: Programming Java Docker Spring Big Data