Quartz 原理分析

现在公司居然用了Quartz定时任务框架,今天我们就来盘它!!!!

Quartz 是一个功能强大的开源任务调度框架,支持任务持久化、集群部署、分布式调度等特性。下面从架构、核心组件、运行流程和 JDBC 持久化机制四个方面详细分析其原理:

一、Quartz 核心架构

┌───────────────────────────────────────────────────────────┐
│                         客户端应用                          │
└───────────────────────────┬───────────────────────────────┘
                            │
                            ▼
┌───────────────────────────────────────────────────────────┐
│                       Quartz Scheduler                      │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────┐  │
│  │ JobStore (JDBC) │  │ ThreadPool      │  │ Scheduler   │  │
│  │ ┌─────────────┐ │  │ ┌─────────────┐ │  │ ┌─────────┐ │  │
│  │ │ 数据库表结构 │ │  │ │ 工作线程池  │ │  │ │ 调度引擎│ │  │
│  │ └─────────────┘ │  │ └─────────────┘ │  │ └─────────┘ │  │
│  └─────────────────┘  └─────────────────┘  └─────────────┘  │
└───────────────────────────┬───────────────────────────────┘
                            │
                            ▼
┌───────────────────────────────────────────────────────────┐
│                     JDBC 持久化存储                        │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐        │
│  │ QRTZ_JOBS   │  │ QRTZ_TRIGGERS │  │ QRTZ_CALENDARS │  │
│  ├─────────────┤  ├─────────────┤  ├─────────────┤        │
│  │ QRTZ_JOB_DETAILS │  │ QRTZ_SIMPLE_TRIGGERS │  │ ...   │  │
│  └─────────────┘  └─────────────┘  └─────────────┘        │
└───────────────────────────────────────────────────────────┘

二、核心组件功能

  1. Scheduler(调度器)

    • 核心入口,负责任务的注册、启动、暂停、删除等操作。
    • 通过 SchedulerFactory 创建,支持集群模式(ClusterManager 负责协调节点)。
  2. Job(任务)

    • 实现 org.quartz.Job 接口的类,定义具体执行逻辑(execute() 方法)。
    • 分为有状态(StatefulJob)和无状态两种,有状态任务会保存运行时数据。
  3. Trigger(触发器)

    • 定义任务执行的时间规则,支持多种类型:
      • SimpleTrigger:固定频率/次数触发。
      • CronTrigger:基于 Cron 表达式触发。
      • CalendarIntervalTrigger:基于日历间隔(如每月1号)。
    • 包含优先级、错过触发策略(Misfire Instruction)等配置。
  4. JobStore(任务存储)

    • 负责存储任务和触发器的状态信息,支持内存存储(RAMJobStore)和持久化存储(JDBCJobStore)。
    • 持久化实现依赖数据库表结构(如 QRTZ_JOB_DETAILSQRTZ_TRIGGERS)。
  5. ThreadPool(线程池)

    • 执行任务的工作线程池,默认实现为 SimpleThreadPool
    • 配置参数:threadCount(线程数)、threadPriority(线程优先级)等。

三、JDBC 持久化机制

Quartz 通过 JDBCJobStore 实现任务状态持久化,核心逻辑:

1. 数据库表结构(部分核心表)
表名作用
QRTZ_JOB_DETAILS存储 Job 定义(类名、描述、是否持久化等)
QRTZ_TRIGGERS存储触发器基本信息(关联 Job、触发类型、状态等)
QRTZ_CRON_TRIGGERS存储 Cron 触发器的表达式和时区信息
QRTZ_SIMPLE_TRIGGERS存储 Simple 触发器的重复次数、间隔等信息
QRTZ_FIRED_TRIGGERS存储正在执行或已完成的触发器状态(锁机制、执行时间等)
QRTZ_SCHEDULER_STATE存储调度器实例状态(心跳信息、集群节点状态)
QRTZ_LOCKS实现分布式锁(用于集群环境下的任务调度协调)
2. 数据持久化流程
  • 任务注册
    scheduler.scheduleJob(jobDetail, trigger) 会将 Job 和 Trigger 信息写入 QRTZ_JOB_DETAILSQRTZ_TRIGGERS 表。

  • 状态变更
    触发器状态(WAITINGACQUIREDEXECUTING 等)在任务生命周期中不断更新,写入 QRTZ_TRIGGERSQRTZ_FIRED_TRIGGERS 表。

  • 调度器状态
    集群模式下,每个调度器实例定期更新 QRTZ_SCHEDULER_STATE 表的心跳信息,用于故障检测和负载均衡。

