[DevOps] 스프링 서버 모놀리식 배포 - 배포스크립트 작성

Doccimann·2022년 4월 12일
0

본격적으로 글을 쓰기에 앞서

이번 포스트에서는 쉘스크립트를 작성해서 git pull부터 빌드해서 실행하기 까지의 과정을 자동화시키겠습니다. 글을 시작하겠습니다!


일단은 스크립트 작성 이전에 해야할 일이 있어요

일단은 이전에 clone받은 프로젝트 폴더를 들어가보겠습니다. 저는 order-example 라는 폴더에 프로젝트가 위치합니다.

우선은 이 폴더를 sources라는 폴더로 통째로 옮겨보겠습니다.

# sources 폴더 생성
mkdir sources
# order-example 폴더를 sources 폴더 내부로 옮기기
mv order-example ./sources/
# sources 폴더로 들어가기
cd sources

그리고 order-example로 들어가서 gradlew의 권한을 바꿔줍시다

# order-example 폴더로 들어가기
cd order-example
# gradlew의 권한 변경
chmod + ./gradlew
# 이전 디렉토리로 복귀
cd ..

이제 본격적으로 빌드스크립트를 작성하겠습니다.


빌드 스크립트를 작성하겠습니다

프로젝트 폴더가 있는 위치(sources)에서 빌드 스크립트를 작성하겠습니다. 일단 파일을 먼저 만들겠습니다.

vim deploy.sh

그리고 deploy.sh 라는 파일이 생성되었다면, 다음과 같이 스크립트를 입력합니다.

# 프로젝트 폴더가 위치해있는 디렉토리
REPOSITORY=/home/ec2-user/sources

# 프로젝트 디렉토리로 들어가기
cd $REPOSITORY/order-example

echo "> GIT PULL"

git pull

echo "> START TO BUILD PROJECT"

./gradlew build

echo "> COPY JAR FILES"

cp ./build/libs/*.jar $REPOSITORY/

echo "> 현재 구동중인 어플리케이션의 PID 확인"

CURRENT_PID=$(pgrep -f devops-test)

if [ -z $CURRENT_PID ]; then
        echo "현재 구동중인 APPLICATION이 없으므로 종료하지 않습니다."
else
        echo "kill -15 $CURRENT_PID"
        kill -15 $CURRENT_PID
        sleep 5
fi

echo "DEPLOY NEW APPLICATION"

JAR_NAME=$(ls $REPOSITORY |grep 'devops-test' | tail -n 1)

echo "JAR NAME : $JAR_NAME"

# nohup을 통한 무중단 배포
nohup java -jar $REPOSITORY/$JAR_NAME &

한 줄씩 해석해드리겠습니다.

# 프로젝트 폴더가 위치해있는 디렉토리
REPOSITORY=/home/ec2-user/sources

# 프로젝트 디렉토리로 들어가기
cd $REPOSITORY/order-example

일단은 프로젝트가 위치한 폴더 내부로 들어가기위한 코드입니다. REPOSITORY에는 pwd 커맨드를 통해서 획득한 sources의 디렉토리를 복사해서 넣어주면 됩니다.

git pull

만일 최신의 프로젝트가 존재한다면 pull을 하여 최신화 시켜줍니다.

./gradlew build

현재 저희의 프로젝트는 gradle 기반이기 때문에 위의 코드를 통해서 프로젝트를 빌드할 수 있습니다.

cp ./build/libs/*.jar $REPOSITORY/

빌드 결과로 생겨난 jar 파일들을 모두 REPOSITORY 주소로 복사합니다.

CURRENT_PID=$(pgrep -f devops-test)

if [ -z $CURRENT_PID ]; then
        echo "현재 구동중인 APPLICATION이 없으므로 종료하지 않습니다."
else
        echo "kill -15 $CURRENT_PID"
        kill -15 $CURRENT_PID
        sleep 5
fi

현재 이 프로젝트를 기반으로한 프로세스가 동작중이라면, 그 프로세스를 죽이고 새 프로세스를 실행하기 위한 코드입니다.

우선 CURRENT_PID에는 현재 프로젝트가 프로세스로 올라가있다면, 그 프로세스의 ID 값이 얼마인지 저장합니다. 저의 프로젝트 이름은 devops-test로 정했기 때문에 devops-test로 pgrep -f 옵션을 통해 검색을합니다.

만약에 PID 값이 존재한다면 프로세스를 kill 하고 5초를 sleep 걸어줍니다.

JAR_NAME=$(ls $REPOSITORY |grep 'devops-test' | tail -n 1)

REPOSITORY에서 디렉토리를 탐색하여서 'devops-test' 라는 이름을 가진 파일을 찾아내되, 이름이 겹치는 경우에는 최신의 파일을 가리키게 JAR_FILE 변수를 선언합니다.

nohup java -jar $REPOSITORY/$JAR_NAME &

nohup을 통해서 jar file을 무중단 실행시킵니다. &를 통해서 nohup을 통해 배포된 프로젝트가 백그라운드에서 동작하게 합니다.

이제 빌드스크립트를 모두 작성했으니, 이제 실행을 할 차레입니다.


이제 빌드스크립트를 실행하겠습니다

우선, deploy.sh의 권한을 먼저 변경하겠습니다.

chmod 755 ./deploy.sh

그 후에 deploy.sh를 실행합니다.

./deploy.sh

deploy.sh를 실행하면 다음과 같이 창이 뜨면서 프로젝트를 빌드하고, 동시에 배포를 진행합니다.

배포가 안정적으로 되었는지 체크하겠습니다. 본인의 인스턴스의 퍼블릭 ip를 통해서 http 요청을 하나 보내보겠습니다.

<인스턴스의 public ip>:<port>/api/shop/1

저의 경우에는, 52.78.182.130:8080/api/shop/1 주소로 http 요청을 하나 보냈습니다.

안정적으로 배포가 된 모습을 확인할 수 있습니다!


설마 혹시 이걸로 만족을 하십니까?

위와 같은 배포 방식에는 문제가 많은데요, 대표적인 문제점은 다음과 같습니다.

  • 다수의 트래픽을 감당하기에 무리가 있습니다. 왜냐하면, 하나의 인스턴스에 대해서 배포를 진행하고 있기 때문입니다.
  • 배포 인스턴스의 이미지를 이용해서 여러 인스턴스로 불려내서 Load Banlancing을 진행한다고 하더라도, 충분히 문제의 소지는 있습니다. 이 경우에는 각각의 instance를 직접 관리를 해야합니다.
  • 어찌저찌 관리를 한다고 하더라도, 장애 복구와 관련된 문제가 있습니다. 장애 복구가 자동화되어있지 않기 때문에 실제 서비스에서 이러한 방식을 채택한다면 크게 문제가 발생할 수도 있습니다.

그래서 다음부터 살펴볼 주제는, docker와 관련된 주제를 살펴보겠습니다. 그 후에 점점 범위를 넓혀가면서 MSA에 전반에 대해서 다뤄보는게 저의 목표입니다. 힘들겠지만요

그러면 이것으로 포스트를 마치겠습니다.

profile
Hi There 🤗! I'm college student majoring Mathematics, and double majoring CSE. I'm just enjoying studying about good architectures of back-end system(applications) and how to operate the servers efficiently! 🔥

0개의 댓글