mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-30 01:38:43 +08:00 
			
		
		
		
	完善 JobHandlerInvoker 的执行,记录 Job 执行日志
This commit is contained in:
		| @@ -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) { | ||||
|   | ||||
| @@ -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()} | ||||
|      */ | ||||
|     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; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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(); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV