定时任务
CmdAdmin 集成了 Quartz 定时任务调度框架,提供可视化的任务管理界面。
功能特性
- Cron 表达式配置:支持可视化配置执行规则
- 任务状态控制:启动、暂停、恢复、立即执行
- 执行日志:详细记录每次任务执行结果
- 内置任务:提供 8 个常用定时任务
内置定时任务
| 任务名称 | 说明 | 默认 Cron |
|---|---|---|
| CleanExpiredLogJob | 清理过期日志 | 0 0 2 * * ? |
| CleanTempFileJob | 清理临时文件 | 0 0 3 * * ? |
| DataSyncJob | 数据同步 | 0 */5 * * * ? |
| DatabaseBackupJob | 数据库备份 | 0 0 1 * * ? |
| DbPoolMonitorJob | 连接池监控 | 0 */1 * * * ? |
| OrderTimeoutJob | 订单超时处理 | 0 */10 * * * ? |
| ReportGenerateJob | 报表生成 | 0 0 6 * * ? |
| ServerLoadMonitorJob | 服务器负载监控 | 0 */2 * * * ? |
任务管理界面
任务列表
展示所有定时任务的基本信息:
- 任务名称
- 任务组
- Cron 表达式
- 任务状态(运行中/已暂停)
- 下次执行时间
- 操作按钮
新增/编辑任务
java
@OperLog(title = "定时任务", businessType = BusinessType.INSERT)
@PostMapping("/add")
public Result<Void> add(@RequestBody @Validated SysJob job) {
// 校验 Cron 表达式合法性
if (!CronExpression.isValidExpression(job.getCronExpression())) {
return Result.error("Cron表达式格式错误");
}
// 保存任务并添加到调度器
sysJobService.addJob(job);
return Result.ok();
}任务操作
| 操作 | 说明 | 接口 |
|---|---|---|
| 启动 | 启动定时任务 | POST /system/job/resume/ |
| 暂停 | 暂停定时任务 | POST /system/job/pause/ |
| 立即执行 | 手动触发一次 | POST /system/job/run/ |
| 删除 | 删除定时任务 | DELETE /system/job/delete/ |
Cron 表达式说明
Cron 表达式由 6 或 7 个字段组成,格式如下:
秒 分 时 日 月 周 年(可选)常用示例
| 表达式 | 说明 |
|---|---|
0 0 12 * * ? | 每天中午12点触发 |
0 15 10 ? * * | 每天上午10:15触发 |
0 0/5 14 * * ? | 每天下午2点到2:55,每隔5分钟触发 |
0 0 0 * * ? | 每天凌晨0点触发 |
0 0 8 ? * MON | 每周一上午8点触发 |
0 0 1 1 * ? | 每月1号凌晨1点触发 |
特殊字符
| 字符 | 含义 |
|---|---|
* | 匹配任意值 |
? | 不指定值(用于日或周) |
- | 范围 |
, | 列表 |
/ | 增量 |
L | 最后 |
W | 最近工作日 |
# | 第几个 |
自定义定时任务
1. 创建任务类
java
@Component
public class MyCustomJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// 获取任务参数
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
String param = dataMap.getString("param");
// 执行业务逻辑
System.out.println("执行自定义任务,参数:" + param);
// 记录执行日志
SysJobLog jobLog = new SysJobLog();
jobLog.setJobName(context.getJobDetail().getKey().getName());
jobLog.setJobGroup(context.getJobDetail().getKey().getGroup());
jobLog.setInvokeTarget("myCustomJob");
jobLog.setStatus("0"); // 成功
jobLog.setCreateTime(LocalDateTime.now());
// 保存日志...
}
}2. 注册任务
java
@Service
public class SysJobService {
@Autowired
private Scheduler scheduler;
public void addJob(SysJob job) throws SchedulerException {
// 创建任务详情
JobDetail jobDetail = JobBuilder.newJob(MyCustomJob.class)
.withIdentity(job.getJobName(), job.getJobGroup())
.usingJobData("param", job.getJobParams())
.build();
// 创建触发器
CronTrigger trigger = TriggerBuilder.newTrigger()
.withIdentity(job.getJobName() + "_trigger", job.getJobGroup())
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
.build();
// 调度任务
scheduler.scheduleJob(jobDetail, trigger);
// 如果状态为暂停,则暂停任务
if ("1".equals(job.getStatus())) {
scheduler.pauseJob(jobDetail.getKey());
}
}
}执行日志
每次任务执行都会记录详细日志:
| 字段 | 说明 |
|---|---|
| job_name | 任务名称 |
| job_group | 任务组 |
| invoke_target | 调用目标 |
| job_message | 执行信息 |
| status | 执行状态(0成功 1失败) |
| exception_info | 异常信息 |
| create_time | 执行时间 |
注意事项
- 任务幂等性:定时任务可能被重复执行,业务逻辑需要保证幂等性
- 异常处理:任务执行异常会被捕获并记录,不会影响其他任务
- 集群部署:Quartz 支持集群模式,需要配置 JDBC JobStore
- 时区问题:Cron 表达式默认使用服务器时区
相关配置
yaml
# application.yml
spring:
quartz:
job-store-type: memory # 内存模式,集群环境改为 jdbc
properties:
org:
quartz:
scheduler:
instanceName: CmdAdminScheduler
instanceId: AUTO
threadPool:
threadCount: 10