Quartz集群原理以及配置应用的方法详解

Quartz集群原理以及配置应用的方法详解

概述

Quartz是一个轻量级的、开源的、基于Java的调度框架,提供了很多调度的功能,比如创建多个定时任务、按照特定的规则执行任务、支持持久化、集群等。其中,Quartz集群支持多个应用实例共同组成一个调度集群,提高任务的可用性和可靠性。

Quartz集群原理

Quartz集群通过基于JDBC的持久化机制实现了数据共享,将JobDetail和Trigger存储在数据库中。多个应用实例通过定时查询数据库的方式获取需要执行的任务,确保每个任务只会在其中的一台机器上执行,从而实现任务的负载均衡和高可用。

配置应用的方法

步骤1:引入Quartz依赖

在pom.xml文件中加入以下依赖:

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.2</version>
</dependency>

步骤2:配置数据库

在程序入口处添加数据库配置:

private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
private static final String JDBC_URL = "jdbc:mysql://localhost:3306/quartz?characterEncoding=UTF-8";
private static final String JDBC_USERNAME = "root";
private static final String JDBC_PASSWORD = "";

private static void initDatabase() {
    try {
        Class.forName(JDBC_DRIVER);
    } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
    }
    StdSchedulerFactory factory = new StdSchedulerFactory();
    factory.initialize(getProperties());
}

private static Properties getProperties() {
    Properties props = new Properties();
    props.put("org.quartz.scheduler.instanceName", "quartzScheduler");
    props.put("org.quartz.scheduler.instanceId", "AUTO");
    props.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
    props.put("org.quartz.threadPool.threadCount", "10");

    props.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
    props.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate");
    props.put("org.quartz.jobStore.dataSource", "myDS");
    props.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
    props.put("org.quartz.jobStore.isClustered", "true");
    props.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
    props.put("org.quartz.jobStore.useProperties", "true");

    props.put("org.quartz.dataSource.myDS.driver", JDBC_DRIVER);
    props.put("org.quartz.dataSource.myDS.URL", JDBC_URL);
    props.put("org.quartz.dataSource.myDS.user", JDBC_USERNAME);
    props.put("org.quartz.dataSource.myDS.password", JDBC_PASSWORD);
    props.put("org.quartz.dataSource.myDS.maxConnections", "10");
    return props;
}

其中,quartzSchedulermyDS是自定义名称,可以根据自己的需要命名。

步骤3:编写Job类和Trigger类

通过实现Job接口来定义具体的任务:

public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("Hello Quartz!");
    }
}

通过实现Trigger接口来定义任务的触发器:

public class MyTrigger {
    public static CronTrigger getCronTrigger(String cronExpression) {
        CronTriggerImpl trigger = new CronTriggerImpl();
        trigger.setCronExpression(cronExpression);
        trigger.setName("myTrigger");
        trigger.setGroup("myGroup");
        trigger.setJobKey(JobKey.jobKey("myJob", "myGroup"));
        return trigger;
    }
}

步骤4:启动多个应用实例

在多个应用实例中启动Quartz调度器:

public class QuartzServer {
    public static void main(String[] args) throws Exception {
        initDatabase();
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        scheduler.clear();
        JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                .withIdentity("myJob", "myGroup")
                .build();
        CronTrigger trigger = MyTrigger.getCronTrigger("0/5 * * * * ? *");
        scheduler.scheduleJob(jobDetail, trigger);
        scheduler.start();
    }
}

注意,scheduler.clear()方法用于清除集群中已有的任务。

示例说明1:配置多个应用实例

假设现在有两台服务器A和B,需要配置成Quartz集群,其中A和B的配置文件中的数据库配置都相同,那么这两台服务器在Quartz集群中需要做如下配置:

  • 将A和B中JobDetail和Trigger存储在数据库中。
  • 设置两个应用实例的调度器名称quartzScheduler和实例IDAUTO相同。
  • 将A和B的线程池大小设置为相同的值。
  • 设置数据库的org.quartz.jobStore.isClustered属性为true
  • 启动A和B的应用实例。

示例说明2:使用Quartz集群

现在需要定时发送邮件,并且需要保证即使一台服务器出现故障,任务也能够继续执行。在这种情况下,可以使用Quartz集群来实现高可用性,保证任务的持续执行。在实现的过程中,需要参照上述步骤进行配置,并设置JobDetail和Trigger,同时需要让定时任务支持集群,具体实现方法如下:

public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        String jobId = context.getJobDetail().getKey().getName();
        String groupName = context.getJobDetail().getKey().getGroup();
        System.out.println("Hello Quartz! JobId=" + jobId + " groupName=" + groupName);
    }
}

