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 索引,是后续章节索引选择优化的重点对象。