# quartzd **Repository Path**: studioustiger/quartzd ## Basic Information - **Project Name**: quartzd - **Description**: quartzd是基于quartz封装的动态作业调度,简化操作API,支持任务持久化和动态控制。 - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-03-04 - **Last Updated**: 2025-03-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: quartz, SpringBoot, Java, Job ## README ### 1. 导读 > Quartz 是一个开源的作业调度框架,它产生的主要目的是为了解决企业级应用中复杂的任务调度问题。 > 在实际的业务场景中,常常需要按照特定的时间规则(如每天凌晨执行数据备份、每月初生成报表等)来执行各种任务,手动管理这些任务的调度不仅繁琐且容易出错。 > Quartz 提供了一种灵活、可靠的方式来定义和管理这些任务的执行时间和顺序,使得开发者可以将更多的精力放在业务逻辑的实现上,而不是任务调度的细节。 Quartz 在“灵活性”、“可靠性” 和 “扩展性” 上有着优势,但是其在持久化方面的较为复杂,涉及的数据库表较多,对于一些轻量级的场景并不是很适合,本项目将提供一个超轻量的持久化方案、支持动态调用,并对 Quartz 的核心组件(Scheduler、Job、Trigger、JobDetial)进行了二次链式封装,降低了调度任务编写配置的复杂度。下面我们将以 “**Quartzd**” 来代指该项目。 **一定要看这个demo类:`src/main/java/com/quartzd/demo/DemoQuartzJob.java`** ### 2. 如何编写作业调度 在 **Quartzd** 中开发者编写作业调度开发者只需继承 `QuartzJob` 类并实现 `doJob()` 方法即可。 ```java // 任务执行逻辑 public class DemoQuartzJob extends QuartzJob { @Override public Object doJob(JobExecutionContext context) { return "DemoQuartzJob 执行完成"; } } ``` ### 3. 如何启动作业调度 结合上下两个方案,我们可以看出,相比于使用 Quartz 和核心组件创建任务实例要简便的多的多。在 **Quartzd** 中我们通过 `QuartzConfigFactory` 去构建出 `QuartzConfig`(调度配置),基于 `QuartzClient` 去创建任务任务实例即可。 ```java public static void main(String[] args) { // 配置 QuartzConfig jobConfig = new QuartzConfigFactory() .identity("12345678987654") .setJobClass(DemoQuartzJob.class) .cron("*/10 * * * * ?") .build(); // 启动 new QuartzClient().create(jobConfig); } ``` ### 4. 如何持久化任务调度 通过 “**如何启动作业调度**” 我演示了如何启动作业调度,但是在实际的使用中,我们并不会如此创建,在 **Quartzd** 中提供了操作的 `web api`,如下: ```java @RestController @RequestMapping("/job") public class JobController { private final QuartzClient quartzClient; private final QuartzInfoService quartzInfoService; public JobController(QuartzClient quartzClient, QuartzInfoService quartzInfoService) { this.quartzClient = quartzClient; this.quartzInfoService = quartzInfoService; } @PostMapping("/add") public Object add(@RequestBody JobInfo jobInfo) { jobInfo.setId(Func.uuid()); return quartzInfoService.save(jobInfo); } @PostMapping("/update") public Object update(@RequestBody JobInfo jobInfo) { JobInfo job = quartzInfoService.getById(jobInfo.getId()); if (job == null) { throw new RuntimeException("任务实例不存在"); } if (job.getStatus() == 1) { throw new RuntimeException("任务实例运行中,请先关闭实例"); } return quartzInfoService.updateById(jobInfo); } @GetMapping("/updateCron") public Object updateCron(@RequestParam String id, @RequestParam String cron) { JobInfo job = quartzInfoService.getById(id); if (job == null) { throw new RuntimeException("任务实例不存在"); } if (job.getStatus() == 1) { throw new RuntimeException("任务实例运行中,请先关闭实例"); } if (cron.equals(job.getCron())) { return true; } job.setCron(cron); return quartzInfoService.updateById(job); } @GetMapping("/delete") public Object delete(@RequestParam String id) throws ClassNotFoundException { JobInfo jobInfo = quartzInfoService.getById(id); if (jobInfo == null) { return true; } if (jobInfo.getStatus() == 1) { quartzClient.remove(JobInit.buildConfig(jobInfo)); } return quartzInfoService.removeById(id); } @GetMapping("/start") public Object start(@RequestParam String id) throws ClassNotFoundException { JobInfo jobInfo = quartzInfoService.getById(id); if (jobInfo == null) { throw new RuntimeException("任务实例不存在"); } if (jobInfo.getStatus() == 1) { return true; } quartzClient.create(JobInit.buildConfig(jobInfo)); return true; } @GetMapping("/stop") public Object stop(@RequestParam String id) throws ClassNotFoundException { JobInfo jobInfo = quartzInfoService.getById(id); if (jobInfo == null) { throw new RuntimeException("任务实例不存在"); } if (jobInfo.getStatus() == 0) { return true; } quartzClient.remove(JobInit.buildConfig(jobInfo)); return true; } } ``` **Quartzd** 并为提供前端界面,需要开发者自行设计。 ### 5. 表结构说明 ```sql CREATE TABLE `quartz_job_info` ( `id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务身份唯一标识', `cron` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'cron', `job_class` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'job类路径', `data_map` text COLLATE utf8mb4_general_ci COMMENT '执行参数', `last_time` datetime DEFAULT NULL COMMENT '最新时间', `status` int DEFAULT NULL COMMENT '状态(0停止 1启动)', PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='quartz定时任务状态'; ``` id : 主键,默认使用UUID。 cron:作业调度的Cron。 job_class:继承了 QuartzJob 的类的全类名。 data_map:数据格式为 JSON 字符串,作为执行方法中的变量去使用。 ### 6. 核心类说明 **com.quartzd.core.config.QuartzConfigFactory** 是 **Quartzd** 中的一个核心类,其目的是创建 QuartzConfig,在 **Quartzd** 中,任务是基于 QuartzConfig 创建的。 ```java # 下面是QuartzConfigFactory的完整使用 QuartzConfig config= new QuartzConfigFactory() // 设置唯一标识 .identity("12345678987654") // 设置自定义doJob类 .setJobClass(DemoQuartzJob.class) // 可以再自定义job中取到在此传递的值,value使用json字符串 .putDataMap(JobConst.DATA_MAP_KEY, "{code: \"12345678765\"}") // 设置cron表达式,也可以使用once()标识执行一次 .cron("*/10 * * * * ?") // 构建config .build(); ``` **com.quartzd.core.client.QuartzClient**是 **Quartzd** 中另一个核心类,其作用是提供操作作业调度的 API,例如:创建、移除、更新、安全 / 强制执行一次 ```java QuartzConfig config = ... # 创建 quartzClient.create(config); # 移除 quartzClient.remove(config); # 更新 config.setCron("*/15 * * * * ?"); quartzClient.updateCron(config); # 安全执行一次 quartzClient.createOnce(config, false); # 强制执行一次 quartzClient.createOnce(config, true); ```