document.write("");

scheduling 动态定时任务

不用nacos的@RefreshScope,是因为使用@RefreshScope后,定时任务会重复执行,查了一些资料后,了解到RefreshScope不能用到Scheduling之类的定时任务中,Scope的数据刷新可能会导致重复创建实例,

所以不使用nacos动态调整参数,而是读取DB,可以将其简单修改成获取Redis里的数据,这样可以避免DB性能压力

PS:

如果只有一个自定义刷新定时规则的定时任务,可以使用如下示例中的 setTriggerTasksList

如果为多个,需调整为 (使用追加方式,避免多个自定义定时规则相互覆盖导致只有一个生效)

taskRegistrar.addTriggerTask(new TriggerTask(task, this::nextExecutionTime));

 

示例如下,

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.config.TriggerTask;
import org.springframework.scheduling.support.CronTrigger;

import java.util.Collections;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

@Slf4j
@Configuration
@EnableScheduling
public class ProductScheduleJob implements SchedulingConfigurer {

    @Autowired
    private XXXMapper xxxMapper;

    private final AtomicBoolean isRun = new AtomicBoolean(true);
    private final AtomicReference<String> cornExpression = new AtomicReference<>("* 0/1 * * * ?");

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        Runnable task = () -> {
            if (isRun.get()) {
                synchronizeTest();
            }
        };

        // 动态更新任务
        taskRegistrar.setTriggerTasksList(Collections.singletonList(
                new TriggerTask(task, this::nextExecutionTime)
        ));
    }

    private void synchronizeTest() {
        log.info("------测试------ {}", isRun.get());
    }

    private Date nextExecutionTime(TriggerContext triggerContext) {
        String name = "XXX";
        XXXParameter parameter = xxxMapper.selectOne(new LambdaQueryWrapper<XXXParameter>().eq(XXXParameter::getXXX, name));

        // 更新 corn 表达式
        if (Objects.nonNull(name)) {
            String newCorn = name.getData();
            if (!cornExpression.get().equals(newCorn)) {
                log.info("Updating corn expression from {} to {}", cornExpression.get(), newCorn);
                cornExpression.set(newCorn);
                isRun.set(true);
            }
        } else {
            isRun.set(false);
        }

        log.info("{}--------------nextExecutionTime-------------- {}", isRun.get() ? "run" : "not run", cornExpression.get());
        CronTrigger cronTrigger = new CronTrigger(cornExpression.get());
        return cronTrigger.nextExecutionTime(triggerContext);
    }
}

  

posted @ 2025-03-05 09:54  人间春风意  阅读(23)  评论(0)    收藏  举报