Spring Quartz 쿼츠

Hailey·2025년 6월 14일

SPRING

목록 보기
15/15

스케줄러는 크게 공부하지 않아도 되었는데... 쿼츠는 진짜 공부해야 구현 가능할 것 같아서 정리해보려고 한다..!

일단, 처음에 난 gpt가 만들어준 코드가 애초에 흐름이 이해가 잘 안되었다..
우리는 알림 테이블이 따로 있는데 스케줄러에 따로 저장시킨다는게 무슨의미인지..? 하지만 이 둘은 목적과 역할이 다르다!

Quartz는 작업 스케줄링을 처리하는 라이브러리이고, 알림 테이블은 알림 데이터를 저장하고 관리하는 곳입니다. Quartz는 스케줄링 라이브러리로, 단순히 특정 시간에 작업(Job)을 자동으로 실행하도록 예약하는 역할을 합니다. 알림 테이블은 그 알림의 내용과 상태를 저장하는 역할을 합니다.

즉, Quartz는 알림을 보내는 작업을 예약하는 스케줄러로서 동작하고, 알림 테이블은 알림의 내용을 관리하는 데이터베이스로 동작하는 것입니다.

1. Spring Boot Quartz란?

Java 기반의 오픈 소스 작업 '스케줄링 라이브러리'를 의미합니다. 이를 사용하면 특정시간에 작업을 실행하거나 특정 간격으로 작업을 수행할 수 있습니다.

2.주요 클래스 및 인터페이스

2-1. Job 인터페이스

실행할 작업을 정의하는 인터페이스

2-2. JobDetail 인터페이스

실행될 작업을 정의하고구성하는 인터페이스 << 나머지는 모두 이걸 구성하기 위한 클래스 인터페이스들이다.

2-3. JobBuilder 클래스

JobDetail 인스턴스를 생성하는데 사용되는 유틸리티 클래스

2-4. JobListner 인터페이스

작업의 생명 주기 동안 발생하는 이벤트를 처리하는 인터페이스

2-5. JobDataMap 클래스

작업 실행시 필요한 데이터를 저장하는 맵

2-6. Trigger 인터페이스

작업의 실행 시간을 결정하는 인터페이스

2-7. Cron 인터페이스

복잡한 실행 스케줄을 정의할 수 있는 Trigger 인터페이스

2-8. TriggerBuilder 클래스

Trigger 인스턴스를 생성하는데 사용되는 유틸리티 클래스

: trigger도 job도 scheduler도 모두 생성하는 builder클래스가 따로 존재한네..!


2-9. Scheduler 인터페이스

작업과 트리거를 관리하고 실행하는 인터페이스

2-10. SimpleScheduleBuilder 클래스

간단한 실행 스케줄을 정의할 수 있는 클래스

2-11. CronScheduleBuilder 클래스

복잡한 실행 스케줄을 cron 표현식으로 정의할 수 있는 클래스

2-12. SchedulerFactory 클래스

Scheduler 인스턴스를 생성하는 클래스

3. Job

1) Job

Quarz에서 ‘실행 할 작업을 정의’하는 인터페이스입니다. 실행할 작업은 클래스를 생성하고 해당 Job 인터페이스의 구현체로 작업을 정의하여 사용합니다.

2) JobDetail

Quatz 스케줄러에 의해 실행되는 작업을 정의합니다. 해당 객체는 JobBuilder를 통해 구성하며 실행하려는 Job의 이름, 그룹, 클래스 타입 등의 정보를 구성합니다.

사용예시

JobDetail jobDetail = JobBuilder
        .newJob(MyJob.class)
        .withIdentity("myJob", "group1")
        .build();

JobBuilder로 구성하며 newJob()메서드를 통해 MyJob라는 Job(사용자가 구현한 job 클래스)을 추가하고 withIdentity()를 통해 그룹을 지정하여 객체를 구성합니다.

3) JobBuilder

Quartz 스케줄러에서 사용하는 유용한 유틸리티 클래스로 JobDetail 인스턴스를 생성합니다. JobDetail 객체를 쉽게 생성하고 작업의 이름, 그룹, 클래스 타입 등의 세부 정보를 설정할 수 있습니다.

