İçerikler :

Cron Job Quartz API Quartz API'de Bir Job Tamamlamadan Diğerinin .. Quartz API'si için Cron Oluşturucu Quartz API'sinde Cron Yazım Kuralları Quartz API Load Balancing ve Cluster Destekle.. QuartzDesk Web Uygulaması Kurulumu Quartz Job'larının XML ile Tanımlanması Quarzt API 2.2.2 Kurulumu ve Basit Bir Job Ça.. StatefulJob Stateless Job

Bu Sayfayı Paylaş:

Kavram

Quartz API

Tanım: Java'da yazılım içinde belirli zamanlarda belirli görevleri (zamanlanmış görevler) yerine getirmek için kullanılan kütüphane, API.

Kavram

Job

Tanım: Quartz API'sinde zamanlanmış görev yaratmak için kullanılan interface. Belirli zamanlarda çalışacak kod yazımı için bu interface implements edilir.

İpucu

Quarzt API 2.2.2 Kurulumu ve Basit Bir Job Çalıştırılması

Maven projesinde aşağıdaki gibi bağımlılık eklenmeli:

    org.quartz-scheduler
    quartz
    2.2.2


    org.quartz-scheduler
    quartz-jobs
    2.2.2

Aşağıdaki gibi quartz.properties dosyasını classpath'e eklenmesi gerekir (örneğin src klasörünün root'na eklenebilir)
org.quartz.scheduler.instanceName = MyScheduler 
org.quartz.threadPool.threadCount = 3 
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.scheduler.instanceName = MyScheduler sistem bir isim vermek için kullanılır. org.quartz.threadPool.threadCount değeri anda çalışacak thread sayısını sınırlamaktadır. org.quartz.jobStore.class ise job'ların RAM'de saklanacağı ve yönetileceği anlamına gelmektedir.
Aşağıdaki gibi ekrana Hello World yazan bir job yapılabilir:
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class HelloWorldJob implements Job{

	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		
		System.out.println("Hello World");
		
	}
	
}
Bu job'ın çalışması için Scheduler sistemini başlatan, bu job'ı çalışması için bir sınıf aşağıdaki gibi yapılabilir:
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;

import static org.quartz.JobBuilder.*;
import static org.quartz.TriggerBuilder.*; 
import static org.quartz.SimpleScheduleBuilder.*;

import org.quartz.JobDetail; 

public class SchedulerManager {

	public void init() throws SchedulerException{
		
		SchedulerFactory schedulerFactory = new StdSchedulerFactory(); 
		Scheduler scheduler = schedulerFactory.getScheduler(); 
		  
		scheduler.start(); 
		
		JobDetail jobDetail = newJob(HelloWorldJob.class) 
			    .withIdentity("job1", "group1") 
			    .build();
		
		Trigger trigger = newTrigger() 
			    .withIdentity("trigger1", "group1") 
			    .startNow() 
			    .withSchedule(simpleSchedule() 
			            .withIntervalInSeconds(10) 
			            .repeatForever())            
			    .build(); 
		
		scheduler.scheduleJob(jobDetail, trigger);
		
	}
	
	public static void main(String[] args) throws SchedulerException {
		
		SchedulerManager manager=new SchedulerManager();
		manager.init();
		
	}
	
}
scheduler.start() ile scheduler sistemi başlatılır. JobDetail sınıfı ile HelloWorld job'ı tanımlanır. Bu job'ın hangi aralıklarla çalışacağını belirlemek için bir Trigger yaratılır. Örnekte yaratılan trigger 10 sn'de bir HelloWorldJob'ın çalışmasını sağlayacak şekildedir. scheduler.scheduleJob(jobDetail, trigger) ile bu işlem yapılmıştır.
main içinde init methodu çağrılacak sistemin çalışması sağlanmıştır. Program çalıştığında ekrana 10 sn de bir Hello World yazılacaktır

Bu job'ın bir web servis içinde , uygulama sunucusu açılırken (jboss , tomcat vb..) yüklenmesi isteniyor ise aşağıdaki gibi web listener ile yapılabilir :


import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.annotation.WebListener;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.quartz.impl.StdSchedulerFactory;

@WebListener
public class QuartzListener extends QuartzInitializerListener {

