1. Quartz调度平台概述

Quartz 是一个功能丰富的开源作业调度框架,几乎可以集成到任何 Java 应用程序中——从独立的小型应用到大型的分布式企业系统。本章作为课程的开篇,将系统梳理 Quartz 的核心概念、调度器、触发器、任务以及作业存储类型,为后续的索引选择与连接池水位巡检实践打下坚实的理论基础。

1.1 Quartz核心概念

Quartz 的架构围绕几个核心抽象构建,理解这些概念是掌握调度平台运维与优化的前提。下表列出了最关键的几个概念及其职责:

概念 接口/类 职责描述
调度器 Scheduler Quartz 的核心引擎,负责管理任务和触发器的注册、启动、暂停与关闭。
任务 Job 需要被调度执行的业务逻辑单元,开发者实现 execute(JobExecutionContext context) 方法。
任务详情 JobDetail 任务的静态描述,包含任务名称、分组、以及任务数据映射(JobDataMap)。
触发器 Trigger 定义任务何时被执行的规则,包括简单触发器和 Cron 触发器两种主要类型。
监听器 JobListener / TriggerListener 用于监听任务执行和触发器触发事件,便于日志记录和监控告警。
巡检视角: 在数据库巡检中,QRTZ_JOB_DETAILS、QRTZ_TRIGGERS、QRTZ_FIRED_TRIGGERS 是三个最核心的监控表,它们的索引设计与连接池水位直接关联。

1.2 调度器(Scheduler)

调度器是 Quartz 的生命线。在分布式场景下,通常使用 StdSchedulerFactory 创建调度器实例,并通过配置指定线程池大小、作业存储类型等参数。调度器的生命周期包括:

  • 初始化: 读取配置文件,创建线程池,初始化作业存储。
  • 启动: 调用 scheduler.start(),开始扫描待触发的触发器。
  • 待机: 调用 scheduler.standby(),暂停触发但不释放资源。
  • 关闭: 调用 scheduler.shutdown(),等待正在执行的任务完成后释放所有资源。
性能要点: 调度器的 threadPool 配置直接影响并发任务吞吐量。默认线程数为 10,在高并发调度场景下,建议根据任务平均执行时长和触发频率动态调整,避免线程饥饿或资源浪费。

1.3 触发器(Trigger)

触发器决定了任务执行的时刻与频率。Quartz 提供了两种最常用的触发器实现:

触发器类型 适用场景 关键属性
SimpleTrigger 固定间隔重复执行,如每 5 分钟执行一次数据同步。 repeatInterval、repeatCount
CronTrigger 基于日历表达式调度,如每天凌晨 2:00 执行报表生成。 cronExpression、timeZone

Cron 表达式是日常巡检中排查“任务未按时触发”问题的重点。一个典型的 Cron 表达式由 6 或 7 个字段组成:

秒 分 时 日 月 周 [年]
0 0 2 * * ?   // 每天凌晨 2:00 执行
0 0/5 * * * ? // 每 5 分钟执行一次
常见陷阱: 当触发器状态为 PAUSED 或 BLOCKED 时,即使 Cron 时间已到,任务也不会执行。巡检时需重点关注 QRTZ_TRIGGERS 表中的 TRIGGER_STATE 字段。

1.4 任务(Job)

任务接口只有一个方法 execute(JobExecutionContext context)。Quartz 每次执行任务时都会创建新的 Job 实例,因此 Job 实现类必须包含无参构造器。任务的状态数据通过 JobDataMap 传递,该数据会被持久化到数据库的 QRTZ_JOB_DETAILS 表中。

一个标准的 Job 实现示例:

public class DataSyncJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        JobDataMap dataMap = context.getJobDetail().getJobDataMap();
        String sourceDb = dataMap.getString("source_db");
        String targetDb = dataMap.getString("target_db");
        // 业务逻辑:从 sourceDb 同步数据到 targetDb
        System.out.println("数据同步任务执行中...");
    }
}

1.5 作业存储类型

作业存储决定了 Quartz 如何保存调度器、任务和触发器的状态。这是数据库索引设计与连接池配置的直接关联点。Quartz 支持两种存储类型:

存储类型 类名 特点 适用场景
RAMJobStore org.quartz.simpl.RAMJobStore 数据保存在内存中,速度快,但应用重启后调度信息丢失。 开发测试环境、无状态调度、允许丢失的任务。
JDBCJobStore org.quartz.impl.jdbcjobstore.JobStoreTX / JobStoreCMT 数据持久化到关系型数据库,支持集群、故障恢复、持久化调度。 生产环境、分布式集群、需要高可用保障的任务。

在生产环境中,绝大多数企业选择 JDBCJobStore。此时,Quartz 会在数据库中创建 11 张以 QRTZ_ 为前缀的系统表。这些表的索引设计、表空间规划以及连接池配置,直接决定了调度平台的稳定性与性能。

巡检前置知识: 使用 JDBCJobStore 时,QRTZ_TRIGGERS 表的 SCHED_NAME、TRIGGER_NAME、TRIGGER_GROUP 联合索引,以及 QRTZ_FIRED_TRIGGERS 表的 SCHED_NAME、INSTANCE_NAME、FIRED_TIME 索引,是后续章节索引选择优化的重点对象。
Quartz 核心架构与数据流 Quartz 核心架构与数据流 Scheduler(调度器) ThreadPool(线程池) JobStore(作业存储) Job(任务) Trigger(触发器) QRTZ_* 系统表 说明: 调度器通过线程池执行任务,同时依赖 JobStore 持久化调度状态。 JDBCJobStore 将任务、触发器、调度器状态写入 QRTZ_* 系统表, 这些表的索引设计与连接池水位直接决定调度平台的稳定性与性能。

1.6 本章小结