자바 스프링 어플리케이션에서 카카오톡 알람 보내기 Part 3. 스케줄러 구축 및 배포

Adam·2022년 6월 28일
0

트러블슈팅

목록 보기
3/4

쿨sms의 api를 활용해 카카오톡을 보내는 것을 정상적으로 구현하였고, 이 블로그에 JPA를 활용해 db에서 알맞은 값을 조회하여 상황에 맞는 카카오톡을 보내는 것을 구현하는 과정까지 적고는 싶으나, 너무 많은 부분을 블로그에 공유를 하면 안될것 같아서 해당 부분은 생략하도록 하겠다.
하지만, 구현된 서비스를 자바에서 제공한 스케쥴러를 통해서 주기적으로 실행하는 방법에 대해서 적어보고, 해당 어플리케이션을 도커를 활용해 아마존 EC2에 배포를 하는 과정까지 작성해 보려고 한다.

스프링의 스케줄러

스프링에서 주기적으로 작업을 수행하는 것을 수월하게 할 수 있게, @Scheduled annotation을 제공한다.
@Scheduled 다음에 해당 스케줄러를 어떠한 규칙으로 실행할 것인지 지정할 수 있다.
내가 설계한 어플리케이션에선 카카오톡을 보내는 로직 이외에도 요일별로 방문자수가 얼마나 되는지 확인 할 수 있게 db에 해당 값을 쌓는 로직 역시 존재한다.
해당 작업을 위해서 특정 테이블에 매주 일요일 00:00:01에 새로운 행을 삽입을 하고, 매일 23:59:59에 해당 요일에 몇명의 유저가 방문을 했는지 카운트하는 로직을 설계하였다.
해당 작업을 위해서 @Scheduler 뒤에 cron 옵션으로 얼마나 자주 해당 로직을 실행할 수 있는지 지정을 해주었는데 코드는 다음과 같다.

//execute every Sunday at 00:00:01 at UTC+9
    @Scheduled(cron="1 0 0 * * 0", zone="GMT+9:00")
    public void insertNewLogin(){
        dayCheckService.insertNewLine();
        log.info("insert new week");
    }

    // execute at 23:59:59 everyday at UTC+9
    @Scheduled(cron ="59 59 23 * * ?", zone = "GMT+9:00")
    public void dayCount(){
        dayCheckService.dailyUserCount();
        log.info("insert daily count");
    }

cron 옵션은 다음과 같다.

따라서 매주 새로운 줄을 추가하는 첫번째 insertNewLogin 로직은 주석으로 써놓은 것 처럼 매주 일요일 1초에 00:00:01에 실행이 되는 것이다.
마찬가지로 dayCount 로직은 매일 23:59:59에 실행이 된다.
추가적으로 zone을 통해 시간대를 설정해 줄 수 있는데, 해당 값이 없을때는 그리니치 시간이 되기 때문에, 특정 한국 시간에 원하는 로직이 실행되길 바란다면 GMT+9:00 옵션을 추가 해주는 것 역시 잊어서는 안된다.

크론잡을 통해 특정 조건에 맞게 수행하는 작업 이외에도 몇분마다 혹은 더 정교하게 몇 밀리세컨드마다 특정 로직을 실행하게 할 수 도 있다.
이때는 cron 옵션이 아닌 fixedDelay를 주어서 얼마마다 특정 로직이 실행될지 지정해줄 수 있다.

// execute every 2min
    @Scheduled(fixedDelay = 120000)
    public void sendReminder() throws RESTException {
        kakaoService.sendReminder();
    }

해당 로직에서는 120000 밀리세컨드, 즉 2분마다 해당 로직을 수행하는 것이다.

어플리케이션 빌드 및 배포

해당 어플리케이션을 배포하는 과정에서 도커, 아마존 ecr, ec2를 사용할 것이다.

전에 블로그 포스트로 도커에 대해서 간단하게 글을 작성해 본 적이 있으니, 도커에 대해서 조금 더 자세한 설명을 원한다면 해당글을 참고하길 바란다.
해당 어플리케이션은 자바17을 사용해 만들었기 때문에 도커파일은 아래와 같다.

FROM openjdk:17-oracle
COPY ./build/libs/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

아마존 ECR

해당 내용 역시 전 회사에서 쿠버네티스 도입을 하면서 작성한 글에서 간략하게 설명은 하였으나, 간단히 말하면 도커 이미지를 푸시하고 받을 수 있는 도커 이미지를 위한 레포지토리라고 생각하면 편하다.
ECR 페이지에서 푸시 관련한 커멘드 역시 매우 친절하게 설명이 되어있기 때문에, 쓰는데 큰 문제는 없을 것이라고 생각된다.

아마존 EC2

아마존에서 제공하는 컴퓨팅 서비스로, 비용을 지불하여 클라우드 위에 컴퓨터를 대여한다고 보면 된다.
현재 개발하는 컴퓨터가 M1 아이맥인데, 도커가 ARM 기반에서 생성한 이미지로 생성한 컨테이너가 ARM이 아닌 환경에서 정상적으로 동작하지 않는 문제가 존재하는데, 해당 문제를 해결하기 위해서 도커 이미지를 생성할때 운영체제를 잘 선택해줘야 하는 번거로움이 있었다.
하지만, 아마존에서 arm 기반의 ec2 인스턴스를 이제 지원해주기 때문에 별다른 설정 없이 아래의 커멘드로 이미지를 생성해주면 된다.

docker build -t scheduler .

생성된 이미지를 docker push를 통해서 ECR 리포지토리에 푸시해준다.

EC2 인스턴스에서 도커 다운로드

아마존의 ec2 인스턴스는 클라우드 위에 있는 리눅스 컴퓨터라고 생각하면 된다.
다른 일반적인 컴퓨터에 프로그램을 실행하기 위해선 먼저 필요한 파일들을 설치해야 하는 것 처럼, 아마존 ec2에서 도커 컨테이너를 실행하기 위해선 ec2 인스턴스에 도커를 설치해 주어야 한다.

sudo yum install docker -y

도커를 설치한 이후 도커를 실행해준다

sudo service docker start

Sudo 명령어 없이도 docker을 실행 할 수 있도록 ec2-user을 docker group에 추가해준다.

sudo usermod -a -G docker ec2-user

정상 반영하기 위해선 시스템을 reboot해주고 docker을 다시 실행시켜주면 된다.

도커를 정상 설치하고 해당 ecr 레포지토리에서 이미지를 풀 받고 docker run을 해주면 어플리케이션이 정상적으로 작동하는 것을 확인할 수 있다.

profile
Keep going하는 개발자

0개의 댓글