Spring Scheduler projelerimizin fazla instance kullanarak dağıtık olarak çalıştırılmasında zamanlaştırılmış görev uygulamarının çalışması sorun oluşturabilir.
Aynı Scheduler uygulamanın aynı anda aynı görevi yapması problemini çözmek için kullanılan ShedLock kullanımından bahsedeceğim.
Shedlock kütüphanesi kısaca bir “ara tablo” oluşturarak çalışan Scheduler’ı kayıt altına alarak verdiğimiz süre boyunca başka bir servisin aynı scheduler’ı çalıştırmasını engellememize olanak sağlamaktadır.
Shedlock kullanmak için Shedlock Spring maven bağımlılığını ve ayrıca veritabanı tercihinize göre ilgili veritabanı provider bağımlılığını kullanmamız gerekmektedir.
Shedlock Spring bağımlılığı için
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>4.33.0</version>
</dependency>
Code language: HTML, XML (xml)
Veritabanı tercihimize göre ilgili provider bağımlılığını ekleyelim. Veritabanı Postgres olacak.
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-jdbc-template</artifactId>
<version>4.33.0</version>
</dependency>
Code language: HTML, XML (xml)
Provider bağımlılığımız bize Shedlock’un ara tablo kurmasını sağlaması için gerekli olacak.
Shedlock providerımız için veritabanımızın bağlantısını sağlamamız için bir config sınıfı oluşturacağız.
@Configuration
public class SchedulerConfiguration {
@Bean
public LockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(dataSource);
}
}
Code language: PHP (php)
LockProvider Shedlock’un bir bean’i ve kullandığımız veritabanımızın datasource bilgilerini Shedlock’a veriyoruz. Shedlock bu bilgiler ile birlikte scheduler’ımız çalıştığında oluşturduğu tabloya çalışan scheduler ile iligli limit bilgilerini ve aktif olan scheduler adını kayıt altına almasını sağlayacak.
Aşağıdaki gibi bir tablo yapısı karşılayacak bizi.
+-------------+--------------------------+--------------------------+---------+
|name |lock_until |locked_at |locked_by|
+-------------+--------------------------+--------------------------+---------+
|schedulerdemo|2022-04-04 20:00:00.000000|2022-04-04 20:10:00.000000|burak |
+-------------+--------------------------+--------------------------+---------+
İlgili scheduler’ımıza bakalım ve bu schedulerımız 10 dakikada bir çalışan bir metot. Bu metotumuza scheduler lock ekleyelim.
@Scheduled(cron = "0 0/15 * * * ?")
@SchedulerLock(name = "schedulerdemo", lockAtMostFor = "4m", lockAtLeastFor = "14m")
public void shortRunningTask() {
System.out.println("Merhaba Dünya");
}
Code language: CSS (css)
15 dakikada bir çalışan metotumuza @SchedulerLock anotasyonu kullanarak adını, en az ve en çok kitleme bekleme süresini tanımlıyoruz.
- lockAtLeastFor : En fazla kitli kalma süresini belirler.
- lockAtMostFor : En az kitli kalma süresini belirler.
Bu tanımlamaları yaparak çoğul olarak çalışan spring uygulamalarımızda kullandığımız scheduler’ımzı tekilleştiriyoruz.
Burdaki tanımlamayı yanlış yapmışsınız bilginiz olsun.
lockAtLeastFor: Kilidin en az süreyle kitli kalacağı zamanı belirler. Bu süre dolmadan kilit serbest bırakılmaz, işlem bitse bile kilit bu minimum süre boyunca kitli kalır.
lockAtMostFor: Kilidin en fazla süreyle kitli kalacağı zamanı belirler. Eğer işlem bu süreyi aşarsa kilit otomatik olarak serbest bırakılır. Yani, kilidin ömrünü sınırlar.
Bu şekilde yaklaşıp makaleyi düzenlerseniz daha doğru olacaktır.
Geri bildiriminiz icin tesekkurler.