[참고] JobBuilder API Document

ex)

JobDetail jobDetail = JobBuilder
       .newJob(MyJob.class)                   // Job의 구현 클래스 설정
       .withIdentity("myJob", "group1")        // Job의 identity 설정
       .withDescription("This is my job")      // Job의 설명 설정
       .ofType(MyJob.class)                   // Job의 구현 클래스 설정
       .requestRecovery(true)                  // Job이 실패한 경우 다시 실행하도록 설정
       .storeDurably(true)                     // Job이 지속적으로 저장되도록 설정
       .usingJobData("key", "value")           // Job의 data map 설정
       .build();                               // 설정된 정보를 바탕으로 JobDetail 인스턴스 생성

4) JobListner

Job의 생명주기를 관리하며 해당 job의 실행 전/중/후에 이벤트를 일어나게 할 수 있다. 대충 그런 의미?로 이해함.

4. Trigger

  • 스케줄러에서 사용되는 Trigger는 SimpleTrigger와 CronTrigger로 나뉩니다.
  1. SimpleTrigger는 Trigger로 인스턴스화 해야합니다.

  2. 이는 TriggerBuilder를 통해 구성하며 withSchedule() 메서드를 통해서 SimpleScheduleBuilder를 구성합니다.

SimpleScheduleBuilder > TriggerBuilder > Trigger 인스턴스

💡 SimpleScheduleBuilder 사용예시

  • Trigger를 인스턴스화 할때 TriggerBuilder를 사용하여 구성합니다.
  • TriggerBuilder에서는 simpleSchedule을 사용하여 구성하였고 10초마다 영원히 반복되는 트리거를 사용하였습니다.
// Trigger 생성
Trigger trigger = TriggerBuilder
        .newTrigger()
        .withIdentity("myTrigger", "group1")
        .startNow()
        .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(10)
                .repeatForever())
        .build();


  1. CronTrigger는 Trigger 혹은 CronTrigger로 인스턴스화해야 합니다.
  2. 이는 TriggerBuilder를 통해 구성하며 withSchedule() 메서드를 통해서 CronScheduleBuilder를 구성합니다.

CroneScheduleBuilder > TriggerBuilder > Trigger 인스턴스
CroneScheduleBuilder + DateBuilder > TriggerBuilder > CronTrigger 인스턴스

💡 CronScheduleBuilder 사용예시

  • Trigger를 인스턴스화 할때 TriggerBuilder를 사용하여 구성합니다.
  • TriggerBuilder에서는 cronSchedule을 사용하여 구성하였고 10초마다 반복되는 트리거를 사용하였습니다.
 Trigger trigger = TriggerBuilder
              .newTrigger()
              .withIdentity("fcmSendTrigger", "fcmGroup")         // Trigger 이름, 그룹 지정
              .withDescription("FCM 처리를 위한 조회 Trigger")       // Trigger 설명
              .startNow()
              .withSchedule(
                      CronScheduleBuilder
                              .cronSchedule("0/10 * * * * ?")
              )
              .build();

4-1. Trigger

Trigger는 간단히 말해 작업이 언제 실행될지를 정의하는 것입니다.

  • Trigger 역시 JobDetail 객체와 비슷하게 TriggerBuilder로 인스턴스를 생성합니다.
  • Quartz는 SimpleTrigger와 CronTrigger 두 가지 주요한 Trigger를 제공합니다.

  1. SimpleTrigger
  • 특정 시간에 시작하여 주기적으로 작업을 실행하도록 설정할 수 있습니다. 이때 실행 주기와 반복 횟수를 설정해야 합니다
  1. CronTrigger
  • UNIX cron 표현식을 사용하여 작업 실행 스케줄을 정의할 수 있습니다. 복잡한 실행 스케줄을 정의할 수 있으므로, 매주 특정 요일에 실행되거나 매월 특정 날에 실행되는 등의 스케줄을 설정할 수 있습니다.

