Вопрос проверяет понимание механизмов координации задач в распределённых системах, в частности, для предотвращения параллельного выполнения одного и того же отложенного задания (scheduled task) на нескольких инстансах приложения.
ShedLock решает проблему, возникающую при горизонтальном масштабировании приложений, использующих планировщики задач (например, Spring's @Scheduled). Когда запущено несколько инстансов одного приложения, каждый из них будет выполнять одну и ту же запланированную задачу, что приводит к дублированию операций, конфликтам и потенциальной порче данных. Библиотека обеспечивает координацию через механизм распределённых блокировок.
Основная идея — использовать общее хранилище (базу данных, Redis, ZooKeeper) для записи факта владения блокировкой. Каждая задача имеет уникальное имя (lock name). Алгоритм работы:
Рассмотрим простой пример настройки и использования ShedLock с Spring Boot и базой данных.
// 1. Добавление зависимостей в pom.xml
// (spring-boot-starter, shedlock-spring, shedlock-provider-jdbc-template)
// 2. Конфигурация Spring-бина для ShedLock
@Configuration
@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "10m")
public class ShedLockConfig {
@Bean
public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(dataSource);
}
}
// 3. Создание таблицы для блокировок в БД (например, для MySQL)
// CREATE TABLE shedlock(
// name VARCHAR(64) PRIMARY KEY,
// lock_until TIMESTAMP NULL,
// locked_at TIMESTAMP NULL,
// locked_by VARCHAR(255)
// );
// 4. Использование в сервисе с задачей
@Component
public class ScheduledTasks {
@Scheduled(cron = "0 */5 * * * *") // каждые 5 минут
@SchedulerLock(name = "reportGenerationTask", lockAtMostFor = "5m", lockAtLeastFor = "1m")
public void generateReport() {
// Эта задача будет выполнена только на одном инстансе в кластере
System.out.println("Generating report at " + new Date());
// ... логика задачи
}
}ShedLock применяется в микросервисных и распределённых архитектурах, где несколько экземпляров сервиса выполняют периодические фоновые задачи: отправка сводок по email, агрегация метрик, очистка устаревших данных, синхронизация с внешними системами. Она проста в настройке и не требует запуска отдельного сервиса-координатора (как, например, Quartz в кластерном режиме).
Вывод: ShedLock стоит применять, когда у вас есть Spring-приложение с запланированными задачами, которое развёрнуто в нескольких экземплярах для отказоустойчивости или масштабирования, и вам необходимо гарантировать идемпотентное выполнение этих задач без дублирования.