JUINTINATION

EC2 프로젝트 cron 주기적 실행 본문

Amazon Web Services

EC2 프로젝트 cron 주기적 실행

DEOKJAE KWON 2024. 7. 10. 19:07
반응형

프로젝트를 배포하면 실행되는 도중 부하가 심해지거나 에러가 발생하는 등의 이유로 서버가 종료될 수 있다. 지난 글에서 만들었던 err.log 파일에서 서버가 종료되었다는 로그를 확인할 수 있지만, 서버가 자동으로 재시작되지는 않기 때문에 서버를 직접 재시작해줘야 하는데 이 과정은 매우 번거롭기 때문에 자동화하기 위해 cron에 대해 알아보자.

 

EC2 프로젝트 nohup으로 백그라운드로 실행해보기

이 글은 지난 EC2 타임존 변경 및 종료 스크립트 작성에서 이어지는 내용이다. 참고한 책과 순서가 조금 다를 수 있다. EC2 서버 타임존 변경 및 종료 스크립트 작성이 글은 지난 Amazon EC2 시작하기

juintination.tistory.com

cron

cron은 작업을 고정된 시간, 날짜, 간격에 주기적으로 실행할 수 있도록 스케줄링하기 위해 사용하는 시간 기반 job scheduler이다. cron 작업을 설정하는 파일을 crontab이라고 하며 cron 프로세스는 다음과 같이 /etc/crontab 파일에 설정된 내용을 읽어서 작업을 수행한다.

이제 해당 디렉터리로 이동하여(해당 디렉터리로 이동해야 하는 줄 알았는데 현재 디렉터리에서도 수정이 가능하다..) crontab 파일에 설정된 내용을 읽어서 작업을 수행해야 한다.

현재 위치 확인 후 최상위 디렉터리의 etc 디렉터리로 이동한 뒤(해당 디렉터리로 이동해야 하는 줄 알았는데 현재 디렉터리에서도 수정이 가능하다..) $ crontab -e 명령어를 실행한다. 이때 처음에는 편집 화면이 바로 나오지 않고 어떤 에디터를 사용할지에 대한 선택 창이 나왔는데, 나는 2번을 선택하여 vim.basic을 사용하였다.

 

위와 같은 편집 화면이 뜨면 i 를 눌러서 INSERT 모드로 진입한 뒤 맨 아래에 원하는 내용을 적으면 된다. 나는 책에 나온 테스트용으로 만든 * * * * * ls -l 1>>cron.log 를 입력하였다. 지난 글에도 잠깐 언급했듯이 꺽쇠(>)가 하나만 있으면 로그가 덮어쓰기가 되는데 두 개를 적어주면 아래에 추가가 되는 방식이다.

 

