XXL-Job、Quartz、ShedLock、@Scheduled等技术对比

----------------------------------------------------------------------------------------------

SpringBoot 四大定时任务:@Scheduled、Quartz、XXL-Job、ShedLock 全网清晰对比

 
直接按单机 / 集群、持久化、运维难度、生产选型一次性讲明白
 

1. 各自一句话定位

 
  1. @Scheduled(Spring Task)
     
    Spring 原生注解,纯内存单机定时,零依赖、最简单
  2. Quartz
     
    老牌开源调度,数据库持久化 + 原生集群,qrtz 十几张表
  3. XXL-Job
     
    分布式调度中台,可视化后台、分布式高可用、开箱即用,目前互联网首选
  4. ShedLock
     
    轻量分布式锁,不做调度,只防集群重复执行,搭配 @Scheduled 用
 

 

2. 核心维度全方位对比表

 
表格
 
对比项@ScheduledQuartzXXL-JobShedLock
存储 纯内存,无 DB MySQL 持久化(qrtz_系列表) MySQL 持久化 + 中心化调度 Redis/DB 锁,无任务表
集群重复执行 ❌ 多实例全部重复跑 ✅ 集群 DB 锁,只执行一次 ✅ 中心化调度,全局唯一 ✅ 分布式锁,只一台执行
项目重启 错过任务直接丢失不补发 ✅ 断点续跑、补发错过任务 ✅ 历史记录、失败重试、补发 ❌ 错过依旧不补发
动态修改 Cron ❌ 改配置必须重启 ✅ 数据库改触发器实时生效 ✅ 后台页面改,无需重启 ❌ 依旧要改代码 / 配置重启
可视化后台 ❌ 无任何界面 ❌ 原生无后台,自己开发 ✅ 自带 WEB 管理、监控、日志 ❌ 无后台
失败重试 ❌ 无 有限支持 ✅ 自定义重试次数、告警 不支持
阻塞问题 默认单线程,全部卡死 独立线程池 分布式分片、并行执行 共用 @Scheduled 线程池
分片广播任务 ❌ 不支持 弱支持 ✅ 超强分片、大数据批量处理 ❌ 不支持
部署架构 单机内存 去中心化 DB 集群 中心化调度中心 + 执行器 去中心化,原生 @Scheduled 加锁
学习 & 接入成本 极低 中等,表多配置复杂 极低,五分钟接入 极低,几行注解搞定
运维成本 几乎无 高,表多难排查 极低,页面看所有日志
 

 

3. 逐个深度优缺点

 

① @Scheduled Spring 原生

 
优点:
 
  • 零依赖、零配置、注解一行搞定
  • 单机小任务极致简单
     
    缺点:
  • 集群必重复执行
  • 重启丢失未执行任务
  • 无监控、无告警、无重试
  • 单线程阻塞所有任务
     
    适用:单机项目、不重要后台清理、缓存刷新
 

② Quartz(qrtz_triggers 这套)

 
优点:
 
  • 标准持久化调度,重启不丢任务
  • 数据库集群天然防重复
  • cron 表达式极强,日历、节假日都支持
     
    缺点:
  • 表超多(11 张 qrtz 表),臃肿难维护
  • 没有后台,排查麻烦
  • 分布式分片弱,大型业务不好用
  • 配置繁琐,集群坑多
     
    适用:传统政企、老项目、金融单机 / 小型集群严谨对账
 

③ XXL-Job (目前企业 90% 首选)

 
优点:
 
  • 可视化管理后台:启停、改 cron、查看日志、失败告警
  • 分布式高可用,调度中心集群
  • 分片任务:大数据分批处理
  • 失败重试、阻塞策略、过期补偿
  • 不侵入业务,接入极简单
     
    缺点:
     
    需要单独部署调度中心
     
    适用:微服务集群、线上重要业务、对账、报表、大数据定时、生产环境标配
 

④ ShedLock

 
本质:给 @Scheduled 加一把分布式锁
 
  • 不改变原有 @Scheduled 写法
  • Redis/MySQL 加锁,集群只有一台执行
  • 轻量、无额外架构、不用新服务
     
    缺点:
  • 依旧是内存调度,重启错过任务不补发
  • 没有后台、没有重试、没有分片
     
    适用:不想换 XXL-Job,只想解决 @Scheduled 集群重复执行
 

 

4. 终极选型口诀(背这个就够)

 
  1. 单机小项目,随便跑跑 → @Scheduled
  2. 老系统 Quartz 表不想动 → 继续 Quartz
  3. 微服务集群、线上重要定时、要后台监控 → XXL-Job
  4. 不想重构代码,只想防止多实例重复跑 → @Scheduled + ShedLock
 

 

5. 一句话总结关系

 
  • @Scheduled:单机裸奔定时
  • ShedLock:给裸奔加锁,解决重复执行,不解决重启丢失
  • Quartz:数据库持久化严谨单机 / 小集群
  • XXL-Job:分布式企业级全能调度,生产标准答案

