调度中心集群参考

  1. 总体思路
  • 利用kafka单播模式:开启一个定时任务
  • 利用kafka广播模式:关闭某个定时任务
  1. 实现代码
  • WcsTimerManager类

     package com.isoftstone.hig.wmsck.adapters.jd.common.timermanager;
     
     import com.alibaba.fastjson.JSONObject;
     import com.isoftstone.hig.common.constants.KafkaConstant;
     import com.isoftstone.hig.common.model.MQEvent;
     import com.isoftstone.hig.common.model.ResultMode;
     import com.isoftstone.hig.common.utils.*;
     import com.isoftstone.hig.wmsck.adapters.jd.api.param.timermanager.TimerTaskParam;
     import com.isoftstone.hig.wmsck.adapters.jd.api.param.timermanager.WcsTimerTaskEnum;
     import com.isoftstone.hig.wmsck.adapters.jd.common.kafka.KafkaClientManager;
     import org.quartz.CronExpression;
     import org.springframework.beans.factory.annotation.Autowired;
     import org.springframework.context.annotation.Bean;
     import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
     import org.springframework.scheduling.support.CronTrigger;
     import org.springframework.stereotype.Component;
     
     import javax.validation.constraints.NotNull;
     import java.util.Date;
     import java.util.HashMap;
     import java.util.Map;
     import java.util.concurrent.ScheduledFuture;
     
     @Component
     public class WcsTimerManager {
     
         private ScheduledFuture future;
     
         private static Map map = new HashMap<>();
     
         @Autowired
         private TimerTask timerTask;
     
         @Autowired
         private ThreadPoolTaskScheduler threadPoolTaskScheduler;
     
         @Bean
         public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
             return new ThreadPoolTaskScheduler();
         }
     
         /**
          * 开启定时器
          */
         public ResultMode startTask(TimerTaskParam timerTask) {
             ResultMode resultMode = new ResultMode();
             try {
                 if (PublicUtil.isEmpty(timerTask.getTaskNameNo())){
                     resultMode.setSucceed(false);
                     resultMode.setErrMsg("任务名称编号不能为空");
                     return resultMode;
                 }
                 if (PublicUtil.isEmpty(timerTask.getTimeCycle())){
                     resultMode.setSucceed(false);
                     resultMode.setErrMsg("任务时间周期不能为空");
                     return resultMode;
                 }
                 if (PublicUtil.isEmpty(timerTask.getTimeType())){
                     resultMode.setSucceed(false);
                     resultMode.setErrMsg("cron表达式类型不能为空");
                     return resultMode;
                 }
                 //获取cron表达式
                 String cronTrigger = this.getCron(timerTask);
                 //校验cron表达式是否合法
                 if (!CronExpression.isValidExpression(cronTrigger)){
                     LogHelper.writeInfo("cron表达式非法!");
                     resultMode.setSucceed(false);
                     resultMode.setErrMsg("cron表达式非法!");
                     return resultMode;
                 }
                 //如果存在Redis标识
                 if (RedisUtil.hexists("future",timerTask.getTaskNameNo())){
                     //判断任务是否关闭,已关闭=true
                     boolean bool = Boolean.valueOf(RedisUtil.hget("future",timerTask.getTaskNameNo()));
                     //如果未关闭,等待其关闭
                     if (!bool){
                         //先关闭上个任务,开启新的任务!!!
                         this.stopTask(timerTask);
                         LogHelper.writeInfo("先关闭上个任务,开启新的任务!!!");
     
                         //如果值为:false-未关闭,一直等待其关闭
                         while (!Boolean.valueOf(RedisUtil.hget("future",timerTask.getTaskNameNo()))){
                             Thread.sleep(1000);
                             LogHelper.writeWarn("休眠1秒!");
                         }
                     }
                 }
                 ExecuteTimerTask executeTimerTask = new ExecuteTimerTask();
                 //任务名称编号
                 executeTimerTask.setTaskNameNo(timerTask.getTaskNameNo());
                 //入参对象
                 executeTimerTask.setData(timerTask.getData());
                 future = threadPoolTaskScheduler.schedule(executeTimerTask,new CronTrigger(cronTrigger));
                 //放入map中,停止任务时需要释放对应的任务
                 map.put(timerTask.getTaskNameNo(),future);
                 //写入标识到Redis
                 long result = RedisUtil.hset("future",timerTask.getTaskNameNo(), "false");
                 LogHelper.writeInfo("Redis标识改为false-未关闭:"+result);
                 LogHelper.writeInfo("策略已经启动");
                 resultMode.setErrMsg("策略已经启动!");
             } catch (Exception e) {
                 LogHelper.writeError("策略启动失败{}", e);
                 resultMode.setSucceed(false);
                 resultMode.setErrMsg("策略启动失败!");
             }
             return resultMode;
         }
     
         /**
          * 关闭定时器-发送kafka消息
          */
         public ResultMode stopTask(TimerTaskParam timerTask) {
             ResultMode resultMode = new ResultMode();
             try {
     
                 if (PublicUtil.isEmpty(timerTask.getTaskNameNo())) {
                     resultMode.setSucceed(false);
                     resultMode.setErrMsg("任务名称编号不能为空");
                     return resultMode;
                 }
                 //发布kafka
                 MQEvent mqEvent = new MQEvent<>(UtilityClass.uuid(), KafkaConstant.EVENT_WCS_TIMER_MANAGER, timerTask);
                 String topic = SpringContextUtil.getKafkaTopicPrefix() + UtilityEnum.KafkaTopicNameEnum.TOPIC_WMSCK_JDA_TIMER_MANAGER.getTopicName();
                 LogHelper.writeInfo("生产消息:" + JSONObject.toJSONString(mqEvent));
                 KafkaClientManager.sendMessage(topic, null, JSONObject.toJSONString(mqEvent));
                 resultMode.setErrMsg("策略关闭请求发送成功");
             }catch (Exception e){
                 LogHelper.writeError("策略关闭失败{}", e);
                 resultMode.setSucceed(false);
                 resultMode.setErrMsg("策略关闭失败!");
             }
             return resultMode;
         }
     
         /**
          * 关闭定时器-消费kafka消息
          */
         public void stopTimerManager(MQEvent mqEvent) {
             LogHelper.writeInfo("定时器,监听测试---------" + JSONObject.toJSONString(mqEvent));
             LogHelper.writeInfo("消费消息:" + JSONObject.toJSONString(mqEvent));
             TimerTaskParam timerTask = JSONObject.parseObject(JSONObject.toJSONString(mqEvent.getData()), TimerTaskParam.class);
             //关闭定时器
             if (!this.stop(timerTask).getSucceed()){
                 LogHelper.writeInfo("关闭定时器失败!");
             }
             LogHelper.writeInfo("关闭定时器成功!");
         }
         //关闭定时任务
         private ResultMode stop(TimerTaskParam timerTask) {
             ResultMode resultMode = new ResultMode();
             try {
                 if (future != null) {
                     future=map.get(timerTask.getTaskNameNo());
                     future.cancel(true);
                     LogHelper.writeInfo("future:"+future);
                 }
                 //Redis标识改为true-已关闭
                 long result = RedisUtil.hset("future",timerTask.getTaskNameNo(),"true");
                 LogHelper.writeInfo("Redis标识改为true-已关闭:"+result);
     
                 LogHelper.writeInfo("策略已经停止");
                 resultMode.setErrMsg("策略已经停止");
                 return resultMode;
             } catch (Exception e) {
                 LogHelper.writeError("策略停止失败{}", e);
                 resultMode.setSucceed(false);
                 resultMode.setErrMsg("策略停止失败!");
                 return resultMode;
     
             }
         }
     
         //获取cron表达式
         private String getCron(TimerTaskParam timerTask){
             //间隔时间或cron表达式
             String time = timerTask.getTimeCycle();
             //按秒执行
             if (WcsTimerTaskEnum.TimerTypeEnum.WCS_TimerType_10.getCode().equals(timerTask.getTimeType())){
                 return "0/"+time+" * * * * ?";
             }
             //按分钟执行
             if (WcsTimerTaskEnum.TimerTypeEnum.WCS_TimerType_20.getCode().equals(timerTask.getTimeType())){
                 return "0 0/"+time+" * * * ?";
             }
             //按小时执行
             if (WcsTimerTaskEnum.TimerTypeEnum.WCS_TimerType_30.getCode().equals(timerTask.getTimeType())){
                 return "0 0 0/"+time+" * * ?";
             }
             //自定义时间cron表达式
             return time;
         }
     
         //执行任务
         private class ExecuteTimerTask implements Runnable{
     
             /**
              * 任务名称编号
              */
             @NotNull(message = "任务名称编号不能为空")
             private String taskNameNo;
     
             /**
              * 入参对象
              */
             private Object data;
     
     
             public String getTaskNameNo() {
                 return taskNameNo;
             }
     
             public void setTaskNameNo(String taskNameNo) {
                 this.taskNameNo = taskNameNo;
             }
     
             public Object getData() {
                 return data;
             }
     
             public void setData(Object data) {
                 this.data = data;
             }
     
             @Override
             public void run() {
                 if (this.taskNameNo.equals(WcsTimerTaskEnum.TimerTaskEnum.WCS_TIMER_TASK_10.getCode())) {
                     LogHelper.writeInfo("定时生成设备摘果单-启动中:" + new Date());
                     //定时生成设备摘果单
                     timerTask.buildPickingTask(this.data);
                 } else {
                     LogHelper.writeInfo("待定任务-我在启动中:" + new Date());
                 }
     
             }
         }
     
     }
     
    
  • TimerTask类

    package com.isoftstone.hig.wmsck.adapters.jd.common.timermanager;
    
    import com.alibaba.fastjson.JSON;
    import com.isoftstone.hig.common.model.ResultMode;
    import com.isoftstone.hig.wmsck.adapters.jd.client.WcsLocalCallServiceBusiness;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    //定时任务类
    @Service
    public class TimerTask {
    
        @Autowired
        private WcsLocalCallServiceBusiness wcsLocalCallServiceBusiness;
    
        /**
         * 自动生成设备摘果单
         */
        public ResultMode buildPickingTask(Object data){
            //LogHelper.writeInfo("入参:"+JSON.toJSONString(data));
            String warehouseNo = JSON.parseObject(JSON.toJSONString(data),String.class);
            //生成设备摘果单
            return wcsLocalCallServiceBusiness.buildPickingTask(warehouseNo);
        }
    
    }
    
    
  • TimerTaskParam类

    package com.isoftstone.hig.wmsck.adapters.jd.api.param.timermanager;
    
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    
    import java.io.Serializable;
    
    @ApiModel("定时器入参")
    public class TimerTaskParam implements Serializable {
    
        private static final long serialVersionUID = 2168115660376016205L;
    
        /**
         * 任务名称编号
         */
        @ApiModelProperty(value = "任务名称编号", name ="taskNameNo")
        private String taskNameNo;
    
        /**
         * 任务时间周期或cron表达式
         */
        @ApiModelProperty(value = "任务时间周期或cron表达式", name ="timeCycle")
        private String timeCycle;
    
        /**
         * cron表达式类型:参考WcsTimerTaskEnum.TimerTypeEnum枚举类型
         */
        @ApiModelProperty(value = "cron表达式类型", name ="timeType")
        private String timeType;
    
        /**
         * 入参对象
         */
        private Object data;
    
        public String getTaskNameNo() {
            return taskNameNo;
        }
    
        public void setTaskNameNo(String taskNameNo) {
            this.taskNameNo = taskNameNo;
        }
    
        public String getTimeCycle() {
            return timeCycle;
        }
    
        public void setTimeCycle(String timeCycle) {
            this.timeCycle = timeCycle;
        }
    
        public String getTimeType() {
            return timeType;
        }
    
        public void setTimeType(String timeType) {
            this.timeType = timeType;
        }
    
        public Object getData() {
            return data;
        }
    
        public void setData(Object data) {
            this.data = data;
        }
    }
    
    
  • WcsTimerTaskEnum

    package com.isoftstone.hig.wmsck.adapters.jd.api.param.timermanager;
    
    public class WcsTimerTaskEnum {
    
        /**
         * 定时任务列表枚举类
         */
        public enum TimerTaskEnum {
    
            WCS_TIMER_TASK_10("10", "定时生成设备摘果单"),
            WCS_TIMER_TASK_20("20", "待定");
    
            private String code;
    
            private String desc;
    
            public String getCode() {
                return code;
            }
    
            public String getDesc() {
                return desc;
            }
    
            private TimerTaskEnum(String code, String desc) {
                this.code = code;
                this.desc = desc;
            }
        }
    
        /**
         * cron表达式类型
         */
        public enum TimerTypeEnum {
    
            WCS_TimerType_10("10", "秒"),
            WCS_TimerType_20("20", "分钟"),
            WCS_TimerType_30("30", "小时"),
            WCS_TimerType_40("40", "自定义cron表达式");
    
            private String code;
    
            private String desc;
    
            public String getCode() {
                return code;
            }
    
            public String getDesc() {
                return desc;
            }
    
            private TimerTypeEnum(String code, String desc) {
                this.code = code;
                this.desc = desc;
            }
        }
    
    }
    
    

你可能感兴趣的:(调度中心集群参考)