elastic-job 分佈式定時任務框架 在 SpringBoot 中如何使用(二)動態添加任務需求

以前一篇用過了如何在使用建立最簡單的任務:好比天天定時清空系統的緩存java

這篇文章主要講解:如何運用elastic-job-lite作靈活的細粒度任務,好比:web

如何定時取消某個訂單在下訂單後30分鐘未支付的訂單,並改變訂單狀態?spring

如何讓某個用戶在得到7天體驗會員在七天後改變這個會員的會員狀態?express

某個用戶想定時發佈一篇文章?apache

如何給某個會員在生日當天發送一條祝福短信?api

 

elastic-job-lite 就能實現這樣的需求……緩存

 主要是任務配置,任務執行類都是同樣的,下面貼出了demo,僅限於單應用節點時,主要爲了實現如何動態的配置任務參數並達到上述需求,方法應用比較簡單restful

 首先要有任務(做業)類,並交給spring管理類app

/*
 * Copyright 1999-2015 dangdang.com.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * </p>
 */

package com.dianji.task_server.job.exec;

import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;

@Slf4j
@Component
public class OrderExpireJob implements SimpleJob {
    @Value("${serverFlag}")
    private String serverFlag;

    @Override
    public void execute(final ShardingContext shardingContext) {
        int shardingItem = shardingContext.getShardingItem();
        String jobName = shardingContext.getJobName();
        String jobParameter = shardingContext.getJobParameter();
        String logRule = "「執行訂單超時任務」任務名:{0},訂單號:{1},任務分片索引:{2},服務進程「{3}」";
        String logStr = MessageFormat.format(logRule, jobName, jobParameter, shardingItem, serverFlag);
        log.info(logStr);
    }
}
任務了demo代碼

 

接着就是任務(做業)配置了less

package com.dianji.task_server.job.config;

import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.event.JobEventConfiguration;
import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration;
import com.dangdang.ddframe.job.lite.spring.api.SpringJobScheduler;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
import com.dianji.task_server.job.exec.OrderExpireJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 動態添加任務配置
 *
 * @author szliugx@gmail.com
 * @create 2018-10-25 下午5:16
 **/
@Slf4j
@Component
public class DynamicAddJobConfig {
    @Autowired
    private ZookeeperRegistryCenter regCenter;

    @Autowired
    private JobEventConfiguration jobEventConfiguration;

    public void dynamicAddSimpleJobScheduler(SimpleJob simpleJob, String jobName, String jobParameter, String cron,
                                             int shardingTotalCount, String shardingItemParameters) {
        new SpringJobScheduler(
                simpleJob,
                regCenter,
                getLiteJobConfiguration(
                        jobName,
                        jobParameter,
                        OrderExpireJob.class,
                        cron,
                        shardingTotalCount,
                        shardingItemParameters),
                jobEventConfiguration).init();
    }

    /**
     * 任務配置
     *
     * @param jobName
     * @param jobParameter
     * @param jobClass
     * @param cron
     * @param shardingTotalCount
     * @param shardingItemParameters
     * @return
     */
    private LiteJobConfiguration getLiteJobConfiguration(
            final String jobName,
            final String jobParameter,
            final Class<? extends SimpleJob> jobClass,
            final String cron,
            final int shardingTotalCount,
            final String shardingItemParameters) {
        return LiteJobConfiguration.newBuilder(
                new SimpleJobConfiguration(
                        JobCoreConfiguration.newBuilder(
                                jobName,
                                cron,
                                shardingTotalCount
                        ).shardingItemParameters(shardingItemParameters).jobParameter(jobParameter).build(),
                        jobClass.getCanonicalName()
                )
        ).overwrite(true).build();
    }
}
做業配置代碼

 

最後,主動觸發任務添加,這裏用了一個restful API 的URL來請求 測試 「讓某個訂單1分鐘後執行過時做業」  任務添加

package com.dianji.task_server.web.controller;

import com.dianji.task_server.job.config.DynamicAddJobConfig;
import com.dianji.task_server.job.exec.OrderExpireJob;
import com.dianji.task_server.util.ResultUtils;
import com.dianji.task_server.web.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 測試控制器
 *
 * @author szliugx@gmail.com
 * @create 2018-10-17 上午9:46
 **/
@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {
    @Autowired
    DynamicAddJobConfig dynamicAddJobConfig;

    @Autowired
    private OrderExpireJob orderExpireJob;

    @GetMapping("/addTask")
    public Result addTask(HttpServletRequest request) {
        Date date = new Date(); // 當前時間
        String orderNo = String.valueOf(date.hashCode()); // 訂單號
        String jobName = "OrderExpireJob-" + orderNo; // 任務名稱(不能重複,否則容易覆蓋掉)
        Date expireTime = addMin(date, 1); // 測試時,1分鐘便可
        String cron = testGetCron(expireTime); // 獲得cron表達式
        String jobParameter = orderNo; // 將訂單號做爲參數
        int shardingTotalCount = 1; // 分片總數
        String shardingItemParameters = "0=a"; // 分片參數
        dynamicAddJobConfig.dynamicAddSimpleJobScheduler(orderExpireJob, jobName, jobParameter, cron,
                shardingTotalCount, shardingItemParameters);
        log.info("「添加訂單超時任務」,任務名{},訂單號{}", jobName, jobParameter);
        return ResultUtils.success();
    }

    /**
     * 僅測試使用方法,日期轉cron表達式
     *
     * @param date 待處理日期
     * @return
     */
    private String testGetCron(java.util.Date date) {
        String dateFormat = "ss mm HH dd MM ? yyyy";
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        String formatTimeStr = "";
        if (date != null) {
            formatTimeStr = sdf.format(date);
        }
        return formatTimeStr;
    }

    /**
     * 僅測試使用方法,給指定的日期添加分鐘
     *
     * @param oldDate 須要處理日期
     * @param number  添加的分鐘數
     * @return
     */
    private Date addMin(Date oldDate, int number) {

        Calendar c = Calendar.getInstance();
        c.setTime(oldDate);
        c.add(Calendar.MINUTE, number);// 添加分鐘

        return c.getTime();
    }
}
測試添加代碼

 

應用跑起來後,訪問 /test/addTask 查看日誌結果:

 

 

 

做業維護後臺,能看見執行的這些 訂單過時任務

相關文章
相關標籤/搜索