----------------------------------------------------------------------------------------------

springboot @Scheduled

SpringBoot @Scheduled 定时任务详解

@Scheduled 是 Spring 提供的轻量级定时任务注解,无需整合第三方中间件,开箱即用,适合简单的定时、周期性任务(如定时统计、定时清理、定时同步等)。

一、核心使用步骤

1. 引入依赖

SpringBoot 自带定时任务功能,只需引入核心 web 依赖即可:
xml
 
 
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
 

2. 开启定时任务

在启动类上添加 @EnableScheduling 注解,开启定时任务功能:
java
 
运行
 
 
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling // 开启定时任务
public class ScheduledApplication {
    public static void main(String[] args) {
        SpringApplication.run(ScheduledApplication.class, args);
    }
}
 

3. 编写定时任务

创建一个 Spring 管理的 Bean(@Component),在方法上添加 @Scheduled 注解即可:
java
 
运行
 
 
 
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;

@Component
public class MyScheduledTask {

    /**
     * 定时任务方法
     * 注意:方法必须是 public void 无参!
     */
    @Scheduled(cron = "0/5 * * * * ?") // 每5秒执行一次
    public void testTask() {
        System.out.println("定时任务执行,当前时间:" + LocalDateTime.now());
    }
}
 

二、@Scheduled 三种核心用法

1. cron 表达式(最常用)

格式:秒 分 时 日 月 周 年(可选)语法:@Scheduled(cron = "表达式")

常用 cron 示例:

表格
 
表达式含义
0/5 * * * * ? 每 5 秒执行一次
0 0/1 * * * ? 每分钟执行一次
0 0 12 * * ? 每天中午 12 点执行
0 0 9 * * MON-FRI 工作日(周一到周五)早上 9 点执行
0 0 0 * * ? 每天凌晨执行
小技巧:在线生成 cron 工具(直接搜索「cron 在线生成」),无需死记硬背。

2. fixedRate:固定频率执行

含义:从上一次任务开始时间计算,每隔固定时间执行一次,不关心任务执行时长。
java
 
运行
 
 
 
// 每隔 5 秒执行一次(单位:毫秒,5000ms = 5s)
@Scheduled(fixedRate = 5000)
public void fixedRateTask() {
    System.out.println("fixedRate 定时任务执行");
}
 

3. fixedDelay:固定延迟执行

含义:从上一次任务结束时间计算,等待固定时间后再执行下一次。
java
 
运行
 
 
 
// 上一次执行完毕后,等待 5 秒再执行下一次
@Scheduled(fixedDelay = 5000)
public void fixedDelayTask() {
    System.out.println("fixedDelay 定时任务执行");
}
 

额外:initialDelay 初始延迟

配合 fixedRate/fixedDelay 使用,项目启动后延迟多久再执行第一次:
java
 
运行
 
 
 
// 项目启动后延迟3秒,之后每隔5秒执行一次
@Scheduled(initialDelay = 3000, fixedRate = 5000)
public void initialTask() {
    System.out.println("初始延迟+固定频率任务");
}
 

三、配置文件抽离(推荐)

硬编码不灵活,推荐把定时规则写到 application.yml 中,方便环境切换:

1. 配置文件

yaml
 
 
# application.yml
scheduled:
  cron: "0/5 * * * * ?"  # 每5秒
  fixed-rate: 5000
  fixed-delay: 5000
 

2. 注解引用

java
 
运行
 
 
 
@Scheduled(cron = "${scheduled.cron}")
public void configTask() {
    System.out.println("从配置文件读取cron表达式");
}
 

四、重要注意事项

  1. 定时任务方法要求:必须是 public void 无参方法,不能有返回值。
  2. 单线程执行:SpringBoot 默认定时任务是单线程的,如果多个任务同时执行,会阻塞!
     
    解决:添加多线程配置:
    java
     
    运行
     
     
     
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.SchedulingConfigurer;
    import org.springframework.scheduling.config.ScheduledTaskRegistrar;
    import java.util.concurrent.Executors;
    
    @Configuration
    public class ScheduledConfig implements SchedulingConfigurer {
        @Override
        public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
            // 设置线程池,支持多线程执行定时任务
            taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
        }
    }
    
     
     
  3. 分布式问题:@Scheduled 是单机定时任务,集群部署会重复执行!
     
    解决方案:使用分布式定时任务(XXL-Job、Quartz、ShedLock 等)。

总结

  1. @EnableScheduling 开启定时任务,@Scheduled 标记任务方法;
  2. 三种核心用法:cron(灵活)、fixedRate(固定频率)、fixedDelay(固定延迟);
  3. 推荐把规则写在配置文件,生产环境建议用线程池 + 分布式定时任务。
qrtz_triggers 和 @Scheduled 的区别

qrtz_triggers(Quartz) vs @Scheduled(Spring 原生)核心区别

先一句话分清:
  • qrtz_triggers:Quartz 框架数据库持久化触发器表,企业级分布式、集群、高可用调度
  • @Scheduled:Spring 自带内存单机注解定时任务,轻量简单、无数据库、不支持集群

