mirror of https://github.com/elunez/eladmin
[代码完善](v2.5): v2.5 beta 定时任务子任务优化完成
1、定时任务中子任务按顺序执行 2、如果子任务执行途中报错,则不会再执行后面的子任务 3、子任务按逗号隔开,中英文逗号都可以 4、子任务中不能添加自身的ID,不然会无限循环 2.5 进度: https://www.ydyno.com/archives/1225.htmlpull/372/head
parent
21f8b4ebb5
commit
0f9a9b1c83
|
@ -42,6 +42,10 @@ public class QuartzJob extends BaseEntity implements Serializable {
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
@ApiModelProperty(value = "用于子任务唯一标识", hidden = true)
|
||||||
|
private String uuid;
|
||||||
|
|
||||||
@ApiModelProperty(value = "定时器名称")
|
@ApiModelProperty(value = "定时器名称")
|
||||||
private String jobName;
|
private String jobName;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ import me.zhengjie.modules.quartz.domain.QuartzJob;
|
||||||
import me.zhengjie.modules.quartz.domain.QuartzLog;
|
import me.zhengjie.modules.quartz.domain.QuartzLog;
|
||||||
import me.zhengjie.modules.quartz.service.dto.JobQueryCriteria;
|
import me.zhengjie.modules.quartz.service.dto.JobQueryCriteria;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -113,4 +112,11 @@ public interface QuartzJobService {
|
||||||
* @throws IOException /
|
* @throws IOException /
|
||||||
*/
|
*/
|
||||||
void downloadLog(List<QuartzLog> queryAllLog, HttpServletResponse response) throws IOException;
|
void downloadLog(List<QuartzLog> queryAllLog, HttpServletResponse response) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行子任务
|
||||||
|
* @param tasks /
|
||||||
|
* @throws InterruptedException /
|
||||||
|
*/
|
||||||
|
void executionSubJob(String[] tasks) throws InterruptedException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package me.zhengjie.modules.quartz.service.impl;
|
package me.zhengjie.modules.quartz.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import me.zhengjie.exception.BadRequestException;
|
import me.zhengjie.exception.BadRequestException;
|
||||||
import me.zhengjie.modules.quartz.domain.QuartzJob;
|
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.QuartzJobService;
|
||||||
import me.zhengjie.modules.quartz.service.dto.JobQueryCriteria;
|
import me.zhengjie.modules.quartz.service.dto.JobQueryCriteria;
|
||||||
import me.zhengjie.modules.quartz.utils.QuartzManage;
|
import me.zhengjie.modules.quartz.utils.QuartzManage;
|
||||||
import me.zhengjie.utils.FileUtil;
|
import me.zhengjie.utils.*;
|
||||||
import me.zhengjie.utils.PageUtil;
|
|
||||||
import me.zhengjie.utils.QueryHelp;
|
|
||||||
import me.zhengjie.utils.ValidationUtil;
|
|
||||||
import org.quartz.CronExpression;
|
import org.quartz.CronExpression;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
@ -47,6 +46,7 @@ public class QuartzJobServiceImpl implements QuartzJobService {
|
||||||
private final QuartzJobRepository quartzJobRepository;
|
private final QuartzJobRepository quartzJobRepository;
|
||||||
private final QuartzLogRepository quartzLogRepository;
|
private final QuartzLogRepository quartzLogRepository;
|
||||||
private final QuartzManage quartzManage;
|
private final QuartzManage quartzManage;
|
||||||
|
private final RedisUtils redisUtils;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object queryAll(JobQueryCriteria criteria, Pageable pageable){
|
public Object queryAll(JobQueryCriteria criteria, Pageable pageable){
|
||||||
|
@ -91,6 +91,12 @@ public class QuartzJobServiceImpl implements QuartzJobService {
|
||||||
if (!CronExpression.isValidExpression(resources.getCronExpression())){
|
if (!CronExpression.isValidExpression(resources.getCronExpression())){
|
||||||
throw new BadRequestException("cron表达式格式错误");
|
throw new BadRequestException("cron表达式格式错误");
|
||||||
}
|
}
|
||||||
|
if(StringUtils.isNotBlank(resources.getSubTask())){
|
||||||
|
List<String> tasks = Arrays.asList(resources.getSubTask().split("[,,]"));
|
||||||
|
if (tasks.contains(resources.getId().toString())) {
|
||||||
|
throw new BadRequestException("子任务中不能添加当前任务ID");
|
||||||
|
}
|
||||||
|
}
|
||||||
resources = quartzJobRepository.save(resources);
|
resources = quartzJobRepository.save(resources);
|
||||||
quartzManage.updateJobCron(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
|
@Override
|
||||||
public void download(List<QuartzJob> quartzJobs, HttpServletResponse response) throws IOException {
|
public void download(List<QuartzJob> quartzJobs, HttpServletResponse response) throws IOException {
|
||||||
List<Map<String, Object>> list = new ArrayList<>();
|
List<Map<String, Object>> list = new ArrayList<>();
|
||||||
|
|
|
@ -26,14 +26,12 @@ import me.zhengjie.modules.quartz.domain.QuartzLog;
|
||||||
import me.zhengjie.modules.quartz.repository.QuartzLogRepository;
|
import me.zhengjie.modules.quartz.repository.QuartzLogRepository;
|
||||||
import me.zhengjie.modules.quartz.service.QuartzJobService;
|
import me.zhengjie.modules.quartz.service.QuartzJobService;
|
||||||
import me.zhengjie.service.EmailService;
|
import me.zhengjie.service.EmailService;
|
||||||
|
import me.zhengjie.utils.RedisUtils;
|
||||||
import me.zhengjie.utils.SpringContextHolder;
|
import me.zhengjie.utils.SpringContextHolder;
|
||||||
import me.zhengjie.utils.ThrowableUtil;
|
import me.zhengjie.utils.ThrowableUtil;
|
||||||
import org.quartz.JobExecutionContext;
|
import org.quartz.JobExecutionContext;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
|
@ -46,8 +44,6 @@ import java.util.concurrent.*;
|
||||||
@SuppressWarnings({"unchecked","all"})
|
@SuppressWarnings({"unchecked","all"})
|
||||||
public class ExecutionJob extends QuartzJobBean {
|
public class ExecutionJob extends QuartzJobBean {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
||||||
|
|
||||||
/** 该处仅供参考 */
|
/** 该处仅供参考 */
|
||||||
private final static ThreadPoolExecutor EXECUTOR = ThreadPoolExecutorUtil.getPoll();
|
private final static ThreadPoolExecutor EXECUTOR = ThreadPoolExecutorUtil.getPoll();
|
||||||
|
|
||||||
|
@ -57,6 +53,7 @@ public class ExecutionJob extends QuartzJobBean {
|
||||||
// 获取spring bean
|
// 获取spring bean
|
||||||
QuartzLogRepository quartzLogRepository = SpringContextHolder.getBean(QuartzLogRepository.class);
|
QuartzLogRepository quartzLogRepository = SpringContextHolder.getBean(QuartzLogRepository.class);
|
||||||
QuartzJobService quartzJobService = SpringContextHolder.getBean(QuartzJobService.class);
|
QuartzJobService quartzJobService = SpringContextHolder.getBean(QuartzJobService.class);
|
||||||
|
RedisUtils redisUtils = SpringContextHolder.getBean(RedisUtils.class);
|
||||||
|
|
||||||
QuartzLog log = new QuartzLog();
|
QuartzLog log = new QuartzLog();
|
||||||
log.setJobName(quartzJob.getJobName());
|
log.setJobName(quartzJob.getJobName());
|
||||||
|
@ -67,25 +64,29 @@ public class ExecutionJob extends QuartzJobBean {
|
||||||
log.setCronExpression(quartzJob.getCronExpression());
|
log.setCronExpression(quartzJob.getCronExpression());
|
||||||
try {
|
try {
|
||||||
// 执行任务
|
// 执行任务
|
||||||
logger.info("任务准备执行,任务名称:{}", quartzJob.getJobName());
|
System.out.println("--------------------------------------------------------------");
|
||||||
|
System.out.println("任务开始执行,任务名称:" + quartzJob.getJobName());
|
||||||
QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(),
|
QuartzRunnable task = new QuartzRunnable(quartzJob.getBeanName(), quartzJob.getMethodName(),
|
||||||
quartzJob.getParams());
|
quartzJob.getParams());
|
||||||
Future<?> future = EXECUTOR.submit(task);
|
Future<?> future = EXECUTOR.submit(task);
|
||||||
future.get();
|
future.get();
|
||||||
long times = System.currentTimeMillis() - startTime;
|
long times = System.currentTimeMillis() - startTime;
|
||||||
log.setTime(times);
|
log.setTime(times);
|
||||||
|
redisUtils.set(quartzJob.getUuid(), true);
|
||||||
// 任务状态
|
// 任务状态
|
||||||
log.setIsSuccess(true);
|
log.setIsSuccess(true);
|
||||||
logger.info("任务执行完毕,任务名称:{} 总共耗时:{} 毫秒", quartzJob.getJobName(), times);
|
System.out.println("任务执行完毕,任务名称:" + quartzJob.getJobName() + ", 执行时间:" + times + "毫秒");
|
||||||
|
System.out.println("--------------------------------------------------------------");
|
||||||
// 判断是否存在子任务
|
// 判断是否存在子任务
|
||||||
if(quartzJob.getSubTask() != null){
|
if(quartzJob.getSubTask() != null){
|
||||||
String[] tasks = quartzJob.getSubTask().split("[,,]");
|
String[] tasks = quartzJob.getSubTask().split("[,,]");
|
||||||
for (String id : tasks) {
|
// 执行子任务
|
||||||
quartzJobService.execution(quartzJobService.findById(Long.parseLong(id)));
|
quartzJobService.executionSubJob(tasks);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} 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;
|
long times = System.currentTimeMillis() - startTime;
|
||||||
log.setTime(times);
|
log.setTime(times);
|
||||||
// 任务状态 0:成功 1:失败
|
// 任务状态 0:成功 1:失败
|
||||||
|
|
|
@ -477,7 +477,7 @@ CREATE TABLE `sys_quartz_job` (
|
||||||
-- Records of sys_quartz_job
|
-- Records of sys_quartz_job
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
BEGIN;
|
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 (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 (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');
|
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');
|
||||||
|
|
Loading…
Reference in New Issue