From 0f9a9b1c8349853a1608bc1006ea09da1690b7ec Mon Sep 17 00:00:00 2001 From: ZhengJie <201507802@qq.com> Date: Sun, 24 May 2020 14:57:59 +0800 Subject: [PATCH] =?UTF-8?q?[=E4=BB=A3=E7=A0=81=E5=AE=8C=E5=96=84](v2.5):?= =?UTF-8?q?=20v2.5=20beta=20=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=E5=AD=90?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E4=BC=98=E5=8C=96=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1、定时任务中子任务按顺序执行 2、如果子任务执行途中报错,则不会再执行后面的子任务 3、子任务按逗号隔开,中英文逗号都可以 4、子任务中不能添加自身的ID,不然会无限循环 2.5 进度: https://www.ydyno.com/archives/1225.html --- .../modules/quartz/domain/QuartzJob.java | 4 ++ .../quartz/service/QuartzJobService.java | 8 +++- .../service/impl/QuartzJobServiceImpl.java | 39 +++++++++++++++++-- .../modules/quartz/utils/ExecutionJob.java | 23 +++++------ sql/eladmin.sql | 2 +- 5 files changed, 59 insertions(+), 17 deletions(-) diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/domain/QuartzJob.java b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/domain/QuartzJob.java index 7d678a1e..39e11f42 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/domain/QuartzJob.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/domain/QuartzJob.java @@ -42,6 +42,10 @@ public class QuartzJob extends BaseEntity implements Serializable { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Transient + @ApiModelProperty(value = "用于子任务唯一标识", hidden = true) + private String uuid; + @ApiModelProperty(value = "定时器名称") private String jobName; diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/QuartzJobService.java b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/QuartzJobService.java index bd385799..b32850e9 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/QuartzJobService.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/QuartzJobService.java @@ -19,7 +19,6 @@ import me.zhengjie.modules.quartz.domain.QuartzJob; import me.zhengjie.modules.quartz.domain.QuartzLog; import me.zhengjie.modules.quartz.service.dto.JobQueryCriteria; import org.springframework.data.domain.Pageable; - import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; @@ -113,4 +112,11 @@ public interface QuartzJobService { * @throws IOException / */ void downloadLog(List queryAllLog, HttpServletResponse response) throws IOException; + + /** + * 执行子任务 + * @param tasks / + * @throws InterruptedException / + */ + void executionSubJob(String[] tasks) throws InterruptedException; } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/impl/QuartzJobServiceImpl.java b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/impl/QuartzJobServiceImpl.java index a7b3965d..1ebdd88d 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/impl/QuartzJobServiceImpl.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/service/impl/QuartzJobServiceImpl.java @@ -15,6 +15,7 @@ */ package me.zhengjie.modules.quartz.service.impl; +import cn.hutool.core.util.IdUtil; import lombok.RequiredArgsConstructor; import me.zhengjie.exception.BadRequestException; import me.zhengjie.modules.quartz.domain.QuartzJob; @@ -24,12 +25,10 @@ import me.zhengjie.modules.quartz.repository.QuartzLogRepository; import me.zhengjie.modules.quartz.service.QuartzJobService; import me.zhengjie.modules.quartz.service.dto.JobQueryCriteria; import me.zhengjie.modules.quartz.utils.QuartzManage; -import me.zhengjie.utils.FileUtil; -import me.zhengjie.utils.PageUtil; -import me.zhengjie.utils.QueryHelp; -import me.zhengjie.utils.ValidationUtil; +import me.zhengjie.utils.*; import org.quartz.CronExpression; import org.springframework.data.domain.Pageable; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.servlet.http.HttpServletResponse; @@ -47,6 +46,7 @@ public class QuartzJobServiceImpl implements QuartzJobService { private final QuartzJobRepository quartzJobRepository; private final QuartzLogRepository quartzLogRepository; private final QuartzManage quartzManage; + private final RedisUtils redisUtils; @Override public Object queryAll(JobQueryCriteria criteria, Pageable pageable){ @@ -91,6 +91,12 @@ public class QuartzJobServiceImpl implements QuartzJobService { if (!CronExpression.isValidExpression(resources.getCronExpression())){ throw new BadRequestException("cron表达式格式错误"); } + if(StringUtils.isNotBlank(resources.getSubTask())){ + List tasks = Arrays.asList(resources.getSubTask().split("[,,]")); + if (tasks.contains(resources.getId().toString())) { + throw new BadRequestException("子任务中不能添加当前任务ID"); + } + } resources = quartzJobRepository.save(resources); quartzManage.updateJobCron(resources); } @@ -122,6 +128,31 @@ public class QuartzJobServiceImpl implements QuartzJobService { } } + @Async + @Override + @Transactional(rollbackFor = Exception.class) + public void executionSubJob(String[] tasks) throws InterruptedException { + for (String id : tasks) { + QuartzJob quartzJob = findById(Long.parseLong(id)); + // 执行任务 + String uuid = IdUtil.simpleUUID(); + quartzJob.setUuid(uuid); + // 执行任务 + execution(quartzJob); + // 获取执行状态,如果执行失败则停止后面的子任务执行 + Boolean result = (Boolean) redisUtils.get(uuid); + while (result == null) { + // 休眠5秒,再次获取子任务执行情况 + Thread.sleep(5000); + result = (Boolean) redisUtils.get(uuid); + } + if(!result){ + redisUtils.del(uuid); + break; + } + } + } + @Override public void download(List quartzJobs, HttpServletResponse response) throws IOException { List> list = new ArrayList<>(); diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java index c79488ab..e79193f8 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/quartz/utils/ExecutionJob.java @@ -26,14 +26,12 @@ import me.zhengjie.modules.quartz.domain.QuartzLog; import me.zhengjie.modules.quartz.repository.QuartzLogRepository; import me.zhengjie.modules.quartz.service.QuartzJobService; import me.zhengjie.service.EmailService; +import me.zhengjie.utils.RedisUtils; import me.zhengjie.utils.SpringContextHolder; import me.zhengjie.utils.ThrowableUtil; import org.quartz.JobExecutionContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.quartz.QuartzJobBean; - import java.util.*; import java.util.concurrent.*; @@ -46,8 +44,6 @@ import java.util.concurrent.*; @SuppressWarnings({"unchecked","all"}) public class ExecutionJob extends QuartzJobBean { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - /** 该处仅供参考 */ private final static ThreadPoolExecutor EXECUTOR = ThreadPoolExecutorUtil.getPoll(); @@ -57,6 +53,7 @@ public class ExecutionJob extends QuartzJobBean { // 获取spring bean QuartzLogRepository quartzLogRepository = SpringContextHolder.getBean(QuartzLogRepository.class); QuartzJobService quartzJobService = SpringContextHolder.getBean(QuartzJobService.class); + RedisUtils redisUtils = SpringContextHolder.getBean(RedisUtils.class); QuartzLog log = new QuartzLog(); log.setJobName(quartzJob.getJobName()); @@ -67,25 +64,29 @@ public class ExecutionJob extends QuartzJobBean { log.setCronExpression(quartzJob.getCronExpression()); try { // 执行任务 - logger.info("任务准备执行,任务名称:{}", quartzJob.getJobName()); + System.out.println("--------------------------------------------------------------"); + System.out.println("任务开始执行,任务名称:" + quartzJob.getJobName()); QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(), quartzJob.getParams()); Future future = EXECUTOR.submit(task); future.get(); long times = System.currentTimeMillis() - startTime; log.setTime(times); + redisUtils.set(quartzJob.getUuid(), true); // 任务状态 log.setIsSuccess(true); - logger.info("任务执行完毕,任务名称:{} 总共耗时:{} 毫秒", quartzJob.getJobName(), times); + System.out.println("任务执行完毕,任务名称:" + quartzJob.getJobName() + ", 执行时间:" + times + "毫秒"); + System.out.println("--------------------------------------------------------------"); // 判断是否存在子任务 if(quartzJob.getSubTask() != null){ String[] tasks = quartzJob.getSubTask().split("[,,]"); - for (String id : tasks) { - quartzJobService.execution(quartzJobService.findById(Long.parseLong(id))); - } + // 执行子任务 + quartzJobService.executionSubJob(tasks); } } catch (Exception e) { - logger.error("任务执行失败,任务名称:{}" + quartzJob.getJobName(), e); + redisUtils.set(quartzJob.getUuid(), false); + System.out.println("任务执行失败,任务名称:" + quartzJob.getJobName()); + System.out.println("--------------------------------------------------------------"); long times = System.currentTimeMillis() - startTime; log.setTime(times); // 任务状态 0:成功 1:失败 diff --git a/sql/eladmin.sql b/sql/eladmin.sql index 01dee727..5a95b68f 100644 --- a/sql/eladmin.sql +++ b/sql/eladmin.sql @@ -477,7 +477,7 @@ CREATE TABLE `sys_quartz_job` ( -- Records of sys_quartz_job -- ---------------------------- BEGIN; -INSERT INTO `sys_quartz_job` VALUES (2, 'testTask', '0/5 * * * * ?', b'1', '测试1', 'run1', 'test', '带参测试,多参使用json', NULL, NULL, NULL, NULL, NULL, 'admin', '2019-08-22 14:08:29', '2020-05-05 17:26:19'); +INSERT INTO `sys_quartz_job` VALUES (2, 'testTask', '0/5 * * * * ?', b'1', '测试1', 'run1', 'test', '带参测试,多参使用json', '测试', NULL, NULL, NULL, NULL, 'admin', '2019-08-22 14:08:29', '2020-05-05 17:26:19'); INSERT INTO `sys_quartz_job` VALUES (3, 'testTask', '0/5 * * * * ?', b'1', '测试', 'run', '', '不带参测试', 'Zheng Jie', '', '2,6', b'1', NULL, 'admin', '2019-09-26 16:44:39', '2020-05-05 20:45:39'); INSERT INTO `sys_quartz_job` VALUES (5, 'Test', '0/5 * * * * ?', b'1', '任务告警测试', 'run', NULL, '测试', 'test', '', NULL, b'1', 'admin', 'admin', '2020-05-05 20:32:41', '2020-05-05 20:36:13'); INSERT INTO `sys_quartz_job` VALUES (6, 'testTask', '0/5 * * * * ?', b'1', '测试3', 'run2', NULL, '测试3', 'Zheng Jie', '', NULL, b'1', 'admin', 'admin', '2020-05-05 20:35:41', '2020-05-05 20:36:07');