	@Override
	public void contextInitialized(ServletContextEvent sce) {

		try {
			super.contextInitialized(sce);
			
			ServletContext ctx = sce.getServletContext();
			
			StdSchedulerFactory schedulerFactory = (StdSchedulerFactory) ctx
					.getAttribute(QUARTZ_FACTORY_KEY);
			
			Scheduler scheduler = schedulerFactory.getScheduler(); 
			  
			scheduler.start(); 
			
			JobDetail jobDetail = newJob(HelloWorldJob.class) 
				    .withIdentity("job1", "group1") 
				    .build();
			
			Trigger trigger = newTrigger() 
				    .withIdentity("trigger1", "group1") 
				    .startNow() 
				    .withSchedule(cronSchedule("0/10 * * * * ?"))            
				    .build(); 
			
			scheduler.scheduleJob(jobDetail, trigger);
			
		} catch (SchedulerException e) {
			e.printStackTrace();
		}

	}

}

Kavram

StatefulJob

Tanım: State'ini (durumunu) bir sonraki çalışmasında erişilebilecek şekilde saklayan Job. Bu Job'larda bir önceki zamanda çalışan Job tamamlanmadan yeni Job çalışmaya başlamaz.

Kavram

Stateless Job

Tanım: Ardışık olarak çalışan Job'ların tamamen birbirinden bağımsız olduğu Job'lardır. Bir önceki Job'ın çalışması tamamlanmadan bir sonraki Job çalışabilir.

İpucu

Quartz API'de Bir Job Tamamlamadan Diğerinin Başlamaması İçin StatefulJob Kullanabilirsiniz

Bir Job çalışmasını tamamlayamadan diğer Job'ın çalışma zamanı gelirse normal durumlarda diğer Job'da çağrılır. Örneğin 10 sn bir çalışması gerekn bir Job'ta bir Job'ın işi 10 sn'de bitmez ise diğer Job'ta çalışmaya başlar. Bu şekilde aynı anda çok sayıda Job çalışabilir. Eğer bu durumun oluşmasını istemiyorsanız Job interface'si yerine StatefulJob interface'sini implement ediniz. 


Kavram

Cron

Tanım: Unix'te zamanlanmış görev (zamanı geldiğinde çalışan görevler) yaratmaya yarayan sistem ve zamanı tanımlamak için kullanılan yazım kuralı

Veri

Quartz API'sinde Cron Yazım Kuralları

Quartz API'sinde Cron aşağıdaki gibi 7 bölümden oluşmuştır :

(Saniye) (Dakika) (Saat) (Ayın Günü) (Ay) (Haftanın Günü) (Yıl)

