mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 04:08:43 +08:00 
			
		
		
		
	完善 JobHandlerInvoker 的执行,记录 Job 执行日志
This commit is contained in:
		@@ -1,39 +1,103 @@
 | 
				
			|||||||
package cn.iocoder.dashboard.framework.quartz.core.handler;
 | 
					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.enums.JobDataKeyEnum;
 | 
				
			||||||
 | 
					import cn.iocoder.dashboard.framework.quartz.core.service.JobLogFrameworkService;
 | 
				
			||||||
 | 
					import lombok.extern.slf4j.Slf4j;
 | 
				
			||||||
import org.quartz.DisallowConcurrentExecution;
 | 
					import org.quartz.DisallowConcurrentExecution;
 | 
				
			||||||
import org.quartz.JobExecutionContext;
 | 
					import org.quartz.JobExecutionContext;
 | 
				
			||||||
 | 
					import org.quartz.JobExecutionException;
 | 
				
			||||||
import org.quartz.PersistJobDataAfterExecution;
 | 
					import org.quartz.PersistJobDataAfterExecution;
 | 
				
			||||||
import org.springframework.context.ApplicationContext;
 | 
					import org.springframework.context.ApplicationContext;
 | 
				
			||||||
import org.springframework.scheduling.quartz.QuartzJobBean;
 | 
					import org.springframework.scheduling.quartz.QuartzJobBean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.annotation.Resource;
 | 
					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)} 执行任务
 | 
					 * 基础 Job 调用者,负责调用 {@link JobHandler#execute(String)} 执行任务
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @author 芋道源码
 | 
					 * @author 芋道源码
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@PersistJobDataAfterExecution
 | 
					 | 
				
			||||||
@DisallowConcurrentExecution
 | 
					@DisallowConcurrentExecution
 | 
				
			||||||
 | 
					@PersistJobDataAfterExecution
 | 
				
			||||||
 | 
					@Slf4j
 | 
				
			||||||
public class JobHandlerInvoker extends QuartzJobBean {
 | 
					public class JobHandlerInvoker extends QuartzJobBean {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Resource
 | 
					    @Resource
 | 
				
			||||||
    private ApplicationContext applicationContext;
 | 
					    private ApplicationContext applicationContext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Resource
 | 
				
			||||||
 | 
					    private JobLogFrameworkService jobLogFrameworkService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    protected void executeInternal(JobExecutionContext executionContext) {
 | 
					    protected void executeInternal(JobExecutionContext executionContext) throws JobExecutionException {
 | 
				
			||||||
        // 获得 JobHandler 对象
 | 
					        // 获得 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);
 | 
					        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);
 | 
					        JobHandler jobHandler = applicationContext.getBean(jobHandlerName, JobHandler.class);
 | 
				
			||||||
 | 
					        Assert.isNull(jobHandler, "JobHandler 不会为空");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // 执行任务
 | 
					        // 执行任务
 | 
				
			||||||
        String jobParam = getJobData(executionContext, JobDataKeyEnum.JOB_HANDLER_PARAM);
 | 
					        CommonResult<String> result = jobHandler.execute(jobHandlerParam);
 | 
				
			||||||
        try {
 | 
					        // 如果执行失败,则抛出 ServiceException 异常,方便统一记录
 | 
				
			||||||
            jobHandler.execute(jobParam);
 | 
					        if (result.isError()) {
 | 
				
			||||||
        } catch (Exception e) {
 | 
					            throw new ServiceException(result.getCode(), result.getMsg());
 | 
				
			||||||
            // TODO 需要后续处理
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        return result.getData();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static String getJobData(JobExecutionContext executionContext, JobDataKeyEnum key) {
 | 
					    private static String getJobData(JobExecutionContext executionContext, JobDataKeyEnum key) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -30,18 +30,6 @@ public class InfJobLogDO extends BaseDO {
 | 
				
			|||||||
     * 关联 {@link InfJobDO#getId()}
 | 
					     * 关联 {@link InfJobDO#getId()}
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private Long jobId;
 | 
					    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;
 | 
					    private Integer resultCode;
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 结果提示
 | 
					     * 结果
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * 目前使用的 {@link CommonResult#getMsg()} 属性
 | 
					     * 成功时,使用 {@link CommonResult#getData()} 数据
 | 
				
			||||||
 | 
					     * 失败时,使用 {@link CommonResult#getMsg()} 属性
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private String resultMsg;
 | 
					    private String result;
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 结果数据
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * 目前使用的 {@link CommonResult#getData()} 数据
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private String resultData;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,4 +18,8 @@ public class DateUtils {
 | 
				
			|||||||
        return System.currentTimeMillis() > time.getTime();
 | 
					        return System.currentTimeMillis() > time.getTime();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static Long diff(Date endTime, Date startTime) {
 | 
				
			||||||
 | 
					        return endTime.getTime() - startTime.getTime();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user