SchedLock: Ефективне управління завданнями у багатопоточних системах

Spring надає простий спосіб реалізації API для планування завдань. Він працює чудово, доки ми не розгортаємо декілька екземплярів нашого додатку. Spring, за замовчуванням, не може обробляти синхронізацію планувальника між декількома екземплярами. Замість цього, він виконує завдання одночасно на кожному вузлі. У цьому короткому матеріалі ми розглянемо ShedLock, бібліотеку Java, яка гарантує, що наші заплановані завдання будуть виконуватися тільки один раз в один і той же час, і є альтернативою Quartz.

У сучасному світі розробники програмного забезпечення стикаються з викликами, пов’язаними з багатопоточним програмуванням. Одним із таких викликів є синхронізація доступу до критичних секцій коду, щоб уникнути непередбачених поведінок, таких як гонки станів (race conditions) чи мертві блокування (deadlocks). У цьому контексті бібліотека ShedLock стала важливим інструментом для управління завданнями, які виконуються у розподілених системах або багатопоточному середовищі.

Що таке SchedLock?

SchedLock (або ShedLock) — це бібліотека, яка забезпечує механізм блокування для задач, що виконуються за розкладом (scheduled tasks). Її основною метою є гарантування того, що лише один екземпляр завдання буде виконано у будь-який момент часу навіть у випадку розподіленого середовища, де є кілька вузлів (серверів).

Цей інструмент особливо корисний для систем, у яких розкладені завдання (наприклад, обробка черг або регулярні підрахунки) виконуються у кластері серверів. Наприклад, ви можете мати кілька серверів у різних регіонах, і, в ідеалі, одна із нод має виконати завдання, щоб уникнути дублювання.

Як працює SchedLock?

SchedLock використовує механізм “локів” (захоплення блокувань) через загальний зовнішній ресурс, наприклад, базу даних, Redis або інші сховища. Деякі особливості роботи ShedLock:

  1. Ініціалізація та встановлення блокування: Коли задача розпочинається, ShedLock намагається отримати блокування через механізм, наприклад, запис у базу даних з унікальним ідентифікатором.
  2. Перевірка наявності блокування: Якщо блокування вже існує, інша задача або інший вузол не має права виконувати завдання.
  3. Звільнення блокування: Після завершення завдання ShedLock скасовує блокування, що дозволяє іншим процесам виконувати задачу.

Таким чином, ShedLock гарантує, що одна й та сама задача буде виконуватись лише один раз у заданий момент часу.

Ключові особливості ShedLock

  1. Розподілене середовище: ShedLock працює у багатосерверному середовищі, відслідковуючи виконання задач через загальний ресурс, такий як база даних чи Redis.
  2. Висока адаптивність: ShedLock підтримує різні типи сховищ для блокувань, такі як SQL-бази (MySQL, PostgreSQL) або NoSQL-рішення (MongoDB, Redis).
  3. Проста імплементація: Інтеграція ShedLock у проект досить проста і не потребує значного переписування існуючого коду.

Переваги використання ShedLock

  1. Запобігання дублюванню: Гарантія, що задача виконується лише один екземпляр незалежно від кількості серверів.
  2. Стабільність і надійність: ShedLock знижує ймовірність помилок, пов’язаних із некоректним виконанням задач у багатонодових середовищах.
  3. Гнучкість налаштувань: Розробник може налаштувати час блокування, період оновлення блокування, таймаути та інші параметри.

Як інтегрувати SchedLock у Spring Boot проект?

Щоб використовувати ShedLock з Spring, нам потрібно додати залежність shedlock-spring:

<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-spring</artifactId>
    <version>${shedlock_version}</version>
</dependency>
<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-provider-jdbc-template</artifactId>
    <version>${shedlock_version}</version>
</dependency>
XML

Інтеграція ShedLock у проект на базі Spring Boot є досить прямолінійною. Розглянемо основні кроки:

  • Додати залежність у pom.xml 
  • Налаштувати базу даних для блокування: Використовуйте SQL, щоб створити таблицю для управління блокуваннями:
CREATE TABLE shedlock( name VARCHAR(64) NOT NULL, lock_until TIMESTAMP(3) NOT NULL, locked_at TIMESTAMP(3) NOT NULL, locked_by VARCHAR(255) NOT NULL, PRIMARY KEY (name) );
SQL
  • Налаштувати конфігурацію ShedLock: У створеній конфігурації вкажіть використання бази даних для управління блокуваннями.