Örnek : 0 15 10 * * ? 2005 (2005 yılında her gün 10'u 15 geçe)

* Yıl bölümünü kullanmak zorunlu değildir. 

Her bölümde kullanılacak karakterler aşağıdaki gibi olabilir  :

Saniye :   0-59 , - * /

Dakika :   0-59 , - * /

Saat :   0-59 , - * /

Ayın Günü : 1-31 , - * / ? L W

Ay : 1-12 veya JAN-DEC , - * /

Haftanın Günü : 1-7 veya SUN-SAT , - * / ? L #

Year : 1970-2099 , - * /

 

Karakterlerin Anlamı 

* :Tüm değerler için kullanılır

? :Herhangi bir değer için kullanılır

, :Birden fazla değer vermek için kullanılır. 

- :Aralık vermek için kulanılır. Örneğin saat değeri 10-13 ise saat 10,11,12,13 anlaşılır

/ :Belirli değerde arttırmak için kullanılır. Örneğin saniye değeri için 0/15 ifadesi saniye değeri 0 ,15, 30, 45 anlamına gelmektedir.

L :Last(son) anlamına gelmektedir. L Ayın son günü veya haftanın son günü için kullanılır.

W :Weekday (İş günü) anlamına gelmektedir.

# :".nci günü" anlamına gelmektedir. Örneğin haftanın günü için 6#3 ifadesi ayın 3. cuması anlamına gelmektedir.


Kaynak

Quartz API'si için Cron Oluşturucu

Quartz API'sinde kullanılabilmesi için kolayca Cron scriptini üretmeniz için kullanılabilen araç.

Veri

Quartz API Load Balancing ve Cluster Destekleme Özelliği

Quartz API,  Load Balancing ve Cluster desteği bulunmaktadır. Birden fazla server üzerinde tek bir server'da çalışır gibi çalışabilmektedir. 

Dağıtık çalışabilmesi için veriler bir ilişkisel veritabanında saklanmalı ve JDBC ile ona erişilmelidir. Konfigürasyonda dağıtık (load balancing veya cluster ortamında) ortamda çalışıldığı bilgisi tanımlanmalıdır. 

Veritabanındaki kitleme sistemi sayesinde aynı anda bir Job iki veya daha fazla server'da çalışamaz. 

 


Örnek

Quartz Job'larının XML ile Tanımlanması

Quartz API'si job'ları XML ile tanımlamanızı sağlayabilirsiniz. XML üzerinde yapılan değişiklik otomatik olarak tekrar yüklenmektir.
quartz.properties aşağıdaki gibi tanımlanabilir:
org.quartz.scheduler.instanceName = MyScheduler
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.plugin.jobInitializer.class =org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames = D:\quartz-config.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
org.quartz.plugin.jobInitializer.wrapInUserTransaction = false
org.quartz.plugin.jobInitializer.scanInterval = 10
XML ile iki tane job tanımlayalım. XML dosyası D:\quartz-config.xml klasöründe olsun
<?xml version="1.0" encoding="UTF-8"?>
<job-scheduling-data
	xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData
	http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd"
	version="1.8">
             
	<schedule>
		<job>
			<name>JobA</name>
			<group>GroupDummy</group>
			<description>This is Job A</description>
			<job-class>com.thy.mercury.jobs.HelloJob</job-class>
		</job>
		<trigger>
		  <cron>
			 <name>dummyTriggerNameA</name>
			 <job-name>JobA</job-name>
			 <job-group>GroupDummy</job-group>
			 <cron-expression>0/5 * * * * ?</cron-expression>
		  </cron>
		</trigger>
	</schedule>
	<schedule>
		<job>
		  <name>JobB</name>
		  <group>GroupDummy</group>
		  <description>This is Job B</description>
		  <job-class>com.thy.mercury.jobs.HelloJob2</job-class>
		</job>
		<trigger>
			<cron>
				<name>dummyTriggerNameB</name>
				<job-name>JobB</job-name>
				<job-group>GroupDummy</job-group>
				<cron-expression>0/5 * * * * ?</cron-expression>
			</cron>
		</trigger>
</schedule>
HelloWorld job'ları aşağıdakine benzer olabilir:
 
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
 
public class HelloJob implements Job {
 
	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
			   
	  System.out.println("Hello Job");
			   
	}
 
}
Scheduler sistemini ayağa kaldırmak için uygulama aşağıdaki gibi olabilir:
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.StdSchedulerFactory;
 
public class JobsApplication {
             
