본문 바로가기

JAVA

[JAVA] Quartz (쿼츠)를 사용하여 자바 스케줄링(scheduling) 하기

Quartz : http://www.opensymphony.com/

tutorial : http://quartz-scheduler.org/docs/tutorial/index.html

 

 

추가 Library 

 

 

참고 : http://blog.naver.com/kst7132?Redirect=Log&logNo=140101991602

         http://blog.naver.com/minis24?Redirect=Log&logNo=80105633208

 

스트러츠에서 Quartz 사용 : http://mygeni.tistory.com/79

스프링에서 Quartz 사용 : http://suya55.springnote.com/pages/1126992

 

 

CronTrigger 사용한 예제

 먼저 테스트로 사용할 Job 클래스 두개를 아래와 같이 만들어 준다.
Job으로 사용할 클래스는 반드시 org.quartz.Job 인터페이스를 구현하고
Job 인터페이스가 가지고 있는 public void execute(JobExecutionContext context) 메소드를 정의해 주어야 한다.


1
2
3
4
5
6
7
8
9
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
  
public class TestJob1 implements Job {
 public void execute(JobExecutionContext context) {
  System.out.println("TestJob1.execute() is Executed... : " + new Date());
 }
}
1
2
3
4
5
6
7
8
9
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
  
public class TestJob2 implements Job {
 public void execute(JobExecutionContext context) {
  System.out.println("TestJob2.execute() is Executed... : " + new Date());
 }
}



위에서 만든 두개의 Job 클래스를 스케쥴에 등록해주는 소스이다.
생성자에 있는 코드를 보면 먼저 스케쥴을 생성하여 시작해준다.
그리고 TestJob1 클래스를 매분마다 00초에 실행하도록 스케쥴에 등록해주었다.
그러면 스케쥴은 정해진 주기에 따라 TestJob1 클래스에 있는 execute(JobExecutionContext context) 메소드를 실행해준다.
두번째 TestJob2 클래스는 매분마다 30초에 실행하도록 스케쥴에 등록해주었다.
import java.text.ParseException;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;

public class TestCronTrigger {
private SchedulerFactory schedFact;
private Scheduler sched;

public TestCronTrigger() {
  try {
   // 스케쥴 생성후 시작
   schedFact = new StdSchedulerFactory();
   sched = schedFact.getScheduler();
   sched.start();
  
   // Job1 생성 (Parameter : 1.Job Name, 2.Job Group Name, 3.Job Class)
   JobDetail job1 = new JobDetail("job1", "group1", TestJob1.class);

   // Trigger1 생성 (Parameter : 1.Trigger Name, 2.Trigger Group Name, 3.Cron Expression)
   CronTrigger trigger1 = new CronTrigger("trigger1", "group1", "0 * * * * ?");

   // 아래는 trigger 가 misfire 되었을 경우에 대한 처리를 설정한다.
   //trigger1.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING);
   sched.scheduleJob(job1, trigger1);
  
   // Job2 생성후 등록  
   JobDetail job2 = new JobDetail("job2", "group2", TestJob2.class);
   CronTrigger trigger2 = new CronTrigger("trigger2", "group2", "30 * * * * ?");
   sched.scheduleJob(job2, trigger2);

      // Job2 삭제 (30초 후)
   // Thread.sleep(30000);
   // sched.deleteJob("job2", "group2");
  } catch (SchedulerException e) {
   e.printStackTrace();
  } catch (ParseException e) {
   e.printStackTrace();
  }
}

public static void main(String[] args) {
  new TestCronTrigger();
}
}



위의 세 클래스를 만들고 실행해주면 아래와 같은 결과가 나온다.


TestJob1.execute() is Executed... : Tue Jun 16 19:09:00 KST 2009
TestJob2.execute() is Executed... : Tue Jun 16 19:09:30 KST 2009
TestJob1.execute() is Executed... : Tue Jun 16 19:10:00 KST 2009
TestJob2.execute() is Executed... : Tue Jun 16 19:10:30 KST 2009
TestJob1.execute() is Executed... : Tue Jun 16 19:11:00 KST 2009



참고로 아래의 표는 CronTrigger 에서 작업주기를 설정하는 식의 예와 설명이다.
순서

    1. Seconds (0-59) - * /

    2. Minutes (0-59)  - * /

    3. Hours (0-23)  - * /

    4. Day-of-month (1-31) - * ? / L W C

    5. Month (1-12 or JAN-DEC) - * /

    6. Day-of-week (1-7 or SUN-SAT) - * ? / L C #

    7. Year (optional, empty, 1970-2099) - * /

의미

"0 0 12 * * ?"

매일 12(정오)에실행

"0 15 10 ? * *"

매일 오전 1015분에 실행

"0 15 10 * * ?"

매일 오전 1015분에 실행

"0 15 10 * * ? *"

매일 오전 1015분에 실행

"0 15 10 * * ? 2005"

2005년의 매일 오전 1015분에 실행

"0 * 14 * * ?"

매일 오후 2시부터 오후 259분까지 매분마다 실행

"0 0/5 14 * * ?"

매일 오후 2시부터 오후 255분까지 매5분마다 실행

"0 0/5 14,18 * * ?"

매일 오후 2시부터 오후 255분까지 매5분마다 실행 그리고

매일 오후 6시부터 오후 655분까지 매5분마다 실행

"0 0-5 14 * * ?"

매일 오후 2시부터 오후 205분까지 매분마다 실행

"0 10,44 14 ? 3 WED"

3월의 매주 수요일 오후 210분과 오후 244분에 실행

"0 15 10 ? * MON-FRI"

