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

    Робота з базами даних у Spring: порівнюємо JDBC, Hibernate та Spring Data JPA

    Робота з базами даних — одна з найважливіших складових практично будь-якого backend-застосунку. Spring пропонує кілька рівнів абстракції для доступу до даних: низькорівневий Spring JDBC, потужний ORM-фреймворк Hibernate та зручну надбудову Spring Data JPA. Розглянемо, чим вони відрізняються, коли варто обирати кожен з них. 1. Spring JDBC Spring JDBC — це тонка обгортка над стандартним java.sql, яка усуває бойлерплейт-код: ручне відкриття/закриття з’єднань, обробку виключень, керування транзакціями. Основний інструмент — клас JdbcTemplate: Переваги: Недоліки: Spring JDBC…

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

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

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

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

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

    Цікаве

    Garbage Collection: Як працює сміттевоз в Java

    • Автор javaadmin
    • 13 Серпня, 2026
    • 123 views
    Garbage Collection: Як працює сміттевоз в Java

    Робота з базами даних у Spring: порівнюємо JDBC, Hibernate та Spring Data JPA

    • Автор javaadmin
    • 6 Серпня, 2026
    • 133 views
    Робота з базами даних у Spring: порівнюємо JDBC, Hibernate та Spring Data JPA

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

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

    Java Collections Framework: List, Set чи Map?

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

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

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

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

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