zoukankan      html  css  js  c++  java
  • 如何通过编码的方式手动触发xxl-job执行器

    前言

    xxl-job是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展、开箱即用。我部门大部分定时任务调度都是基于xxl-job,诸如报表统计、定时数据同步等。
    今天的素材来源于某天产品经理想在定时同步报表数据的基础上,再增加一个手动触发报表数据同步的功能。即在报表页面上新增一个手动同步的按钮,触发该按钮就可以执行报表数据同步

    需求分析

    1、保留定时同步功能,同时新增手动同步

    2、手动同步的数据产生的效果要和定时数据同步的产生效果一样

    解决思路

    1、方案一、新建一个手动调用的controller,controller触发数据同步逻辑service

    其实就是把写在xxl-job执行器里面的同步逻辑,再放到controller执行一遍

    2、方案二、新建一个手动调用的controller,在controller里面直接触发xxl-job执行器

    解决方案分析

    在原先的定时器场景,我们为了避免定时器里面的同步逻辑还没完成,下次定时器就触发导致数据同步不准确,我们在执行器里面做一些手段进行规避,比如设置同步完成标志位等。
    如果基于方案一,方案看似可行,其实存在潜在的坑点。即定时器执行的时候,手动刚好触发执行,或者反过来,手动触发的时候,定时器也执行了。这样就会导致数据同步执行多次,导致数据不准确。

    后面我们调研了xxl-job,看到了xxl-job有提供restful风格触发执行器的功能,这个功能简直就是为我们量身定做,当手动调用的时候,触发执行器,因为执行的是执行器里面的调用逻辑,因此就会触发我们为避免数据同步不准确所采取的手段

    如何通过restful风格手动触发xxl-job执行器执行

    其具体介绍可以查看官网,其链接如下

    https://www.xuxueli.com/xxl-job/#6.2 执行器 RESTful API

    本例的核心代码块

    @RestController
    @RequestMapping(value = "xxl-job")
    @Api(tags = "xxl-job restful调度")
    @Profile("job")
    @Slf4j
    public class XxlJobController {
    
        @Autowired
        private XxljobClientHelper xxljobClientHelper;
    
        @ApiOperation(value = "手动触发任务")
        @GetMapping("/run")
        public AjaxResult execute(){
            String adminClientAddressUrl = xxljobClientHelper.getAdminClientAddressUrl();
            String accessToken = xxljobClientHelper.getAccessToken();
            log.info("adminClientAddressUrl:{},accessToken:{}", adminClientAddressUrl,accessToken);
            ExecutorBiz executorBiz = new ExecutorBizClient(adminClientAddressUrl, accessToken);
            ReturnT<String> retval = executorBiz.run(getTriggerParam());
            log.info("retval:{}", JSON.toJSONString(retval));
             // 200 表示正常、其他失败
            if(retval.getCode() == 200){
                return AjaxResult.success();
            }
            return AjaxResult.error(retval.getMsg(),retval.getCode());
        }
    
        private TriggerParam getTriggerParam(){
            TriggerParam triggerParam = new TriggerParam();
            // 任务ID
    //        triggerParam.setJobId(15);
            // 任务标识
            triggerParam.setExecutorHandler("demoJobHandler");
            // 任务参数
            triggerParam.setExecutorParams("手动触发任务");
            // 任务阻塞策略,可选值参考 com.xxl.job.core.enums.ExecutorBlockStrategyEnum
            triggerParam.setExecutorBlockStrategy(ExecutorBlockStrategyEnum.COVER_EARLY.name());
            // 任务模式,可选值参考 com.xxl.job.core.glue.GlueTypeEnum
            triggerParam.setGlueType(GlueTypeEnum.BEAN.name());
            // GLUE脚本代码
            triggerParam.setGlueSource(null);
            // GLUE脚本更新时间,用于判定脚本是否变更以及是否需要刷新
            triggerParam.setGlueUpdatetime(System.currentTimeMillis());
            // 本次调度日志ID
            triggerParam.setLogId(triggerParam.getJobId());
            // 本次调度日志时间
            triggerParam.setLogDateTime(System.currentTimeMillis());
            return triggerParam;
    
        }
    }
    
    

    注: 代码中的demoJobHandler,就是执行器里面的调度方法。形如下

      /**
         * 1、简单任务示例(Bean模式)
         */
        @XxlJob("demoJobHandler")
        public ReturnT<String> demoJobHandler(String param) throws Exception {
            XxlJobLogger.log("XXL-JOB, Hello World.");
            System.out.println("======================param:"+param+"================================随机数:"+new Random().nextInt(1000));
            return ReturnT.SUCCESS;
        }
    

    总结

    如果选用方案一,也不是不行,就还得做一些改造,比如增加全局标志位,而且在设置标志位的时候,还要考虑并发场景下,可能出现的问题。因此还不如直接采用方案二。方案的选择一定得要基于业务场景进行考量,不基于业务场景,谈技术方案,很容易采坑

    demo链接

    https://github.com/lyb-geek/springboot-learning/tree/master/springboot-xxl-job-executor

  • 相关阅读:
    art-template学习(一)之特性和安装
    Velocity学习(四)之判断是否为空以及为什么要使用{}来明确标识变量
    Velocity学习(三)之 ${} 和$!{}、!${}区别
    sqlcode、sqlerrm
    批量删除存储过程
    cursor 与refcursor及sys_refcursor的区别 (转载)
    分享最近写的几个存储过程
    中国人寿数据库死锁处理
    合理计划 dictionary cache 大小
    表空间、数据文件对应关系
  • 原文地址:https://www.cnblogs.com/linyb-geek/p/14479152.html
Copyright © 2011-2022 走看看