이때 앞에 적힌 애스터리스크(*) 5개의 설정은 각각 다음과 같다.

 

  1. 분(0~59)
    • * * * * *을 1 * * * *로 변경하면 매 시각 1분에 실행된다.
  2. 시간(0~23)
    • * * * * *을 1 3 * * *로 변경하면 매일 새벽 3시 1분에 실행된다.
    • * * * * *을 * 3,4 * * *로 변경하면 매일 새벽 3시, 4시에 실행된다.
    • * * * * *을 * 3-6 * * *로 변경하면 매일 새벽 3시부터 6시 정각에 실행된다.
  3. 일(1~31)
  4. 월(1~12)
  5. 요일(0~7 // 일요일은 0, 월요일은 1)

 

파일 저장 방법은 vi를 사용할 때와 똑같이 ESC 를 누른 후에 :wq 를 입력하고 엔터하면 된다.

파일을 저장하고 약 1분 뒤에 원래 디렉터리로 돌아가보면 cron.log가 생긴 것을 볼 수 있다.

 

이 상태에서 $ cat cron.log 명령어를 실행해보면 1분마다 $ ls -l 명령어를 실행했을 때의 결과가 로그로 남아있는 것을 확인할 수 있다.

 

다시 $ crontab -e 명령어를 실행하여 기존에 작성했던 내용을 지운다. 해당 라인으로 이동하여 dd 를 입력하면 그 라인을 한 번에 지울 수 있다. 이후에 $ rm cron.log 명령어로 cron.log 파일을 지운다.

cron 자동화 스크립트

위의 방법을 사용하면 crontab에 직접 한 줄 한 줄 등록해줘야 하기 때문에 스크립트를 작성하여 자동화해보려고 한다.

먼저 $ vi myScript.sh 명령어로 myScript.sh를 생성한다.

 

이후 위와 같이 내용을 작성한다.

crontab -l 1>crontab_new

crontab -l 옵션을 사용하여 crontab의 내용을 그대로 crontab_new 파일로 옮긴다.

echo "* * * * * /home/ubuntu/job.sh" 1>>crontab_new

아직 job.sh 파일을 만들지는 않았지만 매분마다 job.sh 파일이 실행되도록 한다.

crontab crontab_new

crontab_new 파일의 내용을 crontab에 등록한다.

마찬가지로 $ vi job.sh 명령어로 job.sh를 생성한다.

 

ls -l > /home/ubuntu/cron.log

현패 디렉터리에 있는 모든 결과를 cron.log에 모두 옮기라는 명령이다.

 

두 스크립트 모두 실행되어야 하기 때문에 $ chmod u+x 명령어로 실행 권한을 부여해줬다.

 

마지막으로 $ ./myScript.sh 로 스크립트를 실행한 후에 1분을 기다리면 cron.log 파일이 생성된 것을 알 수 있다.

 

사용한 crontab_new 파일은 이제 필요 없으니 지워줘야 하는데 myScript.sh에서 자동으로 지워지게 위와 같이 rm crontab_new 라인을 추가했다.

 

잘 적용됐는지 확인하기 위해 $ tail -f cron.log 명령어를 실행해보면 매분 결과 내용이 추가되는 것을 확인할 수 있다.

cron으로 프로젝트 재시작

이번에는 스프링 서버가 종료되었을 때 자동으로 재시작하는 cron을 설정해보고자 한다.

먼저 스프링 서버가 실행되고 있는 상태에서$ netstat -ntlp 명령어로 8080 포트가 정상적으로 실행중인지 확인한 후 $ mkdir cron-restart 명령어로 cron-restart 디렉터리를 만든 뒤 해당 디렉터리로 이동한다.

 

이후 $ vi spring-stop.sh 명령어와 $ vi spring-restart.sh 명령어로 각각 스프링 서버를 종료, 재시작하는 스크립트를 생성한다. 각각의 내용은 다음과 같다.

 

spring-stop.sh

echo "SPRINGBOOT STOP..."
SPRING_PID=$(pgrep -f v1-0.0.1-SNAPSHOT.jar)
kill -9 $SPRING_PID

spring-restart.sh

SPRING_PID=$(pgrep -f v1-0.0.1-SNAPSHOT.jar)
SPRING_PATH="/home/ubuntu/aws-v1/build/libs/v1-0.0.1-SNAPSHOT.jar"

echo $SPRING_PID
echo $SPRING_PATH

# 서버가 종료되었는지 확인
# $SPRING_PID는 문자열이 아니기때문에 쌍따옴표로 감싸주기
if [ -z "$SPRING_PID" ]; then
  echo "스프링이 종료된 상태..."
  echo "스프링 재시작 - $(date)" 1>>/home/ubuntu/cron-restart/spring-restart.log
  nohup java -jar $SPRING_PATH 1>log.out 2>err.out &
else
  echo "스프링이 시작된 상태..."
fi

 

이후에 두 스크립트 모두 실행할 것이기 때문에 각각 $ chmod u+x 명령어로 실행 권한을 부여하였다.

위와 같이 spring-stop.sh 스크립트를 실행한 이후에 spring-restart.sh 스크립트를 실행하면 spring-restart.log 파일이 생기면서 스프링 서버가 다시 시작되는 것을 확인할 수 있다. 이제 cron에 등록하기 위한 deploy.sh 파일을 작성해볼 것이다.

 

deploy.sh

# 1. 배포 프로세스
echo "deploy start..."
echo "1. JDK install"
echo "2. github project download"
echo "3. gradlew 실행권한 주기"
echo "4. project build하기"
echo "5. ubuntu timezone setting하기"
echo "6. nohup으로 springboot 실행시키기"

# 2. 스프링서버 종료시 재시작
echo "crontab 등록 - spring restart..."
crontab -l > crontab_new
echo "* * * * * /home/ubuntu/cron-restart/spring-restart.sh" 1>>crontab_new
crontab crontab_new
rm crontab_new

위와 같이 deploy.sh를 작성한 후에 실행 권한을 부여한 뒤 $ crontab -e 명령어로 crontab에 등록된 스케줄이 있다면 모두 삭제한 뒤에 deploy.sh를 실행한 후 다시 $ crontab -e 명령어를 실행하면 새로운 스케줄이 생긴 것을 확인할 수 있다. 또한 spring-stop.sh를 실행한 후 서버가 종료된 것을 확인한 후 1분정도 뒤에 다시 확인해보면 다시 재시작한 것 또한 확인할 수 있다.


결론

이번엔 cron과 이를 이용한 자동화에 대해 공부했다. 공부하면서 계속 느끼는 거지만 아직까진 그렇게까지 어려울 것은 없는 것 같다. 스크립트만 정밀하게 잘 작성한다면 어렵지 않게 프로젝트 배포가 가능할 것 같다는 생각이 든다. 이제 V1 부분이 끝났는데 V5까지는 얼마나 오래 걸릴지.. 그래도 힘내서 끝내보자!

728x90
Comments