Clustered Quartz Timing Task Framework Practice

Keywords: Java github Spring Attribute

In the daily development summary, you often encounter scenarios that require timed tasks. Simple, you can use Spring's timed task scheduling framework or Quartz.Either way, there is a problem that needs to be solved, that is, the cluster problem.Typically, a timed task can and can only run on one application instance.

premise

This project is based on spring boot 2.1.7.RELEASE

 

Project Configuration

1. pom Dependency

 

As shown in the following figure:

 

2. yml Configuration

 

The yml configuration is as follows:

 

3. quartz.properties

 

The quartz-related attribute configuration is shown in the following figure:

 

Be careful:

1. Most importantly, set org.quartz.jobStore.isClustered=true to turn on cluster mode

2. Notes on other configurations

 

4. Scheduler Configuration

 

Use Scheduler FactoryBeanCustomizer Personalized Scheduler

@Configuration
public class SysConfig {

    private final DataSource dataSource;

    public SysConfig(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Bean
    public SchedulerFactoryBeanCustomizer schedulerFactoryBeanCustomizer() {
        return (schedulerFactoryBean) -> {
            schedulerFactoryBean.setDataSource(dataSource);
            schedulerFactoryBean.setConfigLocation(new ClassPathResource("quartz.properties"));
        };
    }

}

 

V. System Startup

 

System startup, if quartz is shown to start in cluster mode, proves successful.As shown in the diagram:

 

Writing tasks

 

I. Job

 

The code is as follows:

package com.luas.quartz.cluster.demo.quartz.job;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.quartz.QuartzJobBean;

public class UserJob extends QuartzJobBean {

    @Value("${server.port}")
    private String port;

    private String name;

    private Integer age;

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        System.out.println(String.format("the user job is execute on port %s. it's name is %s, age is %s", port, name, age));
    }

    public String getPort() {
        return port;
    }

    public void setPort(String port) {
        this.port = port;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

 

2. Controller Trigger

The code is as follows:

package com.luas.quartz.cluster.demo.controller;

import com.luas.quartz.cluster.demo.quartz.job.UserJob;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;

@RestController
@RequestMapping("/job")
public class JobController {

    @Autowired
    private Scheduler scheduler;

    @RequestMapping("/user")
    public Object user() throws Exception {
        JobBuilder jobBuilder = JobBuilder
                .newJob(UserJob.class)
                .withIdentity(new JobKey("UserJob", "default"))
                .withDescription("a demo quartz job")
                .storeDurably();

        JobDataMap jobDataMap = new JobDataMap();
        jobDataMap.put("name", "luas");
        jobDataMap.put("age", 18);

        TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger()
                .withIdentity(new TriggerKey("UserJob's trigger 1", "default"))
                .withSchedule(createSimpleScheduleBuilder())
                .forJob(new JobKey("UserJob", "default"))
                .usingJobData(jobDataMap)
                .startNow();

        this.scheduler.scheduleJob(jobBuilder.build(), triggerBuilder.build());

        return LocalDateTime.now();
    }

    private ScheduleBuilder createSimpleScheduleBuilder() {
        SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInMilliseconds(10000)
                .withRepeatCount(100);

        return simpleScheduleBuilder;
    }

}

 

3. System Startup

 

Start 8080, 8082 instances in turn.idea can only start one instance by default and needs to be configured to run in parallel to run two identical instances, as shown in the following figure, check Allow parallel run.

 

Visit: http://localhost:8080/quartz/job/user, page returns current time.

At this point, console information for 8080 and 8082 is shown as follows:

8080:

 

8082:

 

You can see that Quartz runs on 8080 instances and 8082 instances are under monitoring.

 

4. Switching Running Instances

 

Stop 8080 instances, manually simulate server failures, observe the console output of 8082 instances, and find that quartz is running on 8082 instances, as shown in the diagram:

8080 stop:

 

8082 take-over:

 

 

problem

 

1. Startup error: Couldn't store job: JobDataMap values must be Strings when the'useProperties'property is set.

Modify org.quartz.jobStore.useProperties=false in quartz.properties configuration

 

2. How will the port attribute labeled with the @Value annotation in UserJob be automatically injected, and how will the name and age attributes be automatically injected?

Refer to the following sections of the QuartzAutoConfiguration, SpringBeanJobFactory class:

 

3. Data structure

Download distribution packages on Quartz's website. Download Address .After downloading, under the compressed package path docs\dbTables, there are script files corresponding to each database, and you can select your own script to execute.For example, tables_mysql_innodb.sql was chosen for this article.

 

Other

1. Source Code

The source addresses for this article are as follows:

  • github: https://github.com/liuminglei/learning-demo/tree/master/quartz-cluster-demo

  • gitee: https://gitee.com/xbd521/learning-demo/tree/master/quartz-cluster-demo

2. Integration Framework

Quatz-based clustered, non-clustered lightweight encapsulated timed task scheduling framework-quartz, quartz-boot has been shared, configuration, operation is more convenient and efficient, welcome star, fork.

 quartz-boot:

  • github: https://github.com/liuminglei/quartz-boot

  • gitee: https://gitee.com/xbd521/quartz-boot

 quartz

  • github: https://github.com/liuminglei/quartz

  • gitee: https://gitee.com/xbd521/quartz

 

This article was originally created by Milky Way Architect. Please indicate the author and source for reprinting.The address of this article is also attached:

https://www.cnblogs.com/luas/p/12040304.html

WeChat Search [Galaxy Architect] found more exciting content.

 

Posted by alcapone on Sun, 15 Dec 2019 03:07:14 -0800