spring boot 애플리케이션을 중단 없이 배포하기.

중단은 없지만 세션 클러스터를 하지 않으면 배포 시 세션을 잃게 된다.

 

1. 서비스URL 설정 파일 생성 및 설정

 - 포트는 8009, 8019를 번갈아 가면서 사용

vi /etc/nginx/conf.d/service-url.inc

set $service_url http://127.0.0.1:8009;

 

2. Nginx 설정

 - 생성한 service-url.inc 파일 include

 - 주의 : 꼭 server 안쪽에 include 해야 함.

 - proxy_pass 변경

server {
        include /etc/nginx/conf.d/service-url.inc;
        listen 80;
        listen 81;
        server_name localhost;

        location / {
                proxy_buffer_size 128k;
                proxy_buffers 4 256k;
                proxy_busy_buffers_size 256k;
                proxy_pass $service_url;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

 

3. 서비스 파일 생성

 - 기존 사용하던 서비스 파일을 복사하여 프로파일만 다른 서비스 하나 더 생성

#!/bin/bash
[Unit]
Description=site1
After=syslog.target

[Service]
ExecStart=/home/java/jdk-17/bin/java -Dspring.profiles.active=SERVICE -jar /data/site-0.0.1-SNAPSHOT.jar
SuccessExitStatus=143


[Install]
WantedBy=multi-user.target



#!/bin/bash
[Unit]
Description=site2
After=syslog.target

[Service]
ExecStart=/home/java/jdk-17/bin/java -Dspring.profiles.active=SERVICE2 -jar /data/site-0.0.1-SNAPSHOT.jar
SuccessExitStatus=143


[Install]
WantedBy=multi-user.target

 

4. 프로퍼티 생성

 - 기존 사용하던 서비스 프로퍼티를 복사하여 하나더 생성

 - 기존 서버 포트 : 8009

 - 추가 서버포트 : 8019

추가된 프로퍼티 파일

 

5. 쉡 스크립트 작성

 - 구글에서 검색해보면 실행 중인 PID를 찾아서 Kill 하는 것이 대부분 이였는데 나는 그냥 서비스를 하나 더 만들었다..

#!/bin/bash
BASE_PATH=/data
BUILD_PATH=$(ls $BASE_PATH/deploy/site-0.0.1-SNAPSHOT.jar)
JAR_NAME=$(basename $BUILD_PATH)
echo "> build 파일명: $JAR_NAME"

echo "> 현재 구동중인 Profile 확인"
CURRENT_PROFILE=$(curl -s http://localhost/back/profiles)
echo "> $CURRENT_PROFILE"

# 쉬고 있는 Profile 찾기: SERVICE가 사용중이면 SERVICE2가 쉬고 있고, 반대면 SERVICE이 쉬고 있음
if [ $CURRENT_PROFILE == SERVICE ]
then
  IDLE_PROFILE=SERVICE2
  IDLE_PORT=8019
elif [ $CURRENT_PROFILE == SERVICE2 ]
then
  IDLE_PROFILE=SERVICE
  IDLE_PORT=8009
else
  echo "> 일치하는 Profile이 없습니다. SERVICE을 할당합니다. IDLE_PROFILE: SERVICE"
  IDLE_PROFILE=SERVICE
  IDLE_PORT=8009
fi

echo "> build 파일 복사"
DEPLOY_PATH=$BASE_PATH/web/site-0.0.1-SNAPSHOT.jar
cp $BUILD_PATH $DEPLOY_PATH

echo "> 재시작"
if [ $CURRENT_PROFILE == SERVICE ]
then
  systemctl restart site2
elif [ $CURRENT_PROFILE == SERVICE2 ]
then
  systemctl restart site1
else
  systemctl restart site1
fi

echo "> sleep 5 -> health "
sleep 5
echo "> curl -s http://localhost:$IDLE_PORT/back/healths "

for retry_count in {1..10}
do
  response=$(curl -s http://localhost:$IDLE_PORT/back/healths)
  up_count=$(echo $response | grep 'UP' | wc -l)

  if [ $up_count -ge 1 ]
  then # $up_count >= 1 ("UP" 문자열이 있는지 검증)
      echo "> Health check 성공"
      echo "> Nginx 스위칭"
      echo "set \$service_url http://127.0.0.1:${IDLE_PORT};" |sudo tee /etc/nginx/conf.d/service-url.inc
      echo "> Nginx Reload"
      sudo service nginx reload
      echo "> sleep 3 ->  사용 안하는 서비스 중지"
      sleep 3
      echo "> 사용 안하는 서비스 중지"
      if [ $CURRENT_PROFILE == SERVICE ]
	then
	  systemctl stop site1
	elif [ $CURRENT_PROFILE == SERVICE2 ]
	then
	  systemctl stop site2
	else
	  systemctl stop site2
      fi
      break
  else
      echo "> Health check의 응답을 알 수 없거나 혹은 status가 UP이 아닙니다."
      echo "> Health check: ${response}"
  fi

  if [ $retry_count -eq 10 ]
  then
    echo "> Health check 실패. "
    echo "> Nginx에 연결하지 않고 배포를 종료합니다."
    exit 1
  fi

  echo "> Health check 연결 실패. 재시도..."
  sleep 10
done

 

6. 실행 결과

 - Nginx Reload가 끝나고 기존 사용되던 서비스가 종료되어야 정상 배포 완료.

쉘 스크립트 실행 결과

 

끝!!!

'서버설정 및 설치 > SERVER' 카테고리의 다른 글

Centos nexus 설치  (0) 2021.09.24
Centos7 gitlab 설치 및 nginx 연동  (0) 2021.09.24
centos nginx 설치  (0) 2020.11.24
centos bitcoind 설치  (0) 2020.03.27
Spring Boot - jar로 서비스 등록  (0) 2020.03.27