nidapeng
2024-04-20 51a208c7715ecfea9faeccd5ee56ed2d0a697c95
工作调度
已添加14个文件
已删除2个文件
766 ■■■■ 文件已修改
server/dmvisit_admin/src/main/java/com/doumee/api/timer/QuartzController.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/java/com/doumee/dao/timer/entity/JobState.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/java/com/doumee/dao/timer/entity/LogState.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/java/com/doumee/dao/timer/entity/QuartzJob.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/java/com/doumee/dao/timer/entity/QuartzLog.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/java/com/doumee/dao/timer/job/JobService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/java/com/doumee/dao/timer/job/PrintJob.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/java/com/doumee/dao/timer/job/TimerJob.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/java/com/doumee/dao/timer/mapper/QuartzJobMapper.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/java/com/doumee/dao/timer/mapper/QuartzLogMapper.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/java/com/doumee/dao/timer/scheduler/QuartzManage.java 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/java/com/doumee/dao/timer/scheduler/QuartzRecord.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/java/com/doumee/service/timer/QuartzJobService.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/java/com/doumee/service/timer/QuartzLogService.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/resources/application-proHS.yml 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/dmvisit_service/src/main/resources/application-testHS.yml 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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
ÎļþÒÑɾ³ý