1697 字
约 5 分钟
0
Quartz 定时任务入门

Quartz 定时任务入门

1. 一句话简介

Quartz 是一个功能成熟的开源任务调度(Job Scheduler)框架,核心由 Job(任务逻辑)、Trigger(触发规则)、Scheduler(调度器)三要素组成。它解决的核心问题是「在约定时刻或按 Cron 表达式周期性地执行指定代码」,并支持任务持久化、集群和运行时动态管理。与 Spring 自带的 @Scheduled 相比,Quartz(demo-task-quartz 模块即演示其用法)通过 spring-boot-starter-quartz 自动装配 Scheduler,再配合 JobStoreTX 把任务与触发器写入 MySQL 的 11 张 QRTZ_* 表,从而能在应用运行时对任务进行新增、删除、暂停、恢复、修改 Cron,且重启后任务不丢失。

2. 什么时候使用

✅ 适用场景

  • 需要运行时动态管理定时任务:任务不能写死在代码里,而是要在运行期由外部(如 REST API、管理后台)新增、删除、暂停、恢复、改触发时间。demo-task-quartz 正是一个通过 JobController 暴露这套 CRUD 接口的完整示例。
  • 任务需要持久化、重启后不丢失:把 job-store-type 设为 jdbc 后,任务和触发器存入数据库,应用重启、进程退出后调度状态仍在。这是 @Scheduled 给不了的。
  • 需要成熟丰富的触发方式:支持 Cron 表达式、固定间隔、指定次数、错过触发(misfire)补偿、通知/监听器等能力,适合规则复杂的调度需求。
  • 需要调度器高可用或横向扩展:Quartz 的 JDBC JobStore 支持集群部署,多个节点共享同一套数据库表,配合 QRTZ_LOCKS 锁表和 acquireTriggersWithinLock 上锁避免重复调度。
  • 希望框架自动管理线程池:demo 中通过 org.quartz.threadPool.threadCount: 5 配置并发线程数,任务的并发执行由 Quartz 托管,业务代码无感知。

❌ 不适用 / 需谨慎

  • 只会写死几个固定任务、不需要动态调整:简单场景用 Spring @Scheduled 一行注解即可,引入 Quartz 反而要初始化系统表、配 JobStore,属于过度设计。
  • 仅需快速落地的原型 / 非关键业务:Quartz 配置项多、概念多,学习成本明显高于 @Scheduled,对轻量场景收益不成比例。
  • 需要开箱即用的可视化任务管理、分片调度等能力:Quartz 本身不带 Web 管理界面,也没有 XXL-JOB 那样的调度控制中心和分片执行能力,需要自行搭建 UI(demo 用 Vue + Element UI 自写了 job.html)。
  • 任务量极大、追求秒级以下精度或大规模分布式编排:Quartz 依赖数据库轮询触发器,性能天花板有限;超大规模调度建议用专为分布式设计的 XXL-JOB、Elastic-Job 等。
  • 环境不允许初始化数据库并维护系统表:JDBC 持久化是 Quartz 分布式/持久化的前提;若项目连不上库,Quartz 的持久化优势就无法发挥。

3. 常见业务场景

后台任务管理平台:运营人员通过管理后台随时新增「定时跑报表」「定时同步数据」等任务,随时暂停或调整频率。demo-task-quartz 展示的正是这样一套系统:POST /job 添加、PUT /job?pause|resume|cron 暂停/恢复/改 Cron,调度过程完全由用户驱动,而非写死在代码里。

建表脚本演示持久化:demo 初始化时执行 tables_mysql_innodb.sql 创建 11 张 QRTZ_* 表(QRTZ_JOB_DETAILSQRTZ_TRIGGERSQRTZ_CRON_TRIGGERSQRTZ_LOCKS 等)。对应真实场景,凡是"停机后任务仍需继续"的约定任务——比如账单日扫描、每日数据归档——都可借助持久化保证重启后调度无缝衔接。

按 Cron 表达式的周期任务:demo 用 CronScheduleBuilder.cronSchedule() 构建 CronTrigger,前端传 0/10 * * * * ? 即可每 10 秒执行一次 HelloJob/TestJob。真实场景里,"每天 9 点生成运营日报""每月 1 日凌晨执行库存清算"这类需要精确 Cron 规则的任务是 Quartz 的主场。

任务生命周期精细控制:demo 通过 scheduler.pauseTrigger() / unscheduleJob() / deleteJob() 分步实现删除,用 rescheduleJob() 在不删除任务的前提下替换触发器改时间。适用于对任务状态(WAITING/PAUSED/ACQUIRED)和启停时机有严格要求的业务。

任务即插即用(反射动态装配):demo 用 JobUtil.getClass() 通过 Class.forName() + newInstance() 根据全类名动态实例化 BaseJob 的实现类,新增任务无需改代码、无需重启。这对"允许在运行时注册新类型任务"的中后台系统尤其合适——新增一个任务类即自动获得调度能力。

4. 同类技术对比

技术方案 持久化/重启恢复 动态管理 分布式/高可用 运维成本 学习成本 适用规模
Quartz(本模块) 支持(JDBC JobStore) 强,运行时增删改查 支持(集群模式),但配置偏重 中,需初始化系统表、自行搭 UI 中高 中小规模、单机到小规模集群
Spring @Scheduled 不支持,进程内仅内存 无,写死在注解里 不支持 极低,零配置零依赖 极低 简单固定任务、单机单体
XXL-JOB 强,自带任务持久化 强,带可视化调度中心 强,分片、failover 开箱即用 高,需独立部署调度中心 大规模、分布式任务调度
Elastic-Job 强,基于 Zookeeper 强,分片/弹性伸缩 强,天然分布式分片 高,依赖 ZK 维护 分片型分布式任务(如批处理)

选型建议

  • 简单的固定周期任务、单机单体、不想引入额外运维:选 Spring @Scheduled,零成本满足需求,是大多数场景的默认首选。
  • 在 Spring Boot 内需要动态管理任务、JobStore 持久化、又不想部署额外中间件:选 Quartz。Spring Boot 用 spring-boot-starter-quartz 可自动装配,配合 JDBC 持久化即可覆盖绝大部分单体/小集群业务。
  • 任务规模大、分布部署、需要运维可视化管理中心与分片能力:选 XXL-JOB,它的调度中心、failover、分片开箱即用,代价是独立部署与更高的架构复杂度。
  • 任务天然适合分片、且乐意维护 Zookeeper 集群:选 Elastic-Job,它在数据分片与弹性伸缩上最强,适合大数据量批处理。
Quartz 定时任务入门
http://www.clxhxhhr.top/posts/499/
作者
clxstart
发布于
2026-09-07
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。