完善 JobHandlerInvoker 的执行,记录 Job 执行日志

pull/2/head
YunaiV 2021-02-15 01:25:59 +08:00
parent f60855faa0
commit 5fc03bd8aa
4 changed files with 123 additions and 29 deletions

View File

@ -1,39 +1,103 @@
package cn.iocoder.dashboard.framework.quartz.core.handler;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.dashboard.common.exception.ServiceException;
import cn.iocoder.dashboard.common.pojo.CommonResult;
import cn.iocoder.dashboard.framework.quartz.core.enums.JobDataKeyEnum;
import cn.iocoder.dashboard.framework.quartz.core.service.JobLogFrameworkService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;
import javax.annotation.Resource;
import java.util.Date;
import static cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
import static cn.iocoder.dashboard.util.date.DateUtils.diff;
/**
* Job {@link JobHandler#execute(String)}
*
* @author
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
@Slf4j
public class JobHandlerInvoker extends QuartzJobBean {
@Resource
private ApplicationContext applicationContext;
@Resource
private JobLogFrameworkService jobLogFrameworkService;
@Override
protected void executeInternal(JobExecutionContext executionContext) {
// 获得 JobHandler 对象
protected void executeInternal(JobExecutionContext executionContext) throws JobExecutionException {
// 获得 Job 数据
// 1. 获得 jobId 参数
String jobIdStr = getJobData(executionContext, JobDataKeyEnum.JOB_ID);
if (NumberUtil.isNumber(jobIdStr)) {
log.error("[executeInternal][Job({}) 获取不到正确的 jobId({})]", executionContext.getJobDetail().getKey(), jobIdStr);
throw new IllegalStateException(StrUtil.format("Job({}) 获取不到正确的 jobId({})",
executionContext.getJobDetail().getKey(), jobIdStr));
}
Long jobId = Long.valueOf(jobIdStr);
// 2. 获得 jobHandlerName 参数
String jobHandlerName = getJobData(executionContext, JobDataKeyEnum.JOB_HANDLER_NAME);
if (StrUtil.isEmpty(jobHandlerName)) {
log.error("[executeInternal][Job({}) 获取不到正确的 jobHandlerName({})]", executionContext.getJobDetail().getKey(), jobHandlerName);
throw new IllegalStateException(StrUtil.format("Job({}) 获取不到正确的 jobHandlerName({})",
executionContext.getJobDetail().getKey(), jobHandlerName));
}
// 3. 获得 jobHandlerParam 参数
String jobHandlerParam = getJobData(executionContext, JobDataKeyEnum.JOB_HANDLER_PARAM);
Long jobLogId = null;
Date startTime = new Date();
try {
// 记录 Job 日志(初始)
jobLogId = jobLogFrameworkService.createJobLog(jobId, jobHandlerName, jobHandlerParam);
// 执行任务
String data = this.executeInternal(jobId, jobHandlerName, jobHandlerParam);
// 标记 Job 日志(成功)
Date endTime = new Date();
jobLogFrameworkService.updateJobLogSuccessAsync(jobLogId, endTime, diff(endTime, startTime), data);
} catch (ServiceException serviceException) {
// 标记 Job 日志(异常)
Date endTime = new Date();
jobLogFrameworkService.updateJobLogErrorAsync(jobLogId, endTime, diff(endTime, startTime),
serviceException.getCode(), serviceException.getMessage());
// 最终还是抛出异常,用于停止任务
throw serviceException;
} catch (Throwable e) {
// 标记 Job 日志(异常)
Date endTime = new Date();
jobLogFrameworkService.updateJobLogErrorAsync(jobLogId, endTime, diff(endTime, startTime),
INTERNAL_SERVER_ERROR.getCode(), ExceptionUtil.getRootCauseMessage(e));
// 最终还是抛出异常,用于停止任务
throw new JobExecutionException(e);
}
}
private String executeInternal(Long jobId, String jobHandlerName, String jobHandlerParam) throws Exception {
// 获得 JobHandler 对象
JobHandler jobHandler = applicationContext.getBean(jobHandlerName, JobHandler.class);
Assert.isNull(jobHandler, "JobHandler 不会为空");
// 执行任务
String jobParam = getJobData(executionContext, JobDataKeyEnum.JOB_HANDLER_PARAM);
try {
jobHandler.execute(jobParam);
} catch (Exception e) {
// TODO 需要后续处理
CommonResult<String> result = jobHandler.execute(jobHandlerParam);
// 如果执行失败,则抛出 ServiceException 异常,方便统一记录
if (result.isError()) {
throw new ServiceException(result.getCode(), result.getMsg());
}
return result.getData();
}
private static String getJobData(JobExecutionContext executionContext, JobDataKeyEnum key) {

View File

@ -0,0 +1,43 @@
package cn.iocoder.dashboard.framework.quartz.core.service;
import java.util.Date;
/**
* Job Framework Service
*
* @author
*/
public interface JobLogFrameworkService {
/**
* Job
*
* @param jobId
* @param jobHandlerName Job
* @param jobHandlerParam Job
* @return Job
*/
Long createJobLog(Long jobId, String jobHandlerName, String jobHandlerParam);
/**
* Job
*
* @param id
* @param endTime
* @param duration
* @param data
*/
void updateJobLogSuccessAsync(Long id, Date endTime, Long duration, String data);
/**
* Job
*
* @param id
* @param endTime
* @param duration
* @param code
* @param msg
*/
void updateJobLogErrorAsync(Long id, Date endTime, Long duration, Integer code, String msg);
}

View File

@ -30,18 +30,6 @@ public class InfJobLogDO extends BaseDO {
* {@link InfJobDO#getId()}
*/
private Long jobId;
/**
*
*
* {@link InfJobDO#getName()}
*/
private String jobName;
/**
*
*
* {@link InfJobDO#getGroup()}
*/
private String jobGroup;
/**
*
*
@ -74,16 +62,11 @@ public class InfJobLogDO extends BaseDO {
*/
private Integer resultCode;
/**
*
*
*
* 使 {@link CommonResult#getMsg()}
* 使 {@link CommonResult#getData()}
* 使 {@link CommonResult#getMsg()}
*/
private String resultMsg;
/**
*
*
* 使 {@link CommonResult#getData()}
*/
private String resultData;
private String result;
}

View File

@ -18,4 +18,8 @@ public class DateUtils {
return System.currentTimeMillis() > time.getTime();
}
public static Long diff(Date endTime, Date startTime) {
return endTime.getTime() - startTime.getTime();
}
}