如题,我们可以在springboot中使用@scheduled注解来完成定时任务。我现在有两台机器部署同一个应用。一台希望开启这个定时器,另一台希望关闭它。请问是否可以通过配置文件的方式来决定这个定时器的开关状态。最好用application.properties实现。
另外。自己定义一个参数,在定时方法中对其判断。由于我这个方法每五分钟执行一次。所以效率不高。还是希望能从源头上停掉这个定时器
如题,我们可以在springboot中使用@scheduled注解来完成定时任务。我现在有两台机器部署同一个应用。一台希望开启这个定时器,另一台希望关闭它。请问是否可以通过配置文件的方式来决定这个定时器的开关状态。最好用application.properties实现。
另外。自己定义一个参数,在定时方法中对其判断。由于我这个方法每五分钟执行一次。所以效率不高。还是希望能从源头上停掉这个定时器
没用过问主这种思路的。
但建议在业务逻辑里做开关判断。
application.properties :
task.switch = open
业务代码:
@Value("${task.switch}")
private String taskSwitch;
@scheduled
public void task(){
if(taskSwitch.equal("close")){
return;
}
//do anything
}
@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);
}
8 回答6.5k 阅读
4 回答704 阅读✓ 已解决
2 回答3.4k 阅读
3 回答1.9k 阅读✓ 已解决
1 回答2.2k 阅读✓ 已解决
1 回答2.1k 阅读✓ 已解决
1 回答797 阅读✓ 已解决
试试看这个:
不过最彻底的办法是把定时任务单独分一个项目出来。