Spring @Scheduled注解随机延迟
Spring @Scheduled annotation random delay
我正在使用 Spring 框架中的 @Scheduled
注释来调用一个方法。但是我的设置中有多个节点,我不希望它们同时全部 运行。所以我想给初始延迟设置一个随机值来抵消它们。
import org.springframework.scheduling.annotation.Scheduled;
@Scheduled(fixedRate = 600000, initialDelay = <random number between 0 and 10 minutes> )
不幸的是,我在这里只能使用常量表达式。有没有其他办法解决这个问题?我想到了使用 Spring 表达式语言。
您可以通过Spring表达式语言配置initialDelay:
@Scheduled(fixedRate = 600000, initialDelayString = "#{ T(java.util.concurrent.ThreadLocalRandom).current().nextInt(10*60*1000) }" )
我现在没有 IDE 来测试该代码,因此您可能需要稍微调整一下。
要使初始延迟随机地介于 0 和 fixedRate
之间,试试这个:
@Scheduled(fixedDelayString = "${some.delay}", initialDelayString = "${random.int(${some.delay})}")
您将 some.delay
(但选择一个更合适的名称)定义为 10 分钟,就像 application.properties 或等效项中的 属性 一样。
some.delay = 600000
当然,如果你想偷懒和硬编码,你总是可以使用 ${random.int(600000)}
请记住,initialDelayString 仅在启动时计算一次,然后在计划作业时使用相同的值。
参见org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor#processScheduled
在此工作示例中,随机延迟将在 5 到 10 秒之间。
@Scheduled(fixedDelayString = "#{new Double((T(java.lang.Math).random() + 1) * 5000).intValue()}")
或者您可以在函数末尾添加 Thread.sleep(...)。
@Scheduled(fixedDelay = 10000)
public void replicateData() {
... do stuff ...
try {
Thread.sleep(RandomUtils.nextLong(1000, 10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
在科特林中这有效:
@Component
class MyJob {
companion object {
const val INTERVAL = 24*3600*1000L // once a day
}
@Scheduled(fixedRate = INTERVAL, initialDelayString = "${random.long($INTERVAL)}")
fun doDaily() {
...
}
}
这应该有效
@Scheduled(fixedRate = 600000, initialDelay = "#{new java.util.Random().nextInt(700)}")
通过这个简单的测试验证了它:
@Test
public void testSpEL() {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("new java.util.Random().nextInt(500)");
Integer value =(Integer) exp.getValue();
Assertions.assertThat(value).isNotNull();
}
我正在使用 Spring 框架中的 @Scheduled
注释来调用一个方法。但是我的设置中有多个节点,我不希望它们同时全部 运行。所以我想给初始延迟设置一个随机值来抵消它们。
import org.springframework.scheduling.annotation.Scheduled;
@Scheduled(fixedRate = 600000, initialDelay = <random number between 0 and 10 minutes> )
不幸的是,我在这里只能使用常量表达式。有没有其他办法解决这个问题?我想到了使用 Spring 表达式语言。
您可以通过Spring表达式语言配置initialDelay:
@Scheduled(fixedRate = 600000, initialDelayString = "#{ T(java.util.concurrent.ThreadLocalRandom).current().nextInt(10*60*1000) }" )
我现在没有 IDE 来测试该代码,因此您可能需要稍微调整一下。
要使初始延迟随机地介于 0 和 fixedRate
之间,试试这个:
@Scheduled(fixedDelayString = "${some.delay}", initialDelayString = "${random.int(${some.delay})}")
您将 some.delay
(但选择一个更合适的名称)定义为 10 分钟,就像 application.properties 或等效项中的 属性 一样。
some.delay = 600000
当然,如果你想偷懒和硬编码,你总是可以使用 ${random.int(600000)}
请记住,initialDelayString 仅在启动时计算一次,然后在计划作业时使用相同的值。
参见org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor#processScheduled
在此工作示例中,随机延迟将在 5 到 10 秒之间。
@Scheduled(fixedDelayString = "#{new Double((T(java.lang.Math).random() + 1) * 5000).intValue()}")
或者您可以在函数末尾添加 Thread.sleep(...)。
@Scheduled(fixedDelay = 10000)
public void replicateData() {
... do stuff ...
try {
Thread.sleep(RandomUtils.nextLong(1000, 10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
在科特林中这有效:
@Component
class MyJob {
companion object {
const val INTERVAL = 24*3600*1000L // once a day
}
@Scheduled(fixedRate = INTERVAL, initialDelayString = "${random.long($INTERVAL)}")
fun doDaily() {
...
}
}
这应该有效
@Scheduled(fixedRate = 600000, initialDelay = "#{new java.util.Random().nextInt(700)}")
通过这个简单的测试验证了它:
@Test
public void testSpEL() {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("new java.util.Random().nextInt(500)");
Integer value =(Integer) exp.getValue();
Assertions.assertThat(value).isNotNull();
}