There are several ways to implement a scheduled task:

1. Use the Crontab of Linux

Advantages: 1. Easy to use, just write 2 in crontab. You can modify it at any time without restarting the server. Disadvantages: 1. It is not easy to use in a distributed system, so you can only modify it on one machine. The minute is the smallest unit of time and cannot be used in secondsCopy the code

2. Use ScheduledExecutor delivered with Spring

Advantages: cronExpression is more powerful than crontab. Supports up to second, and has better performance. Disadvantages: After cronExpression is modified, restart the serverCopy the code

3. Use the built-in Timer of the JDK

Advantages: Lightweight, fast execution Disadvantages: Difficult to use in distributed system. It cannot be executed at a specified time, but only at a certain frequencyCopy the code

4. The use of quartz

Advantages: 1. Applicable to distributed systems, Quartz supports cluster mode 2. Fixed the timer task without rebooting the server (this is just some advantages and disadvantages of my personal thought, netizens have other views can leave a message to say)Copy the code

Integration steps:

Now that we know how good Quartz is, how do we integrate it into the project? I will next implement a small feature that triggers dynamic scheduled tasks through HTTP interface calls. JDK :1.8.0_162; Springboot: 1.5.10. The RELEASE 1. Introduction to the jar package, to join in the pom file quartz jar package and spring supports quartz jar

< the dependency > < groupId > org. Quartz - the scheduler < / groupId > < artifactId > quartz < / artifactId > < version > 2.3.1 < / version > </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency>Copy the code

2. The configuration of the scheduler bean, spring here implements three factory class, SchedulerFactoryBean, CronTriggerBean, JobDetailBean, use annotations to the three classes to spring management. Generally, the materials on the Internet are these three classes, which are all managed by Spring. You can refer to this article. In my case, the scheduled task is triggered by the interface, so just use the scheduler that implements the following SchedulerFactoryBean. If you’re not sure what these classes are for, check out this article used by Quartz. Scheduler is the scheduler of a task, job is the specific task class, and trigger is the trigger that determines when a task is executed. The scheduler is the subject’s scheduler, trigger is the time, and job is what to do.

@Configuration
public class SchedulerConfig {

    /** * attention: * Details */
    @Bean(name = "scheduler")
    public SchedulerFactoryBean schedulerFactory(a) {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        // For Quartz cluster,QuartzScheduler starts to update existing jobs
        bean.setOverwriteExistingJobs(true);
        // Delayed startup, 1 second after the application starts
        bean.setStartupDelay(1);
        returnbean; }}Copy the code

3. Specific tasks class job, must implement the quartz job class, this can also go to realize spring QuartJobBean (spring on the realization of the job class) is the same, or is there a way is MethodInvokingJobDetailFactoryBean, There is more flexibility in setting which methods of which classes can perform this task:

@Slf4j
public class ScheduleTaskJob implements Job {

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        log.info("Mission executed......"); }}Copy the code

4. HTTP interface to trigger the scheduler:

@Slf4j
@RestController
public class Controller {

    @Resource(name = "scheduler")
    private Scheduler scheduler;

    @PostMapping(value = "/api/executeTask")
    public String executeTask(TaskVO taskVO) {
        / / the job class
        JobDetail jobDetail = JobBuilder.newJob(ScheduleTaskJob.class)
               .withIdentity(taskVO.getJobName(), taskVO.getJobGroupName())
                .build();
        // Trigger class
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(taskVO.getTriggerName(), taskVO.getTriggerGroupName())
                .startNow()
                .withSchedule(cronSchedule(taskVO.getCronExpression()))
                .build();
        try {
            // Execute the task
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            log.error("Task execution exception", e);
        }
        return "success"; }}Copy the code

GroupName (job, triger, groupName, groupName, triger, groupName, groupName); Execute the program to see the effect: jobName:job1 jobGroupName:jobGroup1 triggerName:trigger1 triggerGroupName:triggerGroup1 cronExpression:0/1 * * * * ?

jobName:job2 jobGroupName:jobGroup1 triggerName:trigger2 triggerGroupName:triggerGroup1 cronExpression:0/1 * * * * ?

The upper part of the red box in the figure has only one scheduled task, which is executed once every second, while the lower part has a new task added, so the answer leads to the execution results of the two tasks.

Pits encountered:

1.java.lang.NoSuchMethodError: org.springframework.boot.SpringApplication.run(Ljava/lang/Object; [Ljava/lang/String;) Lorg/springframework/context/ConfigurableApplicationContext; solution: This is due to an incompatibility issue with SpringBoot2, so using SpringBoot1.5 will not cause this error.

2.Caused by: java.lang.ClassNotFoundException: org.springframework.transaction.PlatformTransactionManager at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~ [na: 1.8.0 comes with _162] at Java lang. This. The loadClass (424). This Java: ~ [na: 1.8.0 comes with _162] the at Sun. Misc. The Launcher $AppClassLoader. LoadClass (338). The Launcher Java: ~ [na: 1.8.0 comes with _162] the at Java. Lang. This. LoadClass (357). This Java: ~ [na: 1.8.0 comes with _162] 39 common frames if omitted start-up time to quote the wrong, To introduce a package of Spring-Tx things

 <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
 </dependency>
Copy the code

Source code address:Github source address, friends think writing is still good help star, follower, 23333, thanks ~

References:

[1] blog.csdn.net/liuchuanhon… [2] www.w3cschool.cn/quartz_doc/… [3] www.ibm.com/developerwo… [4]www.quartz-scheduler.org/