栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

nacos+定时任务动态配置 @Scheduled定时器

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

nacos+定时任务动态配置 @Scheduled定时器

maven 依赖添加   该依赖可以动态监听nacos配置文件修改

com.purgeteam
dynamic-config-spring-boot-starter
0.1.1.RELEASE
启动类加注解 @EnableDynamicConfigEvent nacos + 定时任务时间 实现动态配置 添加以下文件 : AbstractDynamicSchedule.java NacosCronDataIdChangeListener.java TestSchedule.java TestSchedule 内有三个方法: taskName() :定时任务名。 cronKey() : nacos 配置 run() : 里面写定时任务的逻辑
package cn.witsky.qydx.project.test;


public interface AbstractDynamicSchedule extends Runnable {

    
    String taskName();

    
    String cronKey();

}

package cn.witsky.qydx.project.business.manager;

import cn.witsky.qydx.project.test.AbstractDynamicSchedule;
import com.google.common.collect.Lists;
import com.purgeteam.dynamic.config.starter.event.ActionConfigEvent;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
import org.springframework.scheduling.config.CronTask;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;


@Component
@Slf4j
public class NacosCronDataIdChangeListener implements ApplicationListener, SchedulingConfigurer {

    private ScheduledTaskRegistrar taskRegistrar;
    private static final ConcurrentHashMap> SCHEDULED_FUTURES = new ConcurrentHashMap<>();
    private static final ConcurrentHashMap CRON_TASKS = new ConcurrentHashMap<>();
    @Resource
    private ApplicationContext applicationContext;
    
    @Resource
    private Map scheduleMap;

    @Override
    public void onApplicationEvent(ActionConfigEvent  event) {

        Collection editCronScheduleMap = Lists.newArrayList();
        // 对比每一个配置
        scheduleMap.keySet().forEach(schedule -> {
            AbstractDynamicSchedule bean = (AbstractDynamicSchedule) applicationContext.getBean(schedule);
            String cronKey = bean.cronKey();
            CronTask cronTask = CRON_TASKS.get(cronKey);
            if (Objects.isNull(cronTask)) {
                // 新增
                editCronScheduleMap.add(scheduleMap.get(schedule));
                return;
            }
            if(event.getPropertyMap()==null||event.getPropertyMap().get(cronKey)==null){
                return;
            }
            String oldCronValue = cronTask.getExpression();
            String newCronValue = (String) event.getPropertyMap().get(cronKey).get("after");

            if (Objects.equals(oldCronValue, newCronValue)) {
                log.info("task time not change , cronKey={}, oldCronValue={}", cronKey, oldCronValue);
                return;
            }

            // 发生了变化
            editCronScheduleMap.add(scheduleMap.get(schedule));
        });

        this.refreshTasks(editCronScheduleMap);

    }

    public void refreshTasks(Collection tasks) {

        tasks.forEach(schedule -> {

            String cronKey = schedule.cronKey();

            // 取消已经删除的策略任务
            if ("-".equals(cronKey) || StringUtils.isBlank(cronKey)) {
                cancel(cronKey);
                log.info("取消已经删除的策略任务, taskName={}, cronKey={}", schedule.taskName(), schedule.cronKey());
                return;
            }

            String cronNewValue = applicationContext.getEnvironment().getProperty(cronKey);

            // 新的值为取消定时任务
            if ("-".equals(cronNewValue) || StringUtils.isBlank(cronNewValue)) {
                cancel(cronKey);
                log.info("定时任务关闭, taskName={}, cronKey={}", schedule.taskName(), schedule.cronKey());
                return;
            }

            // 定时任务没有发生任何变化
            if (SCHEDULED_FUTURES.containsKey(cronKey) && CRON_TASKS.get(cronKey).getExpression().equals(cronNewValue)) {
                log.info("定时任务没有发生任何变化, taskName={}, cronKey={}", schedule.taskName(), schedule.cronKey());
                return;
            }

            // 如果策略执行时间发生了变化,则取消当前策略的任务
            boolean isUpdate = SCHEDULED_FUTURES.containsKey(cronKey) && cancel(cronKey);

            CronTask task = new CronTask(schedule, cronNewValue);
            CRON_TASKS.put(cronKey, task);
            ScheduledFuture future = Optional.ofNullable(taskRegistrar.getScheduler())
                    .orElse(new ConcurrentTaskScheduler()).schedule(task.getRunnable(), task.getTrigger());
            SCHEDULED_FUTURES.put(cronKey, future);

            if (isUpdate) {
                log.info("定时任务修改, taskName={}, cronKey={}, taskNewCron={}",
                        schedule.taskName(), cronKey, cronNewValue);
            } else {
                log.info("定时任务新增, taskName={}, cronKey={}, taskCron={}",
                        schedule.taskName(), cronKey, cronNewValue);
            }

        });

    }

    private boolean cancel(String cronKey) {
        ScheduledFuture future = SCHEDULED_FUTURES.get(cronKey);
        if (Objects.nonNull(future)) {
            SCHEDULED_FUTURES.get(cronKey).cancel(false);
        }
        SCHEDULED_FUTURES.remove(cronKey);
        CRON_TASKS.remove(cronKey);
        return true;
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {

        this.taskRegistrar = taskRegistrar;

        this.refreshTasks(scheduleMap.values());

    }

}

package cn.witsky.qydx.project.test;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Date;


@Slf4j
@Component
public class TestSchedule implements AbstractDynamicSchedule {

    @Override
    public String taskName() {
        return "测试定时任务";
    }

    @Override
    public String cronKey() {
        return "test-dynamic-schedule";
    }

    @Override
    public void run() {
        log.debug(new Date() + "----1");
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/825472.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号