@Configuration
public class ShedLockConfig {
    @Bean
    public JdbcTemplateLockProvider lockProvider(DataSource dataSource) {
        return new JdbcTemplateLockProvider(
            JdbcTemplateLockProvider.Configuration.builder()
                .withJdbcTemplate(new JdbcTemplate(dataSource))
                .usingDbTime() // Використовуємо системний час бази даних
                .build()
        );
    }
}
Java
  • Додати розкладені задачі зі ShedLock: 

Позначте задачі за допомогою анотації @SchedulerLock, яка гарантує, що задача виконується лише один раз якщо наприклад у вас є группа однакових мікросервісів.

@Component
public class ScheduledTasks {

    @Scheduled(cron = "0 */5 * * * *") // Виконується кожні 5 хвилин
    @SchedulerLock(name = "TaskName", lockAtLeastFor = "PT4M", lockAtMostFor = "PT5M")
    public void performScheduledTask() {
        // Ваш код тут
        System.out.println("Executing scheduled task...");
    }
}
Java

Практичні кейси використання ShedLock

  1. Обробка платіжних транзакцій: Якщо кілька серверів обробляють чергу платежів, ShedLock допоможе уникнути дублювання операцій.
  2. Очистка архівів: Для періодичного очищення архівів або логів з бази даних варто переконатися, що завдання виконується лише один раз у кластері.
  3. Синхронізація даних: ShedLock ідеально підходить для завдань, пов’язаних із синхронізацією даних із зовнішніх API чи систем.

Заключення

SchedLock — це потужний інструмент для розробників, які працюють із багатопоточними або розподіленими системами. Його використання дозволяє уникнути дублювання обробки задач та забезпечує стабільність програмного забезпечення. Простота інтеграції, масштабовність та адаптивність роблять ShedLock ідеальним вибором для роботи з розкладеними завданнями в сучасних додатках.

  • javaadmin

    Супер крутий Dev

    Related Posts

    Dependency Injection у Spring: пояснюємо на пальцях

    Коли програміст-початківець вперше відкриває документацію до Spring Framework, на нього одразу висипається купа грізних термінів: Dependency Injection (DI), Inversion of Control (IoC), ApplicationContext, Bean. Здається, що це вища математика. Ми вже розглядали DI в минулих матеріалах але цю дуже не просту тему краще розібрати по болтиках для повного розуміння. Насправді за цими розумними словами ховається надзвичайно проста та красива ідея. Це історія про те, як перестати збирати складні речі вручну й довірити…

    Dependency Injection в Java

    Dependency Injection (впровадження залежностей) — один з фундаментальних патернів проектування в сучасній Java-розробці. Цей принцип допомагає створювати гнучкі, тестовані та підтримувані додатки. Давайте розберемося, що це таке і як правильно його застосовувати. Що таке Dependency Injection? Dependency Injection — це техніка, при якій об’єкт отримує свої залежності ззовні, а не створює їх самостійно. Замість того, щоб клас сам інстанціював потрібні йому об’єкти, вони передаються йому через конструктор, setter-методи…

    Коментарі “SchedLock: Ефективне управління завданнями у багатопоточних системах

    Залишити відповідь

    Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *

    Цікаве

    Dependency Injection у Spring: пояснюємо на пальцях

    • Автор javaadmin
    • 31 Липня, 2026
    • 15 views
    Dependency Injection у Spring: пояснюємо на пальцях

    Java Collections Framework: List, Set чи Map?

    • Автор javaadmin
    • 31 Липня, 2026
    • 29 views
    Java Collections Framework: List, Set чи Map?

    Оптимізуємо це: GraalVM Native Image, Leyden та CRaC

    • Автор javaadmin
    • 17 Липня, 2026
    • 57 views
    Оптимізуємо це: GraalVM Native Image, Leyden та CRaC

    JBang: Як вивчати Java легко

    • Автор javaadmin
    • 12 Травня, 2026
    • 130 views
    JBang: Як вивчати Java легко

    Agent Skills: Що це таке і чому про це варто знати

    • Автор javaadmin
    • 13 Квітня, 2026
    • 233 views
    Agent Skills: Що це таке і чому про це варто знати

    Dependency Injection в Java

    • Автор javaadmin
    • 9 Грудня, 2025
    • 407 views
    Dependency Injection в Java