ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring @Scheduled 사용 및 동작원리
    spring/core 2021. 5. 19. 16:20

    배경

    프로젝트에서 멤버가 회원가입하고 로그인하는 과정을 살펴보자. 양식을 입력한 유저는 회원가입 요청을 서버에 하게 된다. 서버는 DB에 회원정보를 저장하는데 그 권한을 PRE로 설정하고 회원 이메일로 인증코드가 포함된 URL을 보낸다. 회원가입한 유저는 본인 이메일로 접속해 이 메일의 URL을 클릭하면 서버가 회원의 권한을 PRE에서 USER로 바꾸고 정상적으로 로그인을 처리할 수 있도록 하게 된다. 서버 내부적으로 유저이메일을 key값으로, 인증코드를 value로 외부 데이터베이스인 redis에 저장하게 된다.

     

    만약 회원가입한 유저가 회원가입만 진행한 후 인증을 제때 처리하지 않으면 어떻게 될까? 레디스에 저장하는 인증코드는 적절한 expire를 갖는 게 맞다. 레디스 저장소가 expire된다면 유저는 나중에 인증을 진행해도 권한이 USER로 바뀌지 않을 거고 영원히 인증을 진행할수도, 새로 회원가입할 수도 없을 것이다. 

     

    redis 시간이 만료된 경우는 어쩔 수 없이 새 회원가입을 하도록 설계해야 한다. 그렇다면 테이블에서 PRE상태로 일정시간 이상 유지된 레코드는 적절히 삭제해주는 로직으로 구현할 수 있을 것 같다. 그렇다면 이 작업은 누가 해줄 수 있을까

     

     

    TaskExecutor 서비스 추상화

    ThreadPoolExecutor

    독립적인 스레드를 만들어 실행하기 위해서 Thread객체에 Runnable콜백을 넘기는 방법을 사용한다. 이러한 방식을 통합해 추상화한 객체를 TaskExecutor라 하고 스프링의 주 구현 기술로 ThreadPoolExecutor가 있다. 나중에 사용할 일이 있다면 실습까지 해보자

     

    TaskScheduler

    애플리케이션 로직 내에서 의도적으로 스레드를 생성해 작업하는 경우 보통 일정한 간격이나 시간을 기준으로 실행하게 된다. 이러한 스케줄링을 스프링은 추상화하여 TaskScheduler를 제공한다. TaskScheduler에 실행콜백과 스캐줄 콜백을 넘기면 정해진 시간에 정해진 작업을 수행하게 할 수 있다.

     

     

    @Scheduled

    빈으로 등록된 클래스에 @EnableScheduling를 붙여주고 스캐줄러 클래스에 빈을 주입할 걸 생각해 @Service애너테이션을 붙임으로써 빈으로 등록했다. 마법처럼 @Scheduled애너테이션 하나로 스케줄링된 태스크를 수행하는 메서드를 작성할 수 있다. fixedDelay는 이전 작업이 끝난 시각을 기준으로 밀리초 후에 다음 작업을 수행한다. 값을 1000으로 주면 이전 작업이 끝나고 1초 후에 다시 작업을 수행한다. 단일 스레드에서 작업을 지속적으로 이루어지고 시스템 시각 1초당 1번이 아닌 걸 주의하자.

     

     

    @Async 애노테이션을 붙이면 멀리스레드로 작업을 처리할 수 있다. fixedDelay설정에선 큰 의미가 없을 거고 fixedRate환경에서 즉, 이전 작업 시작 시점으로 일정간격으로 실행하는 작업이라면 의미가 있을 것이다. 첫 코드는 같은 스레드 아이디가 출력는 걸, 위 코드는 각각 다른 스레드 아이디가 출력되는 걸 확인할 수 있다.

    @Scheduled(fixedDelay = "${..})와 같이 설정파일에서 값을 전달하도록 하자

     

    cron 매개변수를 넘기면 특정 시간마다 작업하는 스캐줄러를 만들 수 있다. 위 예시는 평일 매분마다 실행하는 작업을 의미한다.

     

    동작원리(간단)

    기본 설정으로 스레드1개를 갖는 스레드풀을 생성해 스케줄대로 수행한다. 반복 실행해도 동일한 스레드가 작업하는 걸 확인할 수 있다. SchedulingConfigurer를 구현한 클래스를 빈으로 등록해 스레드풀 설정을 커스텀할 수 있지만 굳이 다수의 스레드를 사용하느 스케줄링이 필요할지는 모르겠다. 나중에 여유가 있다면 스케줄러가 정해진 시간에 어떻게 프로세스를 실행하느지 조사해봐도 재밌을 것 같다.

    'spring > core' 카테고리의 다른 글

    Spring @RequestScope 빈 스코프  (0) 2022.08.07
    Spring 에러 핸들링  (0) 2021.10.02
    Spring Interceptor 사용 및 동작 정리  (0) 2021.05.14
    스프링 DI 방법  (0) 2021.05.06
    스프링 부트 자동설정 과정  (0) 2021.04.06

    댓글

Designed by Tistory.