	public static void main(String[] args) {
		try {
			Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
			scheduler.start();
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}
}
Job'a aşağıdaki gibi parametre de ekleyebilirsiniz:
<job>
	<name>JobA</name>
	<group>GroupDummy</group>
	<description>This is Job A</description>
	<job-class>com.thy.mercury.jobs.HelloJob</job-class>
	<job-data-map>
		<entry>
			<key>Name</key>
			<value>World</value>
		</entry>
	</job-data-map>
</job>
Bu parametreler Job'ın içinde aşağıdaki gibi alınabilir:
System.out.println("Hello Job");
 
JobDataMap map=jobExecutionContext.getJobDetail().getJobDataMap();
 
for (String key : map.keySet()) {
             
	System.out.println(key+"="+map.getString(key));
             
}
XML'de yapılan değişiklikler 10 sn sonra devreye alınmaktadır. Eğer Job'ları kaldırmak istiyorsanız XML'in başına aşağıdakini ekleyebilirsiniz :
<pre-processing-commands>
<delete-job>
	<name>JobA</name>
	<group>GroupDummy</group>
</delete-job>
<delete-trigger>
	<name>dummyTriggerNameA</name>
</delete-trigger>
</pre-processing-commands>

Veri

QuartzDesk Web Uygulaması Kurulumu

QuartzDesk Web uygulaması, Lite edition (ücretsiz) olarak kullanılabilir. Bu yazıda bu ürünün kurulması anlatılmaktadır.
Öncelikle Lite Edition için lisans anahtar dosyası alınmalıdır. Lisan dosyası https://www.quartzdesk.com/try-purchase/get-free-license-key bu adresden alınabilir. Size lisans dosyası mail ile gönderilecektir.
https://www.quartzdesk.com/downloads/latest-release/3-6-0 sayfasından QUARTZDESK-WEB-3.6.0.WAR bölümünden war'ı indirmeniz gerekir. quartzdesk-web-3.6.0.war şeklinde bir dosya olmalı.
Bir klasör yaratın. Örneğin E:\Programs\quartzdesc olsun. İçine mail ile gönderilen lisans dosyasını ekleyin. Ardında .war dosyası içinde extrask dizini içindeki logback.xml ve quartzdesk-web.properties dosyasını bu dizine kopyalayın.
QuartzDesk bir veritabanı gerektirir. Bu nedenle boş bir veritabanı yaratmanız gerekir. Bu veritabanına göre quartzdesk-web.properties dosyası doldururlur. Örneğin H2 veritabanını kullanıyorsak db.profile = h2 şeklinde olmalıdır. Yine H2 ile ilgili bölüm açılabilir:
#onestep.jdbc.driverClassName = org.h2.Driver
#onestep.jdbc.url = jdbc:h2:file:${quartzdesk-web.work.dir}/h2/quartzdesk
#onestep.jdbc.username = quartzdesk
#onestep.jdbc.password = quartzdesk
#onestep.jdbc.pool.initialSize = 1
#onestep.jdbc.pool.maxTotal = 20
#onestep.jdbc.pool.minIdle = 1
#onestep.jdbc.pool.maxIdle = 1
#onestep.jdbc.pool.maxWaitMillis = 5000
#onestep.jdbc.pool.validationQuery = select 1
Eğer bunun yerine datasource kullanmak istiyorsanız Tomcat'de conf içinde server.xml'de GlobalNamingResources elementi içine aşağıdakini ekleyebilirsiniz. Datasource kullanmanızı tavsiye ederiz.
<Resource name="jdbc/QuartzDeskDS"
 auth="Container"
 type="javax.sql.DataSource"
 removeAbandoned="true"
 removeAbandonedTimeout="30"
 maxActive="10"
 maxIdle="1"
 maxWait="2000"
 validationQuery="select 1"
 poolPreparedStatements="true"
 username="quartzdesc"
 password="quartzdesc"
 driverClassName="org.h2.Driver"
 url="jdbc:h2:file:C:\Users\test\quartzdesc.mv.db"/>
Kullandığınız veritabanın driver'ını Tomcat'in lib dizinine ekleyin. Böylece veritabanı sürücüsü classpath'de olacaktır.
İçinde lisans ve properties dosyaları bulunan E:\Programs\quartzdesc dizini Work dizinidir. Bu dizini Tomcat açılırken vermek gerekir. Ayrıca hangi Datasource'un kullanıcağıda verilmeldir. Bunun için Tomcat conf dizini altındaki Catalina/localhost altına quartzdesk.xml adında bir XML oluşturup aşağıdaki içeriği ekleyin:
<?xml version="1.0"?>
<Context>
  <Parameter name="quartzdesk-web.work.dir" 
value="E:\Programs\quartzdesc"/>  
  <ResourceLink name="QuartzDeskDS" global="jdbc/QuartzDeskDS"
type="javax.sql.DataSource"/>
</Context>
quartzdesk-web.work.dir değeri Tomcat açılırken parametre olarak
set CATALINA_OPTS=%CATALINA_OPTS% -Dquartzdesk-web.work.dir=Q:\Programs\quartzdesc
şeklinde de verilebilir. Bu ifade setEnv veya doğrudan catalina.bat'a ekleyebilirsiniz.
Artık .war dosyasını Tomcat'e deploy edebilirsiniz. Tomcat içideki webapp içine quartzdesk.war adıyla atmanız gerekir.
Tomcat açıldığında sorun yoksa http://localhost:8080/quartzdesk/ ile girebilirsiniz. Login ekranında kullanıcı adı admin ve şifre admin123 girip girebilirsiniz. ana sayfayı görebiliyorsanız artık kurulmuş demektir.
Sol menüden bir Connection ekleyelim. Açılan pencereded JMX IP ve port bilgilerini `verip Discover düğmesine basarsak eğer bir Bean bulunursa listede görülür.
Add düğmesine bastığımızda connection eklenecektir. Artık Lite Edition'un desteklediği kısıtlı özellikleri kullanabilirsiniz.



Bu Sayfayı Paylaş:

İletişim Bilgileri

Takip Et

Her Hakkı Saklıdır. Bu sitede yayınlanan tüm bilgi ve fikirlerin kullanımından fibiler.com sorumlu değildir. Bu sitede üretilmiş , derlenmiş içerikleri, fibiler.com'u kaynak göstermek koşuluyla kendi sitenizde kullanılabilirsiniz. Ancak telif hakkı olan içeriklerin hakları sahiplerine aittir