集群式Quartz定时任务框架实践

在日常开发汇总,经常会遇到需要定时任务的场景,简单的,可以使用Spring的定时任务调度框架,也可以使用Quartz。无论使用哪种,都需要解决一个问题,那就是集群问题。一般情况下,定时任务能且仅能运行于一台应用实例上。

前提

本文工程基于spring boot 2.1.7.RELEASE

工程配置

 一、pom依赖

如下图所示:

二、yml配置

yml配置如下图所示:

三、quartz.properties

quartz相关属性配置如图:

注意:

1、重中之重,要设置org.quartz.jobStore.isClustered=true,开启集群模式

2、其它配置见释义

四、调度器配置

使用SchedulerFactoryBeanCustomizer个性化调度器

@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"));
        };
    }

}

五、系统启动

系统启动,如显示quartz以cluster模式启动,则证明配置成功。如图所示:

编写任务

一、Job

代码如下:

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;
    }
}

二、Controller触发

代码如下:

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;
    }

}

三、系统启动

依次启动8080、8082两个实例。idea默认只能启动一个实例,需要配置并行运行才可以运行两个相同的实例,如下图所示,勾选Allow parallel run即可。

访问:http://localhost:8080/quartz/job/user,页面返回当前时间。

此时,8080和8082控制台信息分别如图所示:

8080:

8082:

可以看出,Quartz运行在8080实例上,而8082实例处于监控状态。

四、切换运行实例

停止8080实例,手工模拟服务器故障,观察8082实例控制台输出,发现quartz已经运行在8082实例上,如图所示:

8080停止:

8082接管:

问题

1、启动报错:Couldn‘t store job: JobDataMap values must be Strings when the ‘useProperties‘ property is set.

修改quartz.properties配置中org.quartz.jobStore.useProperties=false

2、UserJob中@Value注解标注的port属性如何会自动注入、name、age属性如何会自动注入?

参考QuartzAutoConfiguration、SpringBeanJobFactory类的如下片段:

3、数据结构

Quartz官网下载分发包,下载地址。下载完成后,在压缩包路径docs\dbTables下,有各个数据库相对应的脚本文件,选择自己对应的脚本执行即可。如本文选择的为tables_mysql_innodb.sql。

其它

一、源码

本文源码地址如下:

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

二、集成框架

基于quartz的集群式、非集群式轻量封装定时任务调度框架-quartz、quartz-boot已共享,配置、操作更便捷、高效,欢迎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

本文由【银河架构师】原创,转载请注明作者及出处。另附本文地址:

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

微信搜索【银河架构师】,发现更多精彩内容。

 

 

原文地址:https://www.cnblogs.com/luas/p/12040304.html

时间: 2024-08-01 16:46:31

集群式Quartz定时任务框架实践的相关文章

(2)Spring集成Quartz定时任务框架介绍和Cron表达式详解

在JavaEE系统中,我们会经常用到定时任务,比如每天凌晨生成前天报表,每一小时生成汇总数据等等.我们可以使用java.util.Timer结合java.util.TimerTask来完成这项工作,但时调度控制非常不方便,并且我们需要大量的代码.使用Quartz框架无疑是非常好的选择,并且与Spring可以非常方便的集成,下面介绍它们集成方法和Cron表达式的详细介绍. 一.增加所依赖的JAR包1.增加Spring的Maven依赖 <dependency> <groupId>org

quartz定时任务框架调度机制解析

转自集群调度机制调研及源码分析 quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的java任务调度框架,功能强大配置灵活.在企业应用中占重要地位.quratz在集群环境中的使用方式是每个企业级系统都要考虑的问题.早在2006年,在ITeye上就有一篇关于quratz集群方案的讨论:http://www.iteye.com/topic/40970 IT

c# quartz定时任务框架的使用

一.新建windows服务项目,并从nuget引用下图标记的类库: 二.鼠标右键单击Service1.cs,点击查看代码,把类文件修改成如下: Service1.cs public partial class Service1 : ServiceBase { private IScheduler scheduler; public Service1() { InitializeComponent(); #region Quartz try { //调度器 ISchedulerFactory sc

quartz定时任务框架之实例

import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; import java.util.Date; public class MyJob implements Job { public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println(new Date() + ":

atititt.java定时任务框架选型Spring Quartz 注解总结

atititt.java定时任务框架选型Spring Quartz 总结 1. .Spring Quartz  (ati recomm) 1 2. Spring Quartz具体配置 2 2.1. 增加context,task命名空间xml: 2 2.2. 增加xsi:schemaLocation valide 2 2.3. 我们的task任务扫描注解in spr.xml 2 2.4. 设置运行方法 3 2.5. 设置输出日志 3 3. 运行测试sprX走ok兰. 4 4. Quartz Sch

QUARTZ.NET 一个定时任务框架

<1> Quartz.NET-1.0.3文件下载地址 (这是老版本了,现在已经有新版本了.用法好像不一样了) 首先要添加Quartz.NET-1.0.3 文件下面的  bin/3.5/Release/Quartz/ 目录下面的Common.Logging.dll文件和Quartz.dll文件 然后添加引用.将连个文件引入到项目中来 using Quartz; using Quartz.Impl; using System; using System.Collections.Generic; u

Quartz.Net的使用(简单配置方法)定时任务框架

Quartz.dll 安装nuget在线获取dll包管理器,从中获取最新版 Quartz.Net是一个定时任务框架,可以实现异常灵活的定时任务,开发人员只要编写少量的代码就可以实现“每隔1小时执行”.“每天22点执行”.“每月18日的下午执行8次”等各种定时任务. Quartz.Net中的概念:计划者(IScheduler).工作(IJob).触发器(Trigger).给计划者一个工作,让他在Trigger(什么条件下做这件事)触发的条件下执行这个工作 将要定时执行的任务的代码写到实现IJob接

spring框架整合使用定时任务框架java quartz的示例代码配置

原创整理不易,转载请注明出处:spring框架整合使用定时任务框架java quartz的示例代码配置 代码下载地址:http://www.zuidaima.com/share/1775583461723136.htm 有时候我们的任务(Job)需要再某些任务完成之后才能进行:例如从旧的数据库批量导数据的时候:需要现将被其他数据依赖的数据导入新的数据库:然后再进行关系的导入..在这种情况下我们就可以使用Quartz的listener来做文章了. 首先我们写一个主任务的类,命名为MainJob:她

[转]Python定时任务框架APScheduler

APScheduler是基于Quartz的 一个Python定时任务框架,实现了Quartz的所有功能,使用起来十分方便.提供了基于日期.固定时间间隔以及crontab类型的任务,并且可以 持久化任务.基于这些功能,我们可以很方便的实现一个python定时任务系统,写python还是要比java舒服多了. 1. 安装 安装过程很简单,可以基于easy_install和源码. easy_install apscheduler 或者下载源码,运行命令: python setup.py install