server/dmvisit_admin/src/main/java/com/doumee/api/timer/QuartzController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,54 @@ package com.doumee.api.timer1; import com.doumee.entity.QuartzJob; import com.doumee.service.QuartzJobService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @RestController @RequestMapping("/business/quartz") @Api(tags = "宿¶ä»»å¡æ¥å£") public class QuartzController { @Resource private QuartzJobService quartzJobService ; @ApiOperation( "任塿¥è¯¢") @GetMapping("/job/{id}") public QuartzJob getById(@PathVariable Integer id){ return quartzJobService.getById(id) ; } @ApiOperation( "任塿°å¢") @PostMapping("/job") public Integer insert(@RequestBody QuartzJob quartzJob){ return quartzJobService.insert(quartzJob) ; } @ApiOperation( "æ´æ°ä»»å¡") @PostMapping("/job/update") public Integer update(@RequestBody QuartzJob quartzJob){ return quartzJobService.update(quartzJob) ; } @ApiOperation( "忢任å¡") @PostMapping("/job/pause/{id}") public void pause(@PathVariable("id") Integer id) { quartzJobService.pause(id); } @ApiOperation( "æ¢å¤ä»»å¡") @PostMapping("/job/resume/{id}") public void resume(@PathVariable("id") Integer id) { quartzJobService.resume(id) ; } @ApiOperation( "æ§è¡ä¸æ¬¡") @GetMapping("/job/runOnce/{id}") public void runOnce(@PathVariable("id") Integer id) { quartzJobService.runOnce(id) ; } } server/dmvisit_service/src/main/java/com/doumee/dao/timer/entity/JobState.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,29 @@ package com.doumee.constant; /** * @author å ¬ä¼å·:ç¥äºä¸ç¬ * @since 2023-07-26 10:05 */ public enum JobState { JOB_RUN(1, "è¿è¡"), JOB_STOP(2, "æå"), JOB_DEL(3, "å é¤"); private int status; private String desc; JobState(int status, String desc) { this.status = status; this.desc = desc; } public int getStatus() { return status; } public String getDesc() { return desc; } } server/dmvisit_service/src/main/java/com/doumee/dao/timer/entity/LogState.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,28 @@ package com.doumee.constant; /** * @author å ¬ä¼å·:ç¥äºä¸ç¬ * @since 2023-07-26 10:06 */ public enum LogState { LOG_SUS(1, "æå"), LOG_FAIL(2, "失败"); private int status; private String desc; LogState(int status, String desc) { this.status = status; this.desc = desc; } public int getStatus() { return status; } public String getDesc() { return desc; } } server/dmvisit_service/src/main/java/com/doumee/dao/timer/entity/QuartzJob.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,50 @@ package com.doumee.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.Date; /** * * @author å ¬ä¼å·:ç¥äºä¸ç¬ * @since 2023-07-26 11:04 */ @Data @NoArgsConstructor @AllArgsConstructor @Schema(description = "QuartzJobå®ä½ç±»") public class QuartzJob implements Serializable { private static final long serialVersionUID = 1L; /** * ä»»å¡è°åº¦åæ°key */ public static final String JOB_PARAM_KEY = "BOOT_JOB_PARAM_KEY"; @Schema(description = "ä»»å¡id") @TableId(value = "id",type = IdType.AUTO) private Integer id; @Schema(description = "Beanåç§°") private String beanName; @Schema(description = "æ§è¡åæ°") private String params; @Schema(description = "Cron表达å¼") private String cronExpres; @Schema(description = "ä»»å¡ç¶æï¼1æ£å¸¸ï¼2æåï¼3å é¤") private Integer state; @Schema(description = "夿³¨") private String remark; @Schema(description = "å建æ¶é´") private Date createTime; } server/dmvisit_service/src/main/java/com/doumee/dao/timer/entity/QuartzLog.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,38 @@ package com.doumee.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.Date; /** * * @author å ¬ä¼å·:ç¥äºä¸ç¬ * @since 2023-07-26 11:04 */ @Data @NoArgsConstructor @AllArgsConstructor public class QuartzLog { @TableId(value = "id",type = IdType.AUTO) private Long id; private Integer jobId; private String beanName; private String params; private Integer state; private String error; private Integer times; private Date createTime; } server/dmvisit_service/src/main/java/com/doumee/dao/timer/job/JobService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,11 @@ package com.doumee.job; /** * @author å ¬ä¼å·:ç¥äºä¸ç¬ * @since 2023-07-26 11:43 */ public interface JobService { void run(String params); } server/dmvisit_service/src/main/java/com/doumee/dao/timer/job/PrintJob.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,20 @@ package com.doumee.job; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * @author å ¬ä¼å·:ç¥äºä¸ç¬ * @since 2023-07-26 11:44 */ @Component("printJob") public class PrintJob implements JobService { private static final Logger log = LoggerFactory.getLogger(PrintJob.class); @Override public void run(String params) { log.info("\n ======== \n print-job-params:{} \n ========",params); } } server/dmvisit_service/src/main/java/com/doumee/dao/timer/job/TimerJob.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,24 @@ package com.doumee.job; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.Date; /** * @author å ¬ä¼å·:ç¥äºä¸ç¬ * @since 2023-07-26 14:51 */ @Component("timerJob") public class TimerJob implements JobService { private static final Logger log = LoggerFactory.getLogger(TimerJob.class); private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ; @Override public void run(String params) { log.info("\n ======== \n timer-job-params:{} \n ========",params); log.info("time-now:{}",format.format(new Date())); } } server/dmvisit_service/src/main/java/com/doumee/dao/timer/mapper/QuartzJobMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,10 @@ package com.doumee.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.doumee.entity.QuartzJob; import org.apache.ibatis.annotations.Mapper; @Mapper public interface QuartzJobMapper extends BaseMapper<QuartzJob> { } server/dmvisit_service/src/main/java/com/doumee/dao/timer/mapper/QuartzLogMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,10 @@ package com.doumee.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.doumee.entity.QuartzLog; import org.apache.ibatis.annotations.Mapper; @Mapper public interface QuartzLogMapper extends BaseMapper<QuartzLog> { } server/dmvisit_service/src/main/java/com/doumee/dao/timer/scheduler/QuartzManage.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,146 @@ package com.doumee.scheduler; import com.doumee.constant.JobState; import com.doumee.entity.QuartzJob; import org.quartz.*; import org.springframework.stereotype.Component; import javax.annotation.Resource; /** * 任塿ä½åºç¡å°è£ * @author å ¬ä¼å·:ç¥äºä¸ç¬ * @since 2023-07-26 14:04 */ @Component public class QuartzManage { private static final String SCHEDULE_NAME = "BOOT_JOB_" ; @Resource private Scheduler scheduler ; /** * 触åå¨ KEY */ public TriggerKey getTriggerKey(Integer jobId){ return TriggerKey.triggerKey(SCHEDULE_NAME+jobId) ; } /** * 宿¶ä»»å¡ Key */ public JobKey getJobKey (Integer jobId){ return JobKey.jobKey(SCHEDULE_NAME+jobId) ; } /** * 表达å¼è§¦åå¨ */ public org.quartz.CronTrigger getCronTrigger (Integer jobId){ try { return (CronTrigger) this.scheduler.getTrigger(getTriggerKey(jobId)) ; } catch (SchedulerException e){ throw new RuntimeException("getCronTrigger Fail",e) ; } } /** * åå»ºå®æ¶å¨ */ public void createJob (QuartzJob quartzJob){ try { // æå»ºä»»å¡ JobDetail jobDetail = JobBuilder.newJob(QuartzRecord.class) .withIdentity(getJobKey(quartzJob.getId())).build() ; // æå»ºCronè°åº¦å¨ CronScheduleBuilder scheduleBuilder = CronScheduleBuilder .cronSchedule(quartzJob.getCronExpres()) .withMisfireHandlingInstructionDoNothing() ; // ä»»å¡è§¦åå¨ org.quartz.CronTrigger trigger = TriggerBuilder.newTrigger() .withIdentity(getTriggerKey(quartzJob.getId())) .withSchedule(scheduleBuilder).build() ; jobDetail.getJobDataMap().put(QuartzJob.JOB_PARAM_KEY,quartzJob); scheduler.scheduleJob(jobDetail,trigger) ; // ç¶ææ ¡éª checkStop(quartzJob) ; } catch (SchedulerException e){ throw new RuntimeException("createJob Fail",e) ; } } /** * æ´æ°å®æ¶ä»»å¡ */ public void updateJob(QuartzJob quartzJob) { try { // æ¥è¯¢è§¦åå¨Key TriggerKey triggerKey = getTriggerKey(quartzJob.getId()); // æå»ºCronè°åº¦å¨ CronScheduleBuilder scheduleBuilder = CronScheduleBuilder .cronSchedule(quartzJob.getCronExpres()) .withMisfireHandlingInstructionDoNothing(); // ä»»å¡è§¦åå¨ org.quartz.CronTrigger trigger = getCronTrigger(quartzJob.getId()) .getTriggerBuilder().withIdentity(triggerKey) .withSchedule(scheduleBuilder).build(); trigger.getJobDataMap().put(QuartzJob.JOB_PARAM_KEY, quartzJob); scheduler.rescheduleJob(triggerKey, trigger); // ç¶ææ ¡éª checkStop(quartzJob) ; } catch (SchedulerException e) { throw new RuntimeException("updateJob Fail",e) ; } } /** * æ¢å¤å®æ¶å¨ */ public void resumeJob (Integer jobId){ try { this.scheduler.resumeJob(getJobKey(jobId)); } catch (SchedulerException e){ throw new RuntimeException("resumeJob Fail",e) ; } } /** * å é¤å®æ¶å¨ */ public void deleteJob (Integer jobId){ try { scheduler.deleteJob(getJobKey(jobId)); } catch (SchedulerException e){ throw new RuntimeException("deleteJob Fail",e) ; } } /** * æ§è¡å®æ¶å¨ */ public void run (QuartzJob quartzJob){ try { JobDataMap dataMap = new JobDataMap() ; dataMap.put(QuartzJob.JOB_PARAM_KEY,quartzJob); this.scheduler.triggerJob(getJobKey(quartzJob.getId()),dataMap); } catch (SchedulerException e){ throw new RuntimeException("run Fail",e) ; } } /** * æ ¡éªåæ¢å®æ¶å¨ */ public void checkStop (QuartzJob quartzJob){ try { if(quartzJob.getState() != JobState.JOB_RUN.getStatus()){ this.scheduler.pauseJob(getJobKey(quartzJob.getId())); } } catch (SchedulerException e){ throw new RuntimeException("pauseJob Fail",e) ; } } } server/dmvisit_service/src/main/java/com/doumee/dao/timer/scheduler/QuartzRecord.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,50 @@ package com.doumee.scheduler; import com.doumee.constant.LogState; import com.doumee.entity.QuartzJob; import com.doumee.entity.QuartzLog; import com.doumee.service.QuartzLogService; import org.quartz.JobExecutionContext; import org.springframework.scheduling.quartz.QuartzJobBean; import java.lang.reflect.Method; import java.util.Date; /** * ä»»å¡è®°å½ * @author å ¬ä¼å·:ç¥äºä¸ç¬ * @since 2023-07-26 10:21 */ public class QuartzRecord extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext context) { QuartzJob quartzJob = (QuartzJob)context.getMergedJobDataMap().get(QuartzJob.JOB_PARAM_KEY) ; QuartzLogService quartzLogService = (QuartzLogService)SpringContextUtil.getBean("quartzLogService") ; // 宿¶å¨æ¥å¿è®°å½ QuartzLog quartzLog = new QuartzLog () ; quartzLog.setJobId(quartzJob.getId()); quartzLog.setBeanName(quartzJob.getBeanName()); quartzLog.setParams(quartzJob.getParams()); quartzLog.setCreateTime(new Date()); long beginTime = System.currentTimeMillis() ; try { // å 载并æ§è¡ Object target = SpringContextUtil.getBean(quartzJob.getBeanName()); Method method = target.getClass().getDeclaredMethod("run", String.class); method.invoke(target, quartzJob.getParams()); long executeTime = System.currentTimeMillis() - beginTime; quartzLog.setTimes((int)executeTime); quartzLog.setState(LogState.LOG_SUS.getStatus()); } catch (Exception e){ // å¼å¸¸ä¿¡æ¯ long executeTime = System.currentTimeMillis() - beginTime; quartzLog.setTimes((int)executeTime); quartzLog.setState(LogState.LOG_FAIL.getStatus()); quartzLog.setError(e.getMessage()); } finally { // ä¿åæ§è¡æ¥å¿ quartzLogService.insert(quartzLog) ; } } } server/dmvisit_service/src/main/java/com/doumee/service/timer/QuartzJobService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,111 @@ package com.doumee.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.doumee.constant.JobState; import com.doumee.entity.QuartzJob; import com.doumee.mapper.QuartzJobMapper; import com.doumee.scheduler.QuartzManage; import org.quartz.CronTrigger; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.List; import java.util.Objects; /** * @author å ¬ä¼å·:ç¥äºä¸ç¬ * @since 2023-07-26 11:08 */ @Service public class QuartzJobService { @Resource private QuartzJobMapper quartzJobMapper ; @Resource private QuartzManage quartzManage; /** * åå§åå è½½å®æ¶ä»»å¡ */ @PostConstruct public void init () { LambdaQueryWrapper<QuartzJob> queryWrapper = new LambdaQueryWrapper<>() ; queryWrapper.in(QuartzJob::getState, JobState.JOB_RUN.getStatus(),JobState.JOB_STOP.getStatus()); List<QuartzJob> jobList = quartzJobMapper.selectList(queryWrapper); jobList.forEach(quartzJob -> { CronTrigger cronTrigger = quartzManage.getCronTrigger(quartzJob.getId()) ; if (Objects.isNull(cronTrigger)){ quartzManage.createJob(quartzJob); } else { quartzManage.updateJob(quartzJob); } }); } /** * ä»»å¡ä¸»é®æ¥è¯¢ */ public QuartzJob getById(Integer id) { return quartzJobMapper.selectById(id) ; } /** * æ°å¢ä»»å¡ */ public int insert(QuartzJob quartzJob) { int flag = quartzJobMapper.insert(quartzJob) ; if (flag > 0){ quartzManage.createJob(quartzJob) ; } return flag; } /** * æ´æ°ä»»å¡ */ public int update(QuartzJob quartzJob) { int flag = quartzJobMapper.updateById(quartzJob); if (flag > 0){ quartzManage.updateJob(quartzJob); } return flag ; } /** * æåä»»å¡ */ public void pause(Integer id) { QuartzJob quartzJob = quartzJobMapper.selectById(id) ; if (!Objects.isNull(quartzJob)){ quartzJob.setState(JobState.JOB_STOP.getStatus()); if (quartzJobMapper.updateById(quartzJob)>0){ quartzManage.checkStop(quartzJob); } } } /** * æ¢å¤ä»»å¡ */ public void resume(Integer id) { QuartzJob quartzJob = quartzJobMapper.selectById(id) ; if (!Objects.isNull(quartzJob)){ quartzJob.setState(JobState.JOB_RUN.getStatus()); if (quartzJobMapper.updateById(quartzJob)>0){ quartzManage.resumeJob(id); } } } /** * æ§è¡ä»»å¡ä¸æ¬¡ */ public void runOnce(Integer id) { QuartzJob quartzJob = quartzJobMapper.selectById(id) ; if (!Objects.isNull(quartzJob) && quartzJob.getState() != JobState.JOB_DEL.getStatus()){ quartzManage.run(quartzJob); } } } server/dmvisit_service/src/main/java/com/doumee/service/timer/QuartzLogService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,23 @@ package com.doumee.service; import com.doumee.entity.QuartzLog; import com.doumee.mapper.QuartzLogMapper; import org.springframework.stereotype.Service; import javax.annotation.Resource; /** * * @author å ¬ä¼å·:ç¥äºä¸ç¬ * @since 2023-07-26 11:02 */ @Service("quartzLogService") public class QuartzLogService { @Resource private QuartzLogMapper quartzLogMapper ; public Integer insert(QuartzLog quartzLog) { return quartzLogMapper.insert(quartzLog); } } server/dmvisit_service/src/main/resources/application-proHS.yml
ÎļþÒÑɾ³ý server/dmvisit_service/src/main/resources/application-testHS.yml
ÎļþÒÑɾ³ý