2023.11.17 - [프로젝트 일지] - Spring boot + Github actions + AWS Code deploy 자동화배포 도전!
Spring boot + Github actions + AWS Code deploy 자동화배포 도전!
자동화 배포와 무중단배포를 구현하려고 하는 이유 제가 원래 배포하던 방식은 다음과 같았습니다. 인텔리제이에서 jar 파일을 빌드 한 후 FTP인 FileZilla를 사용하여 EC2에 jar 파일을 전송하고 EC2
sean-lets-go.tistory.com
처음 저의 배포방식에 대한 문제점은 다음과 같았습니다.
- main 브랜치에 푸쉬하고 배포를 하는 시점에 테스트가 진행되지 않는다.
- 개발자가 수동으로 해줘야 하는 작업들이 많다. (FTP로 jar 전송, EC2에서의 각종 명령어)
- 배포를 하는 도중에 서버가 10초정도 멈춘다. (무중단 배포 미구현)
- ec2에 전송되는 jar파일에 민감한 정보인 application.properties가 그대로 노출된다.
위의 문제점 중에서 3번 빼고는 해결이 된것 같습니다.
배포를 한다고 해도 클라이언트들에게 멈추지 않는 서비스를 제공해서 고가용성을 확보하는게 좋습니다.
무중단 배포에관한 글은 무중단 배포 간단하게 알아보기 를 참고하시면 됩니다.
지난 시간까지 자동화배포를 구현하면서, 사진에서의 빨간색 박스친 부분을 제외하고 나머지 부분을 완료했습니다.
작성했던 파일들을 수정하고, nginx를 사용하면서 무중단배포를 구현해보겠습니다.
- 개발환경
프로젝트: Spring boot
빌드툴: Gradle
JDK: openjdk 17
💻 개요
Part.1 Nginx 설치와 설정
- Nginx 설치
- Nginx 설정
Part.2 배포 스크립트 추가
- 새로운 script 작성
- appspec.yml 수정
Part.3 무중단 배포 🚀
Part.4 확인
Part.5 여러 오류에 대하여...
Part.6 번외...
🧭 Part.1 Nginx 설치와 설정
1) Nginx 설치
putty와 같은 ssh로 EC2에 접속한 다음 커맨드를 입력합니다.
(Ubuntu Linux기준입니다, RedHat과는 명령어가 다를 수 있습니다.)
#시스템 업데이트
sudo apt update
sudo apt upgrade
#Nginx 설치
sudo apt install nginx
#방화벽 설정
sudo ufw allow 81/tcp
sudo ufw allow 82/tcp
# 설치 버전 확인
sudo nginx -v
2) Nginx 설정
cd /etc/nginx/
설치 후 /etc/nginx/
로 이동해 보시면 다양한 nginx 설치파일들을 보실 수 있는데요.우리가 관심있게 보아야 할 것은 설정파일인 nginx.conf
파일입니다.
저는 해당 환경을 설정하는 부분에서 많은 고생을 했었습니다.
다른 참조글을 보면 nginx.conf
파일을 열어보면
요렇게 server의 내용이 적혀있을거라 했지만,
적용하고 있는 환경이 Ubuntu여서 인지, 아님 버전이 최신이여서 그런지 몰라도 참조글과는 다른 형태였습니다.
/etc/nginx/nginx.conf
에서 reverse proxy를 수정하는 참조글들이 많지만, 최신 Nginx에서는 직접적으로 파일을 수정해도 정상적으로 작동하지 않는것 같기도 합니다.
따로 폴더를 만들고 그 안에 설정파일들을 만들어 Symbolic link를 걸어주도록 하겠습니다.
우선 nginx.conf
의 내용을 다 지워줍니다.
지우는 방법은 아래와 같습니다.
gg #글 제일 처음으로 이동
shift+v+g #전체선택
d #지우기
다 지운상태에서 밑의 내용을 복사, 붙여넣기 해주시면 됩니다.
linux에 붙여넣기 할 때는 커서에 마우스 오른쪽 클릭하면 됩니다.
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
다 작성했다면, esc → :wq! 입력
이후 ls -al
을 통해 sites-available과 sites-enabled 폴더가 있는지 확인하고, 없으면 만들어줍니다.
sudo mkdir /etc/nginx/sites-available
sudo mkdir /etc/nginx/sites-enabled
이후 sites-available 디렉토리로 이동하여 default
파일을 만들어줍니다.
cd /etc/nginx/sites-available
sudo vim default
이후 다음과 같이 작성해줍니다.
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
include /home/ubuntu/spring-github-action/service_url.inc;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_Host;
proxy_pass $service_url;
}
# Load configuration files
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
- include - 다른 곳에 존재하는 설정 파일 등을 불러 올 수 있습니다.
- proxy_pass - 우리가 지정할 $service_url로 요청을 보낼 수 있도록 하는 프록시 설정입니다.
include로 불러올 파일경로에 다음과 같이 파일을 생성하고 $service_url 변수를 설정하겠습니다.
(추후 CI/CD 과정에서 쉘 스크립트를 통해 위 포트가 8081 또는 8082로 전환됩니다)
vim /home/ubuntu/spring-github-action/service_url.inc
set $service_url http://127.0.0.1:8082;
이후 위에서 언급한 심볼릭 링크를 만들어줍니다.
sudo ln -s /etc/nginx/sites-available/defualt /etc/nginx/sites-enabled/default
이후 Nginx가 정상적인지 테스트하고 재실행합니다.
sudo service nginx status
#sudo service nginx status를 입력 후 active 상태라면 nginx 웹서버가 실행되고 있는 중
sudo service nginx restart
🧭 Part.2 배포 스크립트 추가
1) 새로운 script 작성
- start, stop.sh 파일은 사용하지 않고, 새로운 sh파일 3개를 만들 예정입니다.
(start, stop.sh 파일은 이전 포스팅에서 만든 파일입니다)
script를 보면 각각의 로그는 해당 로그파일에 저장되도록 했습니다.
혹시 어떤 문제가 생기면 해당 로그파일을 열어보고 문제 원인 파악하시면 됩니다.
1-1) run_new_was.sh
# run_new_was.sh
#!/bin/bash
ROOT_PATH="/home/ubuntu/spring-github-action" # 프로젝트 루트
JAR="$ROOT_PATH/application.jar"
SERVICE_URL="$ROOT_PATH/service_url.inc"
APP_LOG="$ROOT_PATH/application.log"
ERROR_LOG="$ROOT_PATH/error.log"
START_LOG="$ROOT_PATH/start.log"
NOW=$(date +%c)
# service_url.inc 에서 현재 서비스를 하고 있는 WAS의 포트 번호 가져오기
CURRENT_PORT=$(cat $SERVICE_URL | grep -Po '[0-9]+' | tail -1)
TARGET_PORT=0
echo "[$NOW] Current port of running WAS is ${CURRENT_PORT}." >> $START_LOG
if [ ${CURRENT_PORT} -eq 8081 ]; then
TARGET_PORT=8082 # 현재포트가 8081이면 8082로 배포
elif [ ${CURRENT_PORT} -eq 8082 ]; then
TARGET_PORT=8081 # 현재포트가 8082라면 8081로 배포
else
echo "[$NOW] Not connected to nginx" >> $START_LOG # nginx가 실행되고 있지 않다면 에러 코드
fi
# 현재 포트의 PID를 불러온다
TARGET_PID = $(sudo lsof -ti tcp:${TARGET_PORT})
# PID를 이용해 해당 포트 서버 Kill
if [ ! -z ${TARGET_PID} ]; then
echo "[$NOW] Kill -9 ${TARGET_PORT}." >> $START_LOG
sudo kill -9 ${TARGET_PID}
fi
cp $ROOT_PATH/build/libs/*.jar $JAR
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp -m tcp --dport 81 -j REDIRECT --to-port 8081
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp -m tcp --dport 82 -j REDIRECT --to-port 8082
# 타켓 포트에 jar파일을 이용해 새로운 서버 실행
sudo nohup java -jar -Dserver.port=${TARGET_PORT} ${JAR} > $APP_LOG 2> $ERROR_LOG &
SERVICE_PID=$(pgrep -f $JAR)
echo "[$NOW] > $JAR 실행 $TARGET_PORT Port / 서비스 PID: $SERVICE_PID" >> $START_LOG
exit 0
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp -m tcp --dport 81 -j REDIRECT --to-port 8081
명령어는 포트 포워딩 설정에 관한 내용입니다.
81번 포트로 들어오는 요청을 8081번 포트로 리다이렉트하여 백엔드 서비스를 실행하고 있는 다른 프로세스에 전달할 수 있습니다.
해당 명령어를 작성하면 주소창에 각각의 포트를 적어주지 않아도 됩니다.
위 스크립트 파일은 위에서 만든 service_url.inc 파일을 통해 현재 서비스를 하고 있는 WAS의 포트 번호를 가져오고 이를 토대로 8081 또는 8082 포트로 서버가 배포되며 최신화됩니다.
1-2) health_check.sh
# health_check.sh
#!/bin/bash
ROOT_PATH="/home/ubuntu/spring-github-action" # 프로젝트 루트
SERVICE_URL="$ROOT_PATH/service_url.inc"
ERROR_LOG="$ROOT_PATH/error.log"
START_LOG="$ROOT_PATH/start.log"
NOW=$(date +%c)
# service_url.inc 에서 현재 서비스를 하고 있는 WAS의 포트 번호 가져오기
CURRENT_PORT=$(cat $SERVICE_URL | grep -Po '[0-9]+' | tail -1)
TARGET_PORT=0
if [ ${CURRENT_PORT} -eq 8081 ]; then
TARGET_PORT=8082
elif [ ${CURRENT_PORT} -eq 8082 ]; then
TARGET_PORT=8081
else
echo "[$NOW] No WAS is connected to nginx" >> $ERROR_LOG
exit 1
fi
# 위 커맨드들을 통해 현재 타겟포트 가져오기
echo "[$NOW] Start health check of WAS at 'http://127.0.0.1:${TARGET_PORT}' ..." >> $START_LOG
# 아래 커맨드들을 새로 열린 서버가 정상적으로 작동하는지 확인
# 해당 커맨드들을 10번씩 반복
# 원래는 for RETRY_COUNT in {1..10}였으나, Bash 버전의 문제인지 1번만 실행되는 오류가 있음
for RETRY_COUNT in 1 2 3 4 5 6 7 8 9 10
do
echo "[$NOW] #${RETRY_COUNT} trying..." >> $START_LOG
sleep 40 #스레드 기아문제를 해결하기 위해 처음부터 기다렸다가 시작
# 테스트할 API 주소를 통해 http 상태 코드 가져오기
RESPONSE_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:${TARGET_PORT}/{api 주소} 2>> $START_LOG)
# RESPONSE_CODE의 http 상태가 200번인 경우
if [ ${RESPONSE_CODE} -eq 200 ]; then
echo "[$NOW] New WAS successfully running" >> $START_LOG
exit 0
elif [ ${RETRY_COUNT} -eq 10 ]; then
echo "[$NOW] Health check failed." >> $ERROR_LOG
exit 1 #exit 1이 호출되면 스크립트의 실행이 중단되고, 이에 따라 switch.sh 스크립트도 실행되지 않습니다.
fi
# 아직 열려있지 않았다면 sleep
echo "[$NOW] RESPONSE_CODE $RESPONSE_CODE / Not yet...sleep 40" >> $START_LOG
done
위 스크립트 파일은 새로 열린 서버가 정상적으로 작동하는지 확인하는 코드입니다. for 문을 통해 서버가 열리는 시간을 고려하여 healthcheck를 진행하며 200번인경우 정상적으로 돌아가는지 확인이 완료된다. 서버가 열리지 않은 상태라면 sleep 40 을 통해 잠시 기다리게 되며 다시한번 RESPONSE_CODE의 http 상태 코드를 검사하여 총 for문에 기재된대로 10번 반복합니다.
몇번 시도해본 결과, 서비스가 시작되는 시간이 있기에 처음부터 sleep 40을 해주는것이
성능적으로 낫다고 판단하여 for문이 시작되자마자 40초를 기다리게 하였습니다.
{api주소} 적는 부분은, 별로로 api check를 해주는 컨트롤러를 만들 필요를 못느껴서
로그인 페이지를 호출하는것으로 저는 작성하였습니다.
1-3) switch.sh
# switch.sh
#!/bin/bash
ROOT_PATH="/home/ubuntu/spring-github-action" # 프로젝트 루트
SERVICE_URL="$ROOT_PATH/service_url.inc"
ERROR_LOG="$ROOT_PATH/error.log"
START_LOG="$ROOT_PATH/start.log"
NOW=$(date +%c)
# service_url.inc 에서 현재 서비스를 하고 있는 WAS의 포트 번호 가져오기
CURRENT_PORT=$(cat $SERVICE_URL | grep -Po '[0-9]+' | tail -1)
TARGET_PORT=0
echo "[$NOW] Nginx currently proxies to ${CURRENT_PORT}." >> $START_LOG
if [ ${CURRENT_PORT} -eq 8081 ]; then
TARGET_PORT=8082
elif [ ${CURRENT_PORT} -eq 8082 ]; then
TARGET_PORT=8081
else
echo "[$NOW] No WAS is connected to nginx" >> $ERROR_LOG
exit 1
fi
#2개의 application이 실행되는것은 과부하 일수도?
# 과거 포트의 PID를 불러온다
OLD_PID = $(sudo lsof -ti tcp:${CURRENT_PORT})
# PID를 이용해 해당 포트 서버 Kill
if [ ! -z ${OLD_PID} ]; then
echo "[$NOW] Kill -9 ${CURRENT_PORT}." >> $START_LOG
sudo kill -9 ${OLD_PID}
fi
# 위 커맨드들을 통해 현재 타겟포트 가져오기
# $ service_url.inc 파일을 현재 바뀐 서버의 포트로 변경
echo "set \$service_url http://127.0.0.1:${TARGET_PORT};" | tee $SERVICE_URL
echo "[$NOW] Now Nginx proxies to ${TARGET_PORT}." >> $START_LOG
# nginx를 reload 해준다.
sudo service nginx reload
echo "[$NOW] Nginx reloaded." >> $START_LOG
위 스크립트는 healthcheck가 완료된 시점이며, WAS의 현재포트 번호를 통해 새로 실행할 타겟 포트를 가져오며 WAS의 포트번호를 타겟 포트로 변경해주고 nginx를 reload 해줍니다.
참고로 reload 커맨드를 입력해준 이유는 nginx 서버의 재시작 없이 바로 새로운 설정값으로 서비스를 이어나갈 수 있도록 하기위함입니다. restart의 경우 서버가 재시작 되므로 잠시 중지되는 과정이 발생하기에 사용하지 않습니다.
2) appspec.yml 수정
- 이전에 start, stop.sh 파일을 사용했던 코드에서, 새로 만들어진 파일을 사용하도록 변경해줍니다.
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/spring-github-action
overwrite: yes
permissions:
- object: /
owner: ubuntu
group: ubuntu
hooks:
ApplicationStart:
- location: scripts/run_new_was.sh
timeout: 60
- location: scripts/health_check.sh
timeout: 60
- location: scripts/switch.sh
timeout: 60
Part.3 무중단 배포 🚀
이전포스팅때와 같은 방법으로, 코드를 커밋&푸쉬 하면 → Actions에 의하여 CI/CD가 진행됩니다.
- start.log를 보시면 어떤 포트에서 시작해서 → 다른 포트에서 서비스를 실행하고 → 정상 작동 되는지 헬스체크를 하고 → 새롭게 서비스를 한 포트로 swtich 까지 한 로그를 확인할 수 있습니다.
오류가 난다면 로그가 정상적으로 쌓인다는 가정하에 눈에 불을 키고 봐야할 로그는 다음과 같습니다. 해당 로그는 ec2의 spring-github-action폴더에 있는 파일들입니다.
또한 nginx의 로그도 봐줘야합니다.
봐야할 폴더를 정리해드리겠습니다.
cd /var/log/nginx/ #nginx에 대한 로그가 쌓이는 곳
cd /etc/nginx/ #nginx에 대한 환경설정을 하는 곳
cd /home/ubuntu/spring-github-action/ #우리의 서비스에 대한 로그가 쌓이는 곳
Part.4 확인
무중단 배포를 성공한다면, 앞서 말씀드린것 처럼 start.log 파일을 열어서 정상적으로 ‘reloaded’로그가 찍혔는지 확인하시면 됩니다.
그럼 정상적으로 페이지가 열리는것을 확인할 수 있습니다.
Part.5 여러 오류에 대하여…
무중단배포를 구현하면서 많은 오류를 만났는데, 그중 대표적이였던 몇몇 문제를 소개해드릴까 합니다.
1) nginx.conf 파일 수정 문제
- 현재 nginx의 상태를 확인해봤더니
nginx: [emerg] unknown directive "vi" in /etc/nginx/nginx.conf:6
오류가 발생했습니다.
ubuntu@ip-172-31-3-161:~/spring-github-action$ systemctl status nginx.service
× nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sat 2023-11-11 20:47:51 KST; 35s ago
Docs: man:nginx(8)
Process: 1614 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=1/FAILURE)
CPU: 3ms
Nov 11 20:47:51 ip-172-31-3-161 systemd[1]: Starting A high performance web server and a reverse proxy server...
Nov 11 20:47:51 ip-172-31-3-161 nginx[1614]: nginx: [emerg] unknown directive "vi" in /etc/nginx/nginx.conf:6
Nov 11 20:47:51 ip-172-31-3-161 nginx[1614]: nginx: configuration file /etc/nginx/nginx.conf test failed
Nov 11 20:47:51 ip-172-31-3-161 systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
Nov 11 20:47:51 ip-172-31-3-161 systemd[1]: nginx.service: Failed with result 'exit-code'.
Nov 11 20:47:51 ip-172-31-3-161 systemd[1]: Failed to start A high performance web server and a reverse proxy server.
요 케이스는 오류 메세지가 친절하게 나와서 쉽게 해결할 수 있었습니다.
nginx.conf 파일을 실수로 삭제해버려서 초기설정을 구글링해서 넣어주었는데
빨간박스의 vi 부분에서 문제가 발생해서 nginx start가 안되고 있었습니다.
(빨간 박스 부분을 제거하면 되고, Part1 과정을 따라오셨다면 이문제는 발생하지 않을겁니다)
2) Thread starvation or clock leap detected 문제
- 무중단 배포를 하던 도중 서버가 다운되버려서 application.log를 살펴보니 Thread starvation or clock leap detected 문제가 발생하고 있었습니다.
2023-11-11 21:06:05.724 WARN 1814 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=50s559ms47µs404ns).
2023-11-11 21:08:11.942 WARN 1814 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=4m23s526ms676µs451ns).
2023-11-11 21:09:32.742 WARN 1814 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=1m18s695ms47µs52ns).
start.log를 확인해보니 #3 trying을 하고, 4번째 trying을 못하고 죽어버렸습니다.
(시도 했을 때 성공 or 실패 or 다시 시도 이기 때문에, 성공/실패가 아니라면 다시 시도해야합니다)
구글링을 하다가 요런 글을 발견했습니다.
인스턴스 상태검사 실패, Thread starvation or clock leap detected, Dead Lock, hikari 오류-1
이 글에서는 스레드가 Connection을 할당받지 못해서 생기는 문제로
application.properties
의 설정을 변경하는 식으로 해결했습니다.
(이전 포스팅을 참고하면 아시겠지만, github에서 secret 부분을 수정해주셔야합니다)
spring.datasource.hikari.maximum-pool-size=20
3) Access to DialectResolutionInfo cannot be null when 'hibernate.dialect
- 요문제가 발생한다면 위와 마찬가지로
application.properties
설정에 내용을 추가해주면됩니다. (저는 mariadb를 사용하였습니다)
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
Part.6 번외…
1) 연속으로 배포하면 Die
행복회로를 돌리면 8081 포트로 서비스되다가 → 자연스럽게 8082 포트로 변경이 되고
사용자는 눈치를 채지 못하는 상황을 기대했었습니다.
하지만,,, 크나큰 문제가 생겼습니다.
Green&Blue 무중단배포를 진행하던중, healthCheck 하는 부분에서 EC2-CPU의 급격한 사용률을 견디지 못해 죽어버리는 상황이 계속 생겼습니다.
처참하게 404 에러까지 뱉어버리는 nginx…
어느 부분에서 문제가 발생하는것인지 체크하기 위해, 문제를 계속해서 발생시켜보았습니다.
처음 무중단배포는 정상적으로 되는듯 보이지만 3번 연속으로 배포를 하면 cpu사용률 high를 기록하며 터져버렸습니다.
왜 항상 3번째에서 실패하는지 잘 모르겠다…
3번째 무중단배포중에 터짐
이후 putty를 접속하려고 하면, 이미 EC2가 망가진터라 빈화면을 보여줍니다.
2) 한번 배포할 때 요청을 마구 보내면 Die
그럼 한번만 배포하는 대신에, switch되는 시점에 요청을 마구 보내보면 어떨지 궁금해졌습니다.
해당 테스트를 위해 매크로 편집기를 다운받았습니다.
설정은 5초마다 새로고침으로 Get 요청을 계속 보내려고 합니다.
우선 배포를 하지 않고 새로고침(F5)을 계속 해보았더니 아래와 같은 결과가 나왔습니다.
위의 매크로 설정과는 다르게 로그인 페이지를 1초에 한번씩 2분정도 새로고침을 했지만 cpu 사용률 3%이내에서 머무르는것을 볼 수 있습니다.
그럼 배포를 하지 않을 때 문제 없는 새로고침 테스트를 배포를 진행하면서 진행해보겠습니다.
서버응답을 기다리면서 504 에러가 나왔고
code deploy를 확인해보니 무한루프에 걸려있었습니다.
배포시점인 15시를 기준으로 cpu 사용률이 high를 찍고 터진것을 볼 수 있습니다.
이후 EC2 재부팅을 하면 당연히 원래대로 돌아옵니다.
1,2 번의 사례를 종합해보면 문제는 다음과 같습니다.
- 연속으로 계속해서 배포를 시도하면 Die
- 연속으로 안하더라도, 배포 중간에 요청을 많이 보내면 Die
- 스레드 기아 문제 같은것들이 아직 해결이 안되서 Die
무중단 배포를 구현하고 위의 문제를 해결하려고 시도를 하다보니 일주일이란 시간이 흘렀고, 요 주제에 대해서 살짝 과열이 온것 같습니다…
위의 문제에 대한 솔루션은 차차 알아보고, 후기를 포스팅하도록 하겠습니다.
제가 생각해본 해결 솔루션은 다음과 같습니다.
- EC2가 프리티어라 Die → 그렇다면 EC2의 성능이 좋으면 괜찮을지?
- nginx의 로드밸런싱 방식이 별로? → auto scaling, aws 로드 밸런서를 적용해보면?
(https://jeonghoon.netlify.app/AWS/aws_bluegreen/) - 스레드 기아 문제를 최적화 해서 해결해본다면?
자동화 배포에 비해 무중단 배포는 많은 시행착오가 있는것 같습니다..
'DevOps > CI & CD' 카테고리의 다른 글
CI/CD Pipeline 그리기 by draw.io (0) | 2024.03.12 |
---|---|
GKE-Argo CD failed to provision volume, QUOTA_EXCEEDED 오류 (1) | 2024.02.25 |
스무스한 자동화 배포 도전! (boot+Github actions+Code deploy) (0) | 2023.11.17 |