springboot中@scheduled有没有开关机制

如题,我们可以在springboot中使用@scheduled注解来完成定时任务。我现在有两台机器部署同一个应用。一台希望开启这个定时器,另一台希望关闭它。请问是否可以通过配置文件的方式来决定这个定时器的开关状态。最好用application.properties实现。
另外。自己定义一个参数,在定时方法中对其判断。由于我这个方法每五分钟执行一次。所以效率不高。还是希望能从源头上停掉这个定时器

阅读 28.2k
7 个回答

试试看这个:

@Configuration
@EnableScheduling
@ConditionalOnProperty(prefix = "scheduling", name = "enabled", havingValue = "true")
public class SchedulingConfig {
}

不过最彻底的办法是把定时任务单独分一个项目出来。

没用过问主这种思路的。
但建议在业务逻辑里做开关判断。

application.properties :

task.switch = open

业务代码:

@Value("${task.switch}")
private String taskSwitch;

@scheduled
public void task(){
    if(taskSwitch.equal("close")){
        return;
    }
    //do anything
}

你这个是典型的分布式锁的问题,建议你通过redis来实现分布式锁。

新手上路,请多包涵

@ragnarrttt 说得对,这是一个分布式锁的问题。但可以用多种方式解决。
在同一个进程内部不同线程之间,可以使用锁的方式解决,比如常见的double checking singleton pattern:

if(null==info){
    synchronized (this){
        if(null==info) {
            // do something
        }
    }
}

但在多个相互独立运行的jvm实例之间,相互协调处理得使用其他的方式实现进程间的通信。
针对你的情况:可以使用共用的数据库,新增任务表保存各个实例下共有的任务状态,任务开始前,先查询任务表中该任务的执行状态和下一次执行时间,某个实例一旦开始执行该任务,即修改状态为“ing”,其他实例即不会再执行。任务执行完之后,再修改任务状态为"completed",同时刷新下一次执行时间;
另外可以使用zookeeper,添加锁来实现;或者采用诸如TBschedule这种方布式调度框架实现。

新手上路,请多包涵

我现在也遇到了这个问题,但是我要求的是我有两个定时任务,需要两个开关来控制,楼上的总开关不适合我的情况

cloud.monitor.sit.isValid=Y
cloud.monitor.uat.isValid=Y
cloud.monitor.prepord.isValid=Y
cloud.monitor.gray.isValid=Y
cloud.monitor.prod.isValid=Y

我有五个开关对应五个定时任务.如果有好办法了请联系我

我之前也有想过这种方式。我有两种思路,一种是直接更改注解字段。但是这种风险比较大,还有一种是不使用Spring的定时任务,而是用JDK原生的SchedulePoolExecutor来实现

public void robotHistoryRecord(int robotNumber) {
        if (!tasks.containsKey(RecordFunctionCode.RobotRecord)) {
            final ScheduledFuture<?> future = scheduledPool.scheduleAtFixedRate(() -> {
                final Robot robot = getRobotFromRedis(robotNumber);
                robotMapper.save(robot);
            }, 1, 1, TimeUnit.SECONDS);

            tasks.put(RecordFunctionCode.RobotRecord, future);
        } else {
            log.info("Robot Recording is going on");
        }
    }

    public void endRecording(int task) {
        final ScheduledFuture<?> taskFuture = tasks.get(task);
        // 等待取消
        taskFuture.cancel(false);
        tasks.remove(task);
    }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题