public class MyTrigger {
    public static CronTrigger getCronTrigger(String cronExpression) {
        CronTriggerImpl trigger = new CronTriggerImpl();
        trigger.setCronExpression(cronExpression);
        trigger.setName("myTrigger");
        trigger.setGroup("myGroup");
        trigger.setJobKey(JobKey.jobKey("myJob", "myGroup"));
        trigger.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW);
        trigger.setPriority(5);
        trigger.setJobData(createJobDataMap());
        return trigger;
    }

    private static JobDataMap createJobDataMap() {
        JobDataMap jobDataMap = new JobDataMap();
        jobDataMap.put("isClustered", true);
        return jobDataMap;
    }
}

在Trigger中,setMisfireInstruction方法用于设置Job的策略,setJobData方法用于设置Job数据映射表,在Job中可以通过context.getJobDetail().getJobDataMap().get("isClustered")获取Job信息。

结语

Quartz集群原理和配置应用方法相信通过上述内容已经有了一定的了解。在应用Quartz集群前,需要充分考虑任务的类型以及具体的业务场景,并根据实际情况进行灵活配置。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Quartz集群原理以及配置应用的方法详解 - Python技术站

(0)
上一篇 2023年5月21日
下一篇 2023年5月21日

相关文章

  • CentOS8下MySQL 8.0安装部署的方法

    以下是CentOS 8下MySQL 8.0安装部署的方法: 准备工作 在安装MySQL之前,需要先安装依赖包和更新系统 sudo yum install -y wget net-tools vim sudo yum update -y 下载MySQL安装包 MySQL官方提供了RPM包安装方式,可以先去官网下载对应版本的rpm包:https://dev.my…

    database 2023年5月22日
    00
  • 如何使用Python实现数据库中数据的多表查询?

    以下是使用Python实现数据库中数据的多表查询的完整攻略。 数据库中数据的多表查询简介 在数据库中,多表查询是指从多个表中检索数据的查询。在Python中,可以使用pymysql库连接到MySQL数据库,并使用JOIN子句实现多表查询。 步骤1:连接到数据库 在Python中,可以使用pymysql库连接MySQL数据库。以下是连接到MySQL数据库的基本…

    python 2023年5月12日
    00
  • Redis在java开发中使用

    1.什么是redis?   redis是当今基本所有互联网产品都在使用的一种提供键值对形式的内存数据库。之所以说是内存数据库,是因为redis基于内存的读取和写入相比传统的数据库基于磁盘IO快上数倍。于是乎redis在现在的应用中使用的非常广泛。主要的作用在于:  1.1、提供缓存服务,存储访问频率高的热数据防止穿透到数据库  1.2、在分布式系统中可以作为…

    Redis 2023年4月13日
    00
  • SQL Server 2005附加数据库时Read-Only错误的解决方案

    以下是详细的攻略。 问题描述 在将 SQL Server 2005 数据库附加到实例时,可能会遇到以下错误: Msg 262, Level 14, State 1, Line 1 CREATE DATABASE permission denied in database ‘master’. Msg 1813, Level 16, State 2, Line …

    database 2023年5月21日
    00
  • Oracle 11g数据库使用expdp每周进行数据备份并上传到备份服务器

    下面我将为你介绍如何使用expdp进行每周数据备份并上传至备份服务器的完整攻略。 准备工作 先创建一个备份文件夹 确保数据库处于归档模式状态 确保你有足够的可用磁盘空间 数据库备份 进入sqlplus命令行,并使用管理员身份登录到Oracle 11g数据库中。 sql sqlplus / as sysdba 设置ORACLE_SID环境变量,以及指定备份文件…

    database 2023年5月22日
    00
  • linux环境中常用的mysql命令介绍

    下面是“linux环境中常用的mysql命令介绍”的完整攻略: 1. 登录Mysql 在Linux中,可以通过以下命令登录到Mysql: mysql -h hostname -P port -u username -p hostname:Mysql服务器的主机名或IP地址; port:Mysql服务器的端口号,默认为3306; username:登录Mysq…

    database 2023年5月22日
    00
  • mysql 事务未提交导致死锁 Lock wait timeout exceeded; try restarting transaction 解决办法

    锁表问题提示:Lock wait timeout exceeded; try restarting transaction 解决锁表方法 查询数据库阻塞的进程SELECT * FROM information_schema.innodb_trx主要看箭头指向的这几个字段,如果有阻塞数据(不为0的就是阻塞的),找到后在根据下图这个字段:try_mysql_th…

    MySQL 2023年4月12日
    00
  • Oracle中命名块之存储过程的详解及使用方法

    Oracle中命名块之存储过程的详解及使用方法 什么是存储过程? 存储过程是一种事先编译好的数据库对象,它是一组SQL语句集(或PL/SQL),可以封装操作,具有以下优点: 降低了网络流量,减少了客户端的工作量。 可以增加公共代码段,简化了维护和管理。 可以重复利用,提高了执行效率。 可以保护数据的完整性和安全性。 存储过程的创建 语法格式如下: CREAT…

    database 2023年5月21日
    00
合作推广
合作推广
分享本页
返回顶部