매주 월, , , , 금요일 오전 1015분에 실행

"0 15 10 15 * ?"

매월 15일 오전 1015분에 실행

"0 15 10 L * ?"

매월 마지막날 오전 1015분에 실행

"0 15 10 ? * 6L"

매월 마지막 금요일 오전 1015분에 실행

"0 15 10 ? * 6L 2002-2005"

2002년부터 2005년까지의 매월 마지막 금요일 오전 1015분에 실행

"0 15 10 ? * 6#3"

매월 세번째 금요일 오전 1015분에 실행

 

 

 

SimpleTrigger을 사용한 예제

 

[ex : Job 구현 클래스]

 import org.quartz.Job;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;

 

 public class QuartzJob implements Job {

     @Override
     public void execute(JobExecutionContext arg0) throws JobExecutionException {
          System.out.println("쿼츠 잡스케줄 실행합니다.");
     }
}

 

 

[ex : 잡스케줄링]

 import java.util.Date;
 import org.quartz.JobDetail;
 import org.quartz.Scheduler;
 import org.quartz.SchedulerException;
 import org.quartz.SimpleTrigger;
 import org.quartz.Trigger;
 import org.quartz.impl.StdSchedulerFactory;

 

 public class QuartzScheduling {
     public static void main(String[] args) throws SchedulerException{
        

         // 실행할 준비가 된 Scheduler 인스턴스를 리턴한다.

         Scheduler scheduler = new StdSchedulerFactory().getScheduler();   
        

         // 쿼츠에서 Scheduler 는 시작,정지,일시정지를 할수 있다.

         // Scheduler 가 시작되지 않거나 일시 정지상태이면 Trigger 를 발동시키지 않으므로 start()해준다.

         scheduler.start();
  

         // JobDetail 인스턴스를 생성한다.

         JobDetail jobDetail = new JobDetail("QuartzJob",                                // 잡의 이름 ,이 잡을 가리키는 역할

                                                             Scheduler.DEFAULT_GROUP,       // 잡의 그룹이름

                                                             QuartzJob.class);                       // 특정 잡을 구현한 클래스
  
         // 트리거를 생성한다.

         Trigger trigger = new SimpleTrigger("simpleTrigger",                            //트리거 이름

                                                            Scheduler.DEFAULT_GROUP,        //그룹이름

                                                            new Date(),                                 //트리거의 시작일

                                                            null,                                            // 트리거의 종료일 null 이면 종료일 없음

                                                            SimpleTrigger.REPEAT_INDEFINITELY, //반복할 횟수 ,무제한으로 설정됨

                                                            3000);                                          //인터벌
        //실행 

        scheduler.scheduleJob( jobDetail , trigger );  
       }
}

 



추가로... J2EE환경에서 작동하게 하려면 다음과 같이 설정할 수 있다.
J2EE환경에서는 servlet으로 초기화 하는 부분을 작성하고 WAS시작시 해당 servlet을 호출하도록 설정(web.xml에서 설정)하면 서비스가 시작 되면서 스케쥴이 동작하게된다.

SimpleTrigger을 사용한 예제

 

[ex : Job 구현 클래스]

package com.servlet; 
import org.quartz.Job;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;

 

 public class QuartzJob implements Job {

     @Override
     public void execute(JobExecutionContext arg0) throws JobExecutionException {
          System.out.println("쿼츠 잡스케줄 실행합니다.");
     }
}

 

 

[servlet으로 스케쥴 작성]

package com.servlet;
import java.util.Date;
 

import javax.servlet.ServletConfig;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

 

import org.quartz.JobDetail;

import org.quartz.Scheduler;

import org.quartz.SchedulerException;

import org.quartz.SimpleTrigger;

import org.quartz.Trigger;

import org.quartz.impl.StdSchedulerFactory;

 

import com.enrise.framework.log.Log;

 

public class QurtzSample extends HttpServlet {

      

       @Override

       public void init(ServletConfig cfg) throws ServletException {

             // TODO Auto-generated method stub

             super.init(cfg);

            

            

             try{

          //실행할 준비가 Scheduler 인스턴스를 리턴한다.

                    Scheduler scheduler = new StdSchedulerFactory().getScheduler();

                   

          // 쿼츠에서 Scheduler 시작, 정지, 일시정지할 있다.

          // Scheduler 시작되지 않았거나 일시 정지상태이면 Trigger

            발동시키지 않으므로 start()해준다.

          scheduler.start();

                   

          //JobDetail인스턴스를 생성한다.

                    JobDetail jobDetail = new JobDetail("QuartzJob",

                                        Scheduler.DEFAULT_GROUP,

                                                                                QuartzJob.class);

                   

          //트리거를 생성한다.

                    Trigger trigger = new SimpleTrigger("simpleTrigger", 
                                       
Scheduler.
DEFAULT_GROUP,

                                                                                new Date(),

                                                                                null,

                                        SimpleTrigger.REPEAT_INDEFINITELY,
                                       
3000);

           //실행

           scheduler.scheduleJob(jobDetail, trigger);

                   

                   

             }catch(SchedulerException se){

                    Log.debug.println(se.toString());

             }

      }

 

}

  
          



[web.xml에 내용추가]  - WAS 시작시 특정 서블릿 호출

  <servlet>      
          <servlet-name>QurtzSample</servlet-name>
          <servlet-class>com.servlet.QurtzSample</servlet-class>
          <init-param>
                <param-name>shutdown-on-unload</param-name>
                <param-value>true</param-value>
          </init-param>
          <load-on-startup>2</load-on-startup>
   </servlet>