Guida a ShedLock con la primavera

1. Panoramica

Spring fornisce un'API di facile implementazione per la pianificazione dei lavori. Funziona alla grande finché non distribuiamo più istanze della nostra applicazione. Spring, per impostazione predefinita, non è in grado di gestire la sincronizzazione dello scheduler su più istanze: esegue invece i lavori simultaneamente su ogni nodo.

In questo breve tutorial, esamineremo ShedLock, una libreria Java che garantisce che le nostre attività pianificate vengano eseguite solo una volta alla stessa volta ed è un'alternativa a Quartz.

2. Dipendenze di Maven

Per utilizzare ShedLock con Spring, dobbiamo aggiungerela dipendenza shedlock-primavera :

 net.javacrumbs.shedlock shedlock-spring 2.2.0 

3. Configurazione

Notare che ShedLock funziona solo in ambienti con un database condiviso dichiarando un LockProvider appropriato . Crea una tabella o un documento nel database in cui memorizza le informazioni sui blocchi correnti.

Attualmente, ShedLock supporta Mongo, Redis, Hazelcast, ZooKeeper e qualsiasi cosa con un driver JDBC.

Per questo esempio, useremo un database H2 in memoria. Per farlo funzionare, dobbiamo fornire il database H2 e la dipendenza JDBC di ShedLock:

 net.javacrumbs.shedlock shedlock-provider-jdbc-template 2.1.0   com.h2database h2 1.4.200 

Successivamente, dobbiamo creare una tabella di database per ShedLock per conservare le informazioni sui blocchi dello scheduler:

CREATE TABLE shedlock ( name VARCHAR(64), lock_until TIMESTAMP(3) NULL, locked_at TIMESTAMP(3) NULL, locked_by VARCHAR(255), PRIMARY KEY (name) )

Dobbiamo dichiarare l'origine dati nel file delle proprietà della nostra applicazione Spring Boot in modo che il bean DataSource possa essere cablato automaticamente . In questo esempio, utilizziamo application.yml per definire l'origine dati del database H2:

spring: datasource: driverClassName: org.h2.Driver url: jdbc:h2:mem:shedlock_DB;INIT=CREATE SCHEMA IF NOT EXISTS shedlock;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE username: sa password: 

Configuriamo il LockProvider con la configurazione dell'origine dati sopra. La primavera può renderlo piuttosto semplice:

@Configuration public class SchedulerConfiguration { @Bean public LockProvider lockProvider(DataSource dataSource) { return new JdbcTemplateLockProvider(dataSource); } }

Un altro requisito di configurazione che dobbiamo fornire sono le annotazioni @EnableScheduling e @EnableSchedulerLock sulla nostra classe di configurazione Spring:

@SpringBootApplication @EnableScheduling @EnableSchedulerLock(defaultLockAtMostFor = "PT30S") public class Application { public static void main(String[] args) { SpringApplication.run(SpringApplication.class, args); } }

Il parametro defaultLockAtMostFor specifica la quantità di tempo predefinita in cui deve essere mantenuto il blocco nel caso in cui il nodo in esecuzione muoia. Utilizza il formato Durata ISO8601.

Nella prossima sezione vedremo come sovrascrivere questa impostazione predefinita.

4. Creazione di attività

Per creare un'attività pianificata gestita da ShedLock, mettiamo semplicemente le annotazioni @Scheduled e @SchedulerLock su un metodo:

@Component class BaeldungTaskScheduler { @Scheduled(cron = "0 0/15 * * * ?") @SchedulerLock(name = "TaskScheduler_scheduledTask", lockAtLeastForString = "PT5M", lockAtMostForString = "PT14M") public void scheduledTask() { // ... } }

Per prima cosa, diamo un'occhiata a @Scheduled . Supporta il formato cron , con questa espressione che significa "ogni 15 minuti".

Successivamente, dando un'occhiata a @SchedulerLock, il parametro name deve essere univoco e ClassName_methodName è in genere sufficiente per ottenerlo. Non vogliamo che più di una esecuzione di questo metodo avvenga contemporaneamente e ShedLock utilizza il nome univoco per ottenere ciò.

Abbiamo anche aggiunto un paio di parametri opzionali.

Innanzitutto, abbiamo aggiunto lockAtLeastForString in modo da poter mettere una certa distanza tra le chiamate dei metodi. L'uso di "PT5M" significa che questo metodo manterrà il blocco per 5 minuti, come minimo. In altre parole, ciò significa che questo metodo può essere eseguito da ShedLock non più spesso di ogni cinque minuti.

Successivamente, abbiamo aggiunto lockAtMostForString per specificare per quanto tempo deve essere mantenuto il blocco nel caso in cui il nodo in esecuzione muoia. L'uso di "PT14M" significa che verrà bloccato per non più di 14 minuti.

In situazioni normali, ShedLock rilascia il blocco direttamente al termine dell'attività. Ora, non dovevamo farlo perché c'è un valore predefinito fornito in @EnableSchedulerLock , ma abbiamo scelto di sovrascriverlo qui.

5. conclusione

In questo articolo, abbiamo imparato come creare e sincronizzare le attività pianificate utilizzando ShedLock.

Come sempre, tutto il codice sorgente è disponibile su GitHub.