3. 锁机制(集群环境)

Quartz 通过 QRTZ_LOCKS 表实现分布式锁,常见锁类型:

  • TRIGGER_ACCESS:保证同一触发器在集群中只被一个节点执行。
  • JOB_ACCESS:控制对 Job 数据的访问。
  • STATE_ACCESS:协调调度器状态。

四、运行流程详解

1. 初始化阶段
// 创建调度器实例(从配置文件读取参数)
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler scheduler = sf.getScheduler();

// 配置 JDBCJobStore
Properties props = new Properties();
props.setProperty("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
props.setProperty("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate");
props.setProperty("org.quartz.jobStore.dataSource", "myDS");
props.setProperty("org.quartz.dataSource.myDS.driver", "com.mysql.jdbc.Driver");
props.setProperty("org.quartz.dataSource.myDS.URL", "jdbc:mysql://localhost/quartz");
// 其他配置...
2. 任务注册与调度
// 定义 Job
JobDetail job = JobBuilder.newJob(MyJob.class)
    .withIdentity("job1", "group1")
    .build();

// 定义触发器(Cron 表达式)
Trigger trigger = TriggerBuilder.newTrigger()
    .withIdentity("trigger1", "group1")
    .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))  // 每5秒执行一次
    .build();

// 注册任务到调度器(数据写入数据库)
scheduler.scheduleJob(job, trigger);
scheduler.start();  // 启动调度器
3. 触发与执行流程
调度器线程轮询触发器状态(从 QRTZ_TRIGGERS 表)
    ↓
发现待触发的触发器(状态=WAITING 且 next_fire_time <= 当前时间)
    ↓
获取 TRIGGER_ACCESS 锁(更新 QRTZ_LOCKS 表)
    ↓
更新触发器状态为 ACQUIRED(更新 QRTZ_TRIGGERS 表)
    ↓
从线程池分配工作线程执行任务
    ↓
执行 Job.execute() 方法
    ↓
任务完成后更新触发器状态(如 RELEASED、COMPLETED)
    ↓
释放 TRIGGER_ACCESS 锁
4. 集群环境下的协调
  • 故障转移:若节点宕机,其他节点通过 QRTZ_SCHEDULER_STATE 表检测到心跳超时,接管未完成的任务。
  • 负载均衡:多个节点通过竞争锁(QRTZ_LOCKS)决定由谁执行任务,避免重复调度。

五、关键配置参数(JDBC 持久化)

# 存储方式:JDBC 事务模式
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX

# 数据库方言(根据数据库类型选择)
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate

# 数据源配置
org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost/quartz
org.quartz.dataSource.myDS.user = quartz
org.quartz.dataSource.myDS.password = quartz
org.quartz.dataSource.myDS.maxConnections = 10

# 表前缀(多应用共享数据库时使用)
org.quartz.jobStore.tablePrefix = QRTZ_

# 集群模式开关
org.quartz.jobStore.isClustered = true
org.quartz.scheduler.instanceId = AUTO  # 自动生成实例ID
org.quartz.jobStore.clusterCheckinInterval = 20000  # 集群检查间隔(毫秒)

六、优缺点分析

优点
  • 功能全面:支持各种复杂的调度需求(Cron、集群、持久化)。
  • 扩展性强:可自定义 JobStore、ThreadPool 等组件。
  • 成熟稳定:社区活跃,广泛应用于企业级系统。
缺点
  • 配置复杂:尤其是集群和持久化配置。
  • 性能开销:依赖数据库操作,频繁调度时可能成为瓶颈。
  • 学习曲线:核心概念(Job、Trigger、JobStore)较多,入门门槛较高。

Quartz 通过 JDBC 持久化实现了任务状态的可靠存储和集群环境下的高可用调度,适合对任务可靠性要求高、需要跨应用共享任务配置的场景。但需注意数据库性能优化和集群配置的复杂性。

如果用数据库持久化的化,就要注意了,我们数据库经常出现IO Error 的问题,导致定时任务在维护任务状态的时候出现问题,从而任务一直就中断了。卡在了立即执行的状态!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

提前退休了-程序员阿飞

兄弟们能否给口饭吃

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值