회사에서 운영하는 서비스에서 수정사항 반영 시 매번 EC2 인스턴스를 중단이 필요했고, 이때 서비스를 제공할 수 없기에 이를 해결하기 위하여 Nginx 를 활용한 무중단 배포 도입을 결정했다.
1. 아키텍처
2. 방법
- Spring Boot 애플리케이션을 기존 1개에서 2개로 추가 변경
- Nginx 관련 설정 파일(ex. nginx.conf 등) 수정하여 리버스 프록시 역할을 하도록 셋팅
- 배포 시 사용할 폴더 및 파일(ex. deploy.sh 등) 추가하여 해당 쉘 스크립트를 실행하면 배포가 진행되도록 셋팅
3. 상세
- 3.1. Nginx 관련 설정 파일 수정
- /etc/nginx 폴더에 nginx.conf 파일
- include /etc/nginx/sites-enabled/*; 로 작성된 부분이 있는데, 이는 해당 부분을 가져와 적용한다는 의미
- /etc/nginx/sites-enabled/default 파일 수정
server {
...생략...
underscores_in_headers on; // 해당 옵션을 설정해야 header 에 "_" 가 포함된 key를 사용 가능
...생략...
server_name XXX; // 수정 (EC2 인스턴스의 DNS 주소 입력)
location / {
include /etc/nginx/conf.d/service-url.inc; // 추가
proxy_pass $service_url; // 추가
proxy_set_header X-Real-IP $remote_addr; // 추가
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; // 추가
proxy_set_header Host $http_host; // 추가
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404; // 비활성화
}
}
- /etc/nginx/conf.d/service-url.inc 파일 생성 후 내용 추가
set $service_url http://127.0.0.1:8081;
- 3.2. 배포 시 사용할 폴더 및 파일 추가
- 폴더
- /home/ubuntu/bogus/nonstop
- /home/ubuntu/bogus/nonstop/api-server/build/libs
- /home/ubuntu/bogus/nonstop/jar
- 파일
- /home/ubuntu/bogus/nonstop/deploy.sh
- /home/ubuntu/bogus/nonstop/switch.sh
- 3.3. 배포 시 사용할 스크립트 파일 작성
- /home/ubuntu/bogus/nonstop/deploy.sh
#!/bin/bash
BASE_PATH=/home/ubuntu/bogus
BUILD_PATH=$(ls $BASE_PATH/build/libs/*.jar)
JAR_NAME=$(basename $BUILD_PATH)
echo "> build 파일명: $JAR_NAME"
echo "> build 파일 복사"
DEPLOY_PATH=$BASE_PATH/nonstop/jar/
rm $DEPLOY_PATH$JAR_NAME
cp $BUILD_PATH $DEPLOY_PATH
echo "> 현재 구동 중인 Profile 확인"
CURRENT_PROFILE=$(curl -s http://localhost/profile)
echo "> $CURRENT_PROFILE"
# 쉬고 있는 set 찾기: production 이 사용중이면 production-2 가 쉬고 있고, 반대면 production 이 쉬고 있음
if [ $CURRENT_PROFILE == production ]
then
IDLE_PROFILE=production-2
IDLE_PORT=8082
elif [ $CURRENT_PROFILE == production-2 ]
then
IDLE_PROFILE=production
IDLE_PORT=8081
else
echo "> 일치하는 Profile 이 없습니다. Profile: $CURRENT_PROFILE"
echo "> production 을 할당합니다. IDLE_PROFILE: production"
IDLE_PROFILE=production
IDLE_PORT=8081
fi
echo "> application.jar 교체"
IDLE_APPLICATION=$IDLE_PROFILE-api-server.jar
echo "> IDLE_APPLICATION: $IDLE_APPLICATION"
IDLE_APPLICATION_PATH=$DEPLOY_PATH$IDLE_APPLICATION
echo "> IDLE_PORT: $IDLE_PORT"
ln -Tfs $DEPLOY_PATH$JAR_NAME $IDLE_APPLICATION_PATH
echo "> $IDLE_PROFILE 에서 구동중인 애플리케이션 pid 확인"
IDLE_PID=$(sudo lsof -t -i :$IDLE_PORT)
if [ -z $IDLE_PID ]
then
echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다."
else
echo "> kill -15 $IDLE_PID"
kill -15 $IDLE_PID
sleep 5
fi
echo "> $IDLE_PROFILE 배포"
nohup java -jar -Dspring.profiles.active=$IDLE_PROFILE $IDLE_APPLICATION_PATH &
echo "> $IDLE_PROFILE 10초 후 Health check 시작"
echo "> curl -s http://localhost:$IDLE_PORT/"
sleep 10
for retry_count in {1..10}
do
response=$(curl -s http://localhost:$IDLE_PORT/)
echo "> response : $response"
up_count=$(echo $response | grep 'success' | wc -l)
if [ $up_count -ge 1 ]
then
echo "> Health check 성공"
break
else
echo "> Health check 의 응답을 알 수 없습니다."
echo "> Health check: ${response}"
fi
if [ $retry_count -eq 10 ]
then
echo "> Health check 실패"
echo "> Ngnix 에 연결하지 않고 배포를 종료합니다."
exit 1
fi
echo "> Health check 연결 실패. 재시도..."
sleep 10
done
echo "> 스위칭"
sleep 10
/home/ubuntu/bogus/nonstop/switch.sh
- /home/ubuntu/api-server/nonstop/switch.sh
#!/bin/bash
echo "> 현재 구동중인 Port 확인"
CURRENT_PROFILE=$(curl -s http://localhost/profile)
# 쉬고 있는 set 찾기: production 이 사용중이면 production-2 가 쉬고 있고, 반대면 production 이 쉬고 있음
if [ $CURRENT_PROFILE == production ]
then
IDLE_PORT=8082
elif [ $CURRENT_PROFILE == production-2 ]
then
IDLE_PORT=8081
else
echo "> 일치하는 Profile 이 없습니다. Profile: $CURRENT_PROFILE"
echo "> 8081을 할당합니다."
IDLE_PORT=8081
fi
echo "> 전환할 Port: $IDLE_PORT"
echo "> Port 전환"
echo "set \$service_url http://127.0.0.1:${IDLE_PORT};" |sudo tee /etc/nginx/conf.d/service-url.inc
PROXY_PROFILE=$(curl -s http://localhost/profile)
echo "> Nginx Current Proxy Profile: $PROXY_PROFILE"
echo "> Nginx Reload"
sudo service nginx reload
- 3.4. 스크립트 파일 실행
- /home/ubuntu/bogus/nonstop/deploy.sh
- 참고) deploy.sh 파일을 실행 과정에서 switch.sh 파일 실행
4. 참고
https://jojoldu.tistory.com/267
'IT > AWS' 카테고리의 다른 글
[AWS] DynamoDB 연동기 (1) | 2024.11.29 |
---|---|
[AWS] ECS Fargate 도입기 (0) | 2024.11.27 |