你如何配置spring来执行重叠的fixedRate任务?
我正尝试在java spring中使用@Scheduled注释以固定的速率执行任务。 然而,如果任务比速率慢,默认情况下,spring不会以固定速率执行fixedRate任务。 是否有一些设置可以添加到我的弹簧配置中以更改此行为?
例如 :
@Service
public class MyTask{
@Scheduled(fixedRate = 1000)
public void doIt(){
// this sometimes takes >1000ms, in which case the next execution is late
...
}
}
我有一个解决方法 ,但它似乎并不理想。 基本上,我只是用线程池替换默认的单线程执行程序,然后我有一个调度方法调用异步方法,因为@Async注释允许并发执行:
@Service
public class MyTask{
@Async
public void doIt(){
// this sometimes takes >1000ms, but the next execution is on time
...
}
}
@Service
public class MyTaskScheduler{
...
@Scheduled(fixedRate = 1000)
public void doIt(){
myTask.doIt();
}
}
@Configuration
@EnableScheduling
@EnableAsync
public class MySpringJavaConfig{
@Bean(destroyMethod = "shutdown")
public Executor taskScheduler() {
return Executors.newScheduledThreadPool(5);
}
}
无聊的细节我的实际情况 :在我的生产代码中,根据当前的工作量,我有一项任务需要10到10分钟。 理想情况下,我想每1000毫秒从池中捕获一个新线程,以使并发线程数量随着工作负载的增加而增加。 显然,我有一个线程上限(以及其他控件),以防止事情失控。
TaskScheduler
API(支持一些Spring调度行为)似乎被定义为阻止您请求的行为
计划给定的Runnable
,在指定的执行时间以及随后的给定时间段内调用它。
参数
随后并且连续似乎表明下一次执行只会在当前执行完成后才会执行。
更重要的是, ScheduledExecutorService#scheduleAtFixedRate(..)
(内置的TaskScheduler
实现使用)也表示
如果任务的执行时间比其周期长,则后续执行可能会晚点, 但不会同时执行 。
所以还有另一层实现可以防止你想要的行为。
一个可能的解决方案,我不推荐,因为API似乎并不是围绕它构建的,而是定义并提供您自己的TaskScheduler
,它可以同时运行任务。 查看@EnableScheduling
和SchedulingConfigurer
以了解如何注册TaskScheduler
。
迄今为止我发现的最佳解决方案是简单地使用委托使方法调用异步。 这是唯一可取的,因为它允许我在与工作方法相同的类中声明时间表:
@Service
public class AsyncRunner {
@Async
public void run(Runnable runnable) {
runnable.run();
}
}
@Service
public class MyTask{
...
@Scheduled(fixedRate = 1000)
public void scheduleIt(){
asyncRunner.run(this::doIt);
}
public void doIt(){
// this sometimes takes >1000ms, but the next execution is on time
...
}
}
链接地址: http://www.djcxy.com/p/85399.html
上一篇: how can you configure spring to execute overlapping fixedRate tasks?