elastic-job 分布式定时任务框架 在 SpringBoot 中如何使用(二)动态添加任务需求

之前一篇用过了如何在使用创建最简单的任务:比如每天定时清空系统的缓存

这篇文章主要讲解:如何运用elastic-job-lite做灵活的细粒度任务,比如:

如何定时取消某个订单在下订单后30分钟未支付的订单,并改变订单状态?

如何让某个用户在获得7天体验会员在七天后改变这个会员的会员状态?

某个用户想定时发布一篇文章?

如何给某个会员在生日当天发送一条祝福短信?

 

elastic-job-lite 就能实现这样的需求……

 主要是任务配置,任务执行类都是一样的,下面贴出了demo,仅限于单应用节点时,主要为了实现如何动态的配置任务参数并达到上述需求,方法应用比较简单

 首先要有任务(作业)类,并交给spring管理类

/*
 * 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代码

 

接着就是任务(作业)配置了

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 查看日志结果:

 

 

 

作业维护后台,能看见执行的这些 订单过期任务

 

posted @ 2018-10-26 14:54  liugx  阅读(2618)  评论(1编辑  收藏  举报