5.Scheduler

  • 스케줄러에서 사용되는 Scheduler는 StdSchedulerFactory를 통해 스케줄러를 가져와서 Scheduler Job을 구성합니다. 또한 Job의 생명주기를 관리하는 JobListener를 등록할 수 있습니다.
  • Scheduler Job에는 Job과 Trigger가 등록이 됩니다.

5-1. Scheduler

  • 여러 작업(Job)을 관리하고 이들을 트리거(Trigger)에 따라 실행합니다. 스케줄러는 작업의 실행 시간, 빈도 등을 제어하며, 필요에 따라 작업을 일시 중지하거나 재개할 수 있습니다.

5-2. StdSchedulerFactory

  • Quartz 스케줄러의 가장 일반적인 구현체입니다. 이 클래스는 Scheduler 인스턴스를 생성하고 초기화하는 역할을 합니다.

6. 사용 예시

스케줄러를 구성하는 과정을 정의한 클래스입니다. Job, Trigger, Scheduler 인스턴스를 생성하여 일정 시간마다 수행하도록 구성합니다.

package com.adjh.multiflexapi.scheduler;

import com.adjh.multiflexapi.scheduler.job.MyJob;
import com.adjh.multiflexapi.scheduler.job.MyJobListener;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * 스케줄러의 설정을 관리합니다.
 *
 * @author : lee
 * @fileName : ScheduleConfig
 * @since : 2/28/24
 */
@Configuration
public class SchedulerConfig {

    private Scheduler scheduler;

    public SchedulerConfig(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

    /**
     * 스케줄러의 실제 처리 과정을 담당합니다.
     */
    @PostConstruct
    private void jobProgress() throws SchedulerException {
        cronScheduler();
    }

    /**
     * SimpleScheduler 구성 메서드
     *
     * @throws SchedulerException
     */
    private void simpleScheduler() throws SchedulerException {
        // [STEP1] Job 생성
        JobDetail job = JobBuilder
                .newJob(MyJob.class)                                   // Job 구현 클래스
                .withIdentity("myJob", "myGroup")     // Job 이름, 그룹 지정
                .withDescription("FCM 처리를 위한 조회 Job")   // Job 설명
                .build();

        // [STEP2] Trigger 생성
        Trigger trigger = TriggerBuilder
                .newTrigger()
                .withIdentity("myTrigger", "myGroup")         // Trigger 이름, 그룹 지정
                .withDescription("FCM 처리를 위한 조회 Trigger")     // Trigger 설명
                .startNow()
                .withSchedule(
                        SimpleScheduleBuilder
                                .simpleSchedule()
                                .withIntervalInSeconds(5)
                                .repeatForever())
                .build();

        // [STEP3] 스케줄러 생성 및 Job, Trigger 등록
        scheduler = new StdSchedulerFactory().getScheduler();
        MyJobListener myJobListener = new MyJobListener();
        scheduler.getListenerManager().addJobListener(myJobListener);
        scheduler.start();
        scheduler.scheduleJob(job, trigger);
    }

    /**
     * CronScheduler 구성 메서드
     */
    private void cronScheduler() throws SchedulerException {

        // [STEP1] Job 생성
        JobDetail job = JobBuilder
                .newJob(MyJob.class)                                   // Job 구현 클래스
                .withIdentity("myJob", "myGroup")     // Job 이름, 그룹 지정
                .withDescription("FCM 처리를 위한 조회 Job")   // Job 설명
                .build();

        CronTrigger cronTrigger = TriggerBuilder
                .newTrigger()
                .withIdentity("fcmSendTrigger", "fcmGroup")         // Trigger 이름, 그룹 지정
                .withDescription("FCM 처리를 위한 조회 Trigger")     // Trigger 설명
                .startNow()
                .withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ?")).build();

        // [STEP3] 스케줄러 생성 및 Job, Trigger 등록
        scheduler = new StdSchedulerFactory().getScheduler();
        MyJobListener myJobListener = new MyJobListener();
        scheduler.getListenerManager().addJobListener(myJobListener);
        scheduler.start();
        scheduler.scheduleJob(job, cronTrigger);
    }

}
profile
럭키헤일리

0개의 댓글