Spring @Scheduled注释随机延迟

时间:2015-01-09 21:48:32

标签: spring spring-annotations spring-scheduled

我使用Spring框架中的@Scheduled注释来调用方法。但是我的设置中有多个节点,我不希望它们全部在同一时间运行。因此,我希望将一个随机值设置为初始延迟,以使它们相互抵消。

import org.springframework.scheduling.annotation.Scheduled;

@Scheduled(fixedRate = 600000, initialDelay = <random number between 0 and 10 minutes> )

不幸的是,我只允许在这里使用常量表达式。还有其他方法吗?我想过使用Spring表达式语言。

7 个答案:

答案 0 :(得分:10)

要使初始延迟在0和fixedRate之间的某个位置随机尝试:

@Scheduled(fixedDelayString = "${some.delay}", initialDelayString = "${random.int(${some.delay})}")

您在application.properties或同等属性中定义some.delay(但选择一个更合适的名称)为10分钟作为属性的位置。

some.delay = 600000

当然,如果您想要懒惰并且硬编码,您可以随时使用${random.int(600000)}

答案 1 :(得分:6)

您可以通过Spring Expression Language配置initialDelay:

@Scheduled(fixedRate = 600000, initialDelayString = "#{ T(java.util.concurrent.ThreadLocalRandom).current().nextInt(10*60*1000) }" )

我现在没有IDE来测试该代码,因此您可能需要稍微调整一下。

答案 2 :(得分:2)

请记住,initialDelayString仅在启动时评估一次,并且只要在安排作业时使用相同的值。

请参阅org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor#processScheduled

答案 3 :(得分:2)

在这个工作示例中,随机延迟将在5到10秒之间。

@Scheduled(fixedDelayString = "#{new Double((T(java.lang.Math).random() + 1) * 5000).intValue()}")

答案 4 :(得分:0)

在科特林,这可行:

@Component
class MyJob {
   companion object {
      const val INTERVAL = 24*3600*1000L // once a day
   }

   @Scheduled(fixedRate = INTERVAL, initialDelayString = "\${random.long($INTERVAL)}")
   fun doDaily() {
      ...
   }
}

答案 5 :(得分:0)

这应该有效

       $(document).ready(function () {
            $('[data-toggle="tooltip"]').tooltip({
                trigger: 'hover click focus',
                boundary: 'window'
            })
        });

通过以下简单测试对其进行验证:

@Scheduled(fixedRate = 600000, initialDelay = "#{new java.util.Random().nextInt(700)}")

答案 6 :(得分:-4)

或者您可以在函数末尾添加Thread.sleep(...)。

@Scheduled(fixedDelay = 10000)
public void replicateData() {

    ... do stuff ...

    try {
        Thread.sleep(RandomUtils.nextLong(1000, 10000));
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}