一、先搞懂各自是什么

1. qrtz_triggers(Quartz)

Quartz 核心数据表,持久化存储所有定时触发器规则
  • 存:触发器名称 / 分组、关联 Job、下次触发时间、状态(等待 / 暂停 / 执行)、cron、错过策略、优先级
  • 配合 qrtz_job_details 组成完整任务 + 触发器,共享 DB 做集群锁、分布式不重复执行
  • 应用重启、节点宕机,任务规则与状态不丢失

2. @Scheduled(Spring Task)

Spring 内置注解定时任务,纯内存 JVM 调度,无任何数据库表
  • 启动扫描注解,内存注册任务,容器销毁任务消失
  • 默认单线程,集群多实例所有节点同时执行,重复跑任务

二、全方位对比表

表格
 
对比维度qrtz_triggers(Quartz)@Scheduled(Spring)
存储方式 数据库持久化(MySQL 等) 纯 JVM 内存,无持久化
集群分布式 ✅ 原生 DB 悲观锁,集群只执行一次 ❌ 多实例重复执行,无分布式协调
重启恢复 ✅ 重启自动续跑、断点恢复 ❌ 重启所有任务重置、历史丢失
动态管理 ✅ 运行时增删改暂停 cron,无需重启 ❌ 硬编码 / 配置文件,改规则必须重启服务
故障转移 ✅ 节点挂了,其他节点接管任务 ❌ 单点故障,本机宕机任务永久中断
触发能力 复杂 Cron、日历触发、错过补偿、优先级 基础 cron/fixedRate/fixedDelay,简单周期
线程模型 独立调度线程池,多任务隔离 默认单线程,长任务阻塞所有定时
依赖成本 额外引入 Quartz、建全套 11 张表 Spring 内置,零额外依赖、开箱即用
运维监控 DB 可查状态、执行日志、历史记录 几乎无原生监控,无执行台账
适用场景 生产集群、金融对账、报表、重要定时任务 单机简单清理、缓存刷新、轻量后台任务

三、底层原理差异

@Scheduled 原理

  1. @EnableScheduling 开启扫描
  2. 后置处理器扫描@Scheduled方法,封装内存 Task
  3. ThreadPoolTaskScheduler内存线程池调度
  4. 无数据库、无锁、无集群协调,容器关闭一切消失

qrtz_triggers(Quartz)原理

  1. JobDetail(任务)+ Trigger(规则)写入 DB
  2. 集群所有节点连同一个库,抢qrtz_triggers行锁
  3. 抢到锁节点执行,其他节点跳过
  4. 每次触发更新next_fire_time、触发器状态,全局统一调度

四、生产选型结论

  1. 单机项目、简单定时、不要求高可用 → 用 @Scheduled,极简无运维
  2. 集群多实例、重要业务、不能重复执行、重启不丢任务 → 用 Quartz(qrtz_triggers)
  3. 大型分布式运维 → 优先 XXL-Job,比原生 Quartz 更易用、带可视化后台
需要我给你一份SpringBoot 整合 Quartz 建表 SQL + 最简配置,直接就能用吗?
 
SpringBoot @Scheduled 定时任务 项目重启后任务会丢失么

一句话标准答案

SpringBoot @Scheduled 定时任务,项目重启后:任务规则不丢,执行进度 / 状态全部丢失

1、会不会丢失任务配置?

  • 不会丢失
  • @Scheduled(cron="xxx") 写在代码 / 配置文件里
  • 重启服务,Spring 重新扫描注解,自动重新加载定时规则

2、会不会丢失执行状态、错过的任务?

会,全部丢失!
  1. @Scheduled 是纯内存调度,不入库(没有 qrtz_triggers 这种表)
  2. 服务宕机 / 重启期间,本该执行的定时任务
     
    → 直接跳过,不会补执行
  3. 上一次任务有没有跑完、跑到哪一步、下次什么时候执行
     
    → 全部存在内存,重启清零重置

3、举个最直白例子

定时:每天凌晨 0 点执行对账
  • 23:50 重启服务
  • 00:00 服务刚好还没起来
     
    → 当天对账任务直接消失,不补发、不补偿

4、对比 Quartz(qrtz_triggers)

  • @Scheduled:内存任务 → 重启不补发错过任务
  • Quartz:数据库持久化 → 重启自动补跑错过任务、状态不丢

5、额外坑

  1. 默认单线程,一个任务卡住,所有定时全部阻塞
  2. 集群多实例部署 → 所有机器同时跑同一个任务,重复执行
  3. 长时间未执行、错过周期,Spring Task 一律不补发

极简总结

  • 定时规则:重启不丢
  • 定时执行记录、未执行任务、断点进度:全部丢失
  • 重要业务、对账、报表 → 绝对不要用 @Scheduled

----------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------

posted @ 2026-04-22 14:28  hanease  阅读(109)  评论(0)    收藏  举报