大鹏任务调度

大鹏任务调度

1.原理

    利用反射查找被标注的任务类,调起quartz提交任务处理并处理.

2.使用

    注意:实际使用时需要定义thrift文件生成接口或特质
    若想只在一个实例中执行可以用
    MasterHelper.isMasterisMaster(String servieName, String versionName)
    判断当前实例是master.
    
    /**
     * 特质声明
     **/
    trait SyncGoodsTaskService {
        def handle():Unit;
    }
    
    /**
     * 在类上使用注解@ScheduledTask 标注此服务类定时任务.   
     **/
    @ScheduledTask
    class SimpleSyncGoodsTaskService extends SyncGoodsTaskService{

        /**
         * 定义定时任务执行时间.
         */
        @ScheduledTaskCron(cron = "0 0 0 * * ?")
        override def handle(): Unit = {
            
        }
    }


    interface SomeTaskService{
        void dealBill();
    }
    
    /**
     * 标注此服务为任务处理服务.
     **/
    @ScheduledTask
    public class SimpleSomeTaskService extends SomeTaskService{
        
        /**
         * 定义 CRON 表达式.
         **/
        @ScheduledTaskCron(cron="0 30 0 0 0 0 ?")
        public void dealBill(){
            //...下载帐单
        }
    }

3.分析

    public class TaskSchedulePlugin implements AppListener, Plugin {
    
        
        private static final Logger LOGGER = LoggerFactory.getLogger("container.scheduled.task");
    
        private final Container container;
    
        private Scheduler scheduler = null;
    
        public TaskSchedulePlugin(Container container) {
            this.container = container;
            container.registerAppListener(this);
        }
    
        @Override
        public void appRegistered(AppEvent event) {
            LOGGER.warn(getClass().getSimpleName() + "::appRegistered, event[" + event.getSource() + "], do nothing here");
        }
    
        /**
         * 应用停止时,停止任务调度
         **/
        @Override
        public void appUnRegistered(AppEvent event) {
            LOGGER.warn(getClass().getSimpleName() + "::appUnRegistered, event[" + event.getSource() + "]");
            stop();
        }
    
        /**
         * 注册所有任务调度
         **/
        @Override
        public void start() {
            LOGGER.warn("Plugin::" + getClass().getSimpleName() + "::start");
            container.getApplications().forEach(application -> {
                List<ServiceInfo> serviceInfos = application.getServiceInfos().stream()
                        .filter(serviceInfo ->
                                serviceInfo.ifaceClass.isAnnotationPresent(ScheduledTask.class))
                        .collect(Collectors.toList());
                serviceInfos.forEach(serviceInfo -> runTask(serviceInfo));
            });
        }
    
        @Override
        public void stop() {
            LOGGER.warn("Plugin::TaskSchedulePlugin stop");
            try {
                if (scheduler != null) {
                    if (scheduler.isInStandbyMode() || !scheduler.isStarted()) {
                        LOGGER.info(" start to shutdown scheduler: " + scheduler.getSchedulerName());
                        scheduler.shutdown();
                    }
                }
            } catch (SchedulerException e) {
                LOGGER.error(" Failed to shutdown scheduler: " + e.getMessage(), e);
            }
        }
    
        public void runTask(ServiceInfo serviceInfo) {
            Class<?> ifaceClass = serviceInfo.ifaceClass;
    
            Map<ProcessorKey, SoaServiceDefinition<?>> processorMap = ContainerFactory.getContainer().getServiceProcessors();
    
            List<Method> taskMethods = Arrays.stream(ifaceClass.getMethods()).filter(method -> method.isAnnotationPresent(ScheduledTaskCron.class))
                    .collect(Collectors.toList());
    
            SoaServiceDefinition soaServiceDefinition = processorMap.get(new ProcessorKey(serviceInfo.serviceName,
                    serviceInfo.version));
    
            if (soaServiceDefinition == null) {
                LOGGER.error(" SoaServiceDefinition Not found....serviceName: {}, version: {} ", serviceInfo.serviceName, serviceInfo.version);
                return;
            }
    
            taskMethods.forEach(method -> {
                String methodName = method.getName();
    
                ScheduledTaskCron cron = method.getAnnotation(ScheduledTaskCron.class);
                String cronStr = cron.cron();
    
                //new quartz job
                JobDataMap jobDataMap = new JobDataMap();
                jobDataMap.put("function", soaServiceDefinition.functions.get(methodName));
                jobDataMap.put("iface", soaServiceDefinition.iface);
                jobDataMap.put("serviceName", serviceInfo.serviceName);
                jobDataMap.put("versionName", serviceInfo.version);
                JobDetail job = JobBuilder.newJob(ScheduledJob.class)
                        .withIdentity(ifaceClass.getName() + ":" + methodName)
                        .setJobData(jobDataMap)
                        .build();
    
                CronTriggerImpl trigger = new CronTriggerImpl();
                trigger.setName(job.getKey().getName());
                trigger.setJobKey(job.getKey());
                try {
                    trigger.setCronExpression(cronStr);
                } catch (ParseException e) {
                    LOGGER.error("定时任务({}:{})Cron解析出错", ifaceClass.getName(), methodName);
                    LOGGER.error(e.getMessage(), e);
                    return;
                }
    
                if (scheduler == null) {
                    try {
                        scheduler = StdSchedulerFactory.getDefaultScheduler();
                        scheduler.start();
                    } catch (SchedulerException e) {
                        LOGGER.error("ScheduledTaskContainer启动失败");
                        LOGGER.error(e.getMessage(), e);
                        return;
                    }
                }
                try {
                    scheduler.scheduleJob(job, trigger);
                } catch (SchedulerException e) {
                    LOGGER.error(" Failed to scheduleJob....job: " + job.getKey().getName() + ", reason:" + e.getMessage(),
                            e);
                    return;
                }
                LOGGER.info("添加定时任务({}:{})成功", ifaceClass.getName(), methodName);
            });
        }
    }
posted @ 2018-08-28 10:40  冰冰与铛铛  阅读(208)  评论(0编辑  收藏  举报