nacos动态修改定时任务配置

一般springboot用的定时任务都是@Scheduled(cron = ""),这个方法固然可以实现定时任务,但是有一种局限,就是不能做统一管理配置定时任务,而且调试的时候如果修改时间,还需要重新启动服务,我在做的时候我就觉得很繁琐,所以我去网上找了很多,终于找到了几种方法,结合了一下,实现了在nacos上动态配置定时任务的方法。

syncTime: 0 0 1 * * ?

只需在nacos上配置这一句,定时任务就可以触发。

这种方法最大的好处就是不用修改代码,如果用户要求调整定时任务,也可以直接去nacos上修改,不需要在代码上修改,然后重新发包。

以下是实现的逻辑及代码(只适合用nacos配置的):

思路:

  • 实现SchedulingConfigurer方法,重写configureTasks
  • 执行scheduledTaskRegistrar.addTriggerTask();

  • 在addTriggerTask()方法里实现自己的业务逻辑(调用业务方法)

() -> {
        try {
              syncUserList();
              log.debug("定时器触发成功!");
             } catch (Exception e) {
                   throw new RuntimeException("接口调用失败");
           }
        }
  • 在addTriggerTask()实现触发器
//实现触发器逻辑
                triggerContext -> {
                    //从nacos中取动态的cron表达式
                    String cron = getSyncUserCron();//获取配置自己实现nacos方法
                    //判断nacos是否有配置cron表达式,如果没有给一个默认配置
                    if (StringUtils.isEmpty(cron)) {
                        cron = "0 0 1 * * *"; //默认配置 比如每1小时执行一次
                    }
                    //这边获取动态配置后执行 计算下次促发时间
                    CronTrigger trigger = new CronTrigger(cron);
                    return trigger.nextExecutionTime(triggerContext);
                }
  • 获取nacos上的配置文件信息,获取到时候把nacos转成对象,通过对象获取定时任务的表达式
public String getSyncUserCron() {
        Properties properties = new Properties();
//      此时ConfigService对象就知道能从哪里获取配置
        properties.put("serverAddr", nacosHost + ":" + nacosPort);
        properties.put("namespace", nacosNs);
        ConfigService configService;
        String syncTime;
        try {
            configService = NacosFactory.createConfigService(properties);
//          这一步其实就是获取配置 参数:String dataId,String group,long timeoutMs超时时间
//          获取配置的时候我们指定dataId与group之后,ConfigService就能获取到信息的配置内容
            String dataId = name + "-" + active + ".yaml";
            String contont = configService.getConfig(dataId, nacosGrup, 5000);
            Yaml yaml = new Yaml();
            Object load = yaml.load(contont);
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                syncTime = JSON.parseObject(objectMapper.writeValueAsString(load), SyncUser.class).getSyncTime();
            } catch (JsonProcessingException e) {
                throw new RuntimeException("获取nacos数据失败!");
            }
        } catch (NacosException e) {
            throw new RuntimeException(e);
        }
        return syncTime;
    }

以下是完整代码

@Component
public class SyncUserTask implements SchedulingConfigurer {

 @Value("${NACOS_NS}")
    private String nacosNs; //命名空间
    @Value("${NACOS_HOST}")
    private String nacosHost;  //IP
    @Value("${NACOS_PORT}")
    private String nacosPort;  //端口
    @Value("${spring.application.name}")
    private String name;      //Data Id  的前缀  如admin-dev中的admin
    @Value("${spring.profiles.active}")
    private String active;    //Data Id 的后缀  dev
    @Value("${NACOS_GROUP}")
    private String nacosGrup;  //Group

public void syncUserList() throws Exception {
        //业务逻辑
}

 @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        //执行任务 使用addTriggerTask 方法
        scheduledTaskRegistrar.addTriggerTask(
                //第一个方法 实现自己的调度任务业务逻辑
                () -> {
                    try {
                        syncUserList();
                        log.debug("定时器触发成功!");
                    } catch (Exception e) {
                        throw new RuntimeException("接口调用失败");
                    }
                }, //业务逻辑
                //实现触发器逻辑
                triggerContext -> {
                    //从nacos中取动态的cron表达式
                    String cron = getSyncUserCron();//获取配置自己实现nacos方法
                    //判断nacos是否有配置cron表达式,如果没有给一个默认配置
                    if (StringUtils.isEmpty(cron)) {
                        cron = "0 0 1 * * *"; //默认配置 比如每1小时执行一次
                    }
                    //这边获取动态配置后执行 计算下次促发时间
                    CronTrigger trigger = new CronTrigger(cron);
                    return trigger.nextExecutionTime(triggerContext);
                });
    }

    public String getSyncUserCron() {
        Properties properties = new Properties();
//      此时ConfigService对象就知道能从哪里获取配置
        properties.put("serverAddr", nacosHost + ":" + nacosPort);
        properties.put("namespace", nacosNs);
        ConfigService configService;
        String syncTime;
        try {
            configService = NacosFactory.createConfigService(properties);
//          这一步其实就是获取配置 参数:String dataId,String group,long timeoutMs超时时间
//          获取配置的时候我们指定dataId与group之后,ConfigService就能获取到信息的配置内容
            String dataId = name + "-" + active + ".yaml";
            String contont = configService.getConfig(dataId, nacosGrup, 5000);
            Yaml yaml = new Yaml();
            Object load = yaml.load(contont);
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                syncTime = JSON.parseObject(objectMapper.writeValueAsString(load), SyncUser.class).getSyncTime();
            } catch (JsonProcessingException e) {
                throw new RuntimeException("获取nacos数据失败!");
            }
        } catch (NacosException e) {
            throw new RuntimeException(e);
        }
        return syncTime;
    }
}

注意:

  • 一定要记得在启动类加上@EnableScheduling
  • @Value的值都是从bootstrap.yml上获取的
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值