如何經過編碼的方式手動觸發xxl-job執行器

前言

xxl-job是一個分佈式任務調度平臺,其核心設計目標是開發迅速、學習簡單、輕量級、易擴展、開箱即用。我部門大部分定時任務調度都是基於xxl-job,諸如報表統計、定時數據同步等。
今天的素材來源於某天產品經理想在定時同步報表數據的基礎上,再增長一個手動觸發報表數據同步的功能。即在報表頁面上新增一個手動同步的按鈕,觸發該按鈕就能夠執行報表數據同步java

需求分析

一、保留定時同步功能,同時新增手動同步

二、手動同步的數據產生的效果要和定時數據同步的產生效果同樣git

解決思路

一、方案1、新建一個手動調用的controller,controller觸發數據同步邏輯service

其實就是把寫在xxl-job執行器裏面的同步邏輯,再放到controller執行一遍github

二、方案2、新建一個手動調用的controller,在controller裏面直接觸發xxl-job執行器

解決方案分析

在原先的定時器場景,咱們爲了不定時器裏面的同步邏輯還沒完成,下次定時器就觸發致使數據同步不許確,咱們在執行器裏面作一些手段進行規避,好比設置同步完成標誌位等。
若是基於方案一,方案看似可行,其實存在潛在的坑點。即定時器執行的時候,手動恰好觸發執行,或者反過來,手動觸發的時候,定時器也執行了。這樣就會致使數據同步執行屢次,致使數據不許確。spring

後面咱們調研了xxl-job,看到了xxl-job有提供restful風格觸發執行器的功能,這個功能簡直就是爲咱們量身定作,當手動調用的時候,觸發執行器,由於執行的是執行器裏面的調用邏輯,所以就會觸發咱們爲避免數據同步不許確所採起的手段springboot

如何經過restful風格手動觸發xxl-job執行器執行

其具體介紹能夠查看官網,其連接以下restful

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

本例的核心代碼塊app

@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,就是執行器裏面的調度方法。形以下dom

/**
     * 一、簡單任務示例(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

相關文章
相關標籤/搜索