2015-01-09 2 views
7

Я использую аннотацию @Scheduled из фреймворка Spring для вызова метода. Но у меня есть несколько узлов в моей настройке, и я не хочу, чтобы все они запускались точно в одно и то же время. Поэтому я хотел бы установить случайное значение для начальной задержки, чтобы компенсировать их друг от друга.Spring @Scheduled аннотация случайная задержка

import org.springframework.scheduling.annotation.Scheduled; 

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

К сожалению, мне разрешено использовать постоянное выражение здесь. Есть ли другой способ обойти это? Я думал об использовании языка выражения Spring.

ответ

4

Вы можете настроить initialDelay через Spring Expression Language:

@Scheduled(fixedRate = 600000, initialDelayString = #{ T(java.lang.Math).random() * 10 }) 

не имеют IDE, чтобы проверить, что код прямо сейчас, так что вам, возможно, придется адаптироваться, что немного.

+1

Не должны ли команды SpEl быть в строках? Я только видел, что они используются в строковых значениях. Это, к сожалению, ожидает большой ценности. Я пробовал его без кавычек и имел нерешенные проблемы компиляции. Я попробовал его как строку, и планировщик никогда не вызывался, но никаких сообщений об ошибках. – masstroy

+0

Вы заметили использование 'initialDelayString' вместо' initialDelay'? Последний занимает длинную, первую строку, которая может быть выражением. –

+0

Пример не совсем подходит. Во-первых, это должно быть указано или компилятор будет жаловаться. Но даже тогда все, что я получаю, равно null. Есть ли какая-то конфигурация, которую мне нужно сделать? – girgen

6

Чтобы сделать начальную задержку случайно где-то между 0 и fixedRate попробовать это:

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

Где вы определяете some.delay (но выбрать более подходящее название), как 10 минут, как свойство, как это в вашем приложении. свойства или эквивалент.

some.delay = 600000 

Конечно, если вы хотите быть ленивым и жесткий код это вы всегда можете просто использовать ${random.int(600000)}

+0

Просто хотел добавить этот альтернативный ответ, поскольку «правильный» ответ не очень полезен, но эта страница высоко в результатах поиска. – mekazu

1

Имейте в виду, что initialDelayString вычисляется только один раз при запуске и чем это те же значения используется всякий раз, задание запланировано.

См org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor # processScheduled

+0

Знаете ли вы, что планировщик не только имеет постоянное случайное значение, оцениваемое при запуске, но и случайное значение между каждым запуском? – yglodt

1

В этом рабочем примере случайная задержка будет находиться в диапазоне от 5 до 10 секунд.

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

Или вы можете просто добавить Thread.sleep (...) в конце своей функции.

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

    ... do stuff ... 

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

Это должно быть случайная задержка в начале функции. И нужно будет сделать код, чтобы сделать эту задержку только в первый раз. Это может сработать, но, вероятно, немного неуклюже – masstroy

+0

Вы не хотите затягивать поток, чтобы ждать. – Dan

Смежные вопросы