logo

Настройка Spring Scheduler: исправляем Cron выражение

Быстрый ответ

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

В примерах ниже задача, которая запускается каждый день в 9 утра:

  • Spring cron: 0 0 9 * * ?
  • UNIX cron: 0 9 * * *

Вот как мог бы выглядеть код для планирования выполнения задачи в Spring:

Java
Скопировать код
@Scheduled(cron = "0 0 9 * * ?") // Для этой задачи могло бы быть задание приготовить кофе ☕
public void dailyTask() {
    // Тут реализация задачи
}

В отличии от Spring cron, который понимает контекст приложения и вполне соответствует требованиям Java-разработчиков, UNIX cron представляет собой инструмент для планирования задач на уровне операционной системы.

Spring и Unix cron: разбираемся в полях

Шаблоны Spring cron состоят из шести полей, в то время как шаблоны Unix cron содержат только пять полей. Важно понять различия между ними.

Например, Spring cron: 0 15 10 * * 1-5 задает время 10:15 утра с понедельника по пятницу.

А UNIX cron: 15 10 * * 1-5 также задает это время, однако без привязки к секундах.

Важная особенность: в шаблонах Spring cron необходимо указывать ноль в поле секунд, и не стоит забывать, что Spring не поддерживает включение в шаблоны седьмого поля – 'год'. Это устаревшая практика! 💁‍♀️

Форматирование выражений cron

Spring cron прекрасно распознает алиасы для дней недели, например, "0 0 18 MON-FRI", которые можно использовать как эквивалент "0 0 18 1-5".

Однако есть несколько особенностей Spring cron:

  • Использование поля 'год' в ваших выражениях Spring cron может привести к сбою приложения в виде исключения.
  • Если вам требуется правильно настроить Spring cron, обращайтесь к справочной документации, в том числе к CronSequenceGenerator. Этот документ местами может показаться скучным, но он поможет вам в работе.
  • Будьте расчетливы при использовании онлайн-инструментов для создания cron-выражений: они имеют тенденцию к неверной интерпретации синтаксиса Spring cron.

Визуализация

Markdown
Скопировать код
🌱 Spring Cron: 
| Элемент синтаксиса     | Поддержка спецсимволов       |
|-----------------------|------------------------------|
| Секунды               | Да (Диапазон: 0-59)          |
| Минуты                | Да (Диапазон: 0-59)          |
| Часы                  | Да (Диапазон: 0-23)          |
| День месяца           | Да (Диапазон: 1-31)          |
| Месяц                 | Да (1-12 или JAN-DEC)        |
| День недели           | Да (0-7 или SUN-SAT)         |
| Год                   | Стандарт не учитывает (лучше избегать)|
Markdown
Скопировать код
🕒 Обычный Cron: 
| Элемент синтаксиса     | Поддержка спецсимволов       |
|-----------------------|------------------------------|
| Минуты                | Да (Диапазон: 0-59)          |
| Часы                  | Да (Диапазон: 0-23)          |
| День месяца           | Да (Диапазон: 1-31)          |
| Месяц                 | Да (1-12 или JAN-DEC)        |
| День недели           | Да (0-7 или SUN-SAT)         |

Применение cron в реальной практике

Теперь, вооружившись знаниями о различиях, рассмотрим практические примеры использования cron.

  1. Задачи каждый час

    • Spring cron: "0 0 */1 * * *" – Задача выполнится каждый час ровно.
    • UNIX cron: "0 */1 * * *" – Задача также выполнится каждый час, но без привязки к секундам.
  2. Первое воскресенье месяца

    • Spring cron: "0 0 0 ? * SUN#1" – Задача выполнится в полночь каждое первое воскресенье месяца.
    • UNIX cron: Не поддерживает такое выражение.
  3. Каждые 8 часов

    • Spring cron: "0 0 */8 * * *" – Задача запускается в 00:00, 08:00 и 16:00.
    • UNIX cron: "0 */8 * * *" – Тоже самое, но без учета секунд.

В каждом примере Spring cron показывает большую гибкость в планировании, что позволяет создавать более сложные расписания.

Полезные материалы