Spring

AWS - 배포와 기록(Spring boot)

jaewoo 2023. 4. 14. 17:25

우리 프로젝트 배포는 AWS EC2와 S3 만 사용했고 Spring Boot (gardle) 로 배포진행 그리고 ubuntu 사용함

 

일단 먼저 겪었던 문제점들

1. Ubuntu는 맨 앞에 / 를 인식하지 못한다. -> 컨트롤러에서 view 이름을 보낼때 앞에 / 가 있으면 해당 경로를 인식하지 못하고 파일을 못 찾는다는 말이 나오게 된다 컨트롤러에서 view 이름에  / 는 제거가 필요하다.

 

2. 메모리는 2기가 이상 서버를 유지해야한다. -> 테스트를 위해 t2.nano(0.5) 테스트 했을 때 docker 이미지를 다운 받는 과정에서 바로 서버가 터졌다. t2.micro(1) 로 다시 올려서 진행했는데 docker 이미지를 다운받는 거 까지와 openjdk를 다운 받는거 까지는 문제가 없었다. 여기서 build를 실행하다가 바로 터져버렸다.....

  두 번이나 터지고 나니 자료조사를 많이 하고 다시 시도하는데 t2.small(2)로 진행을 했다. 근데 이번에도 터질 거 같아 이번에는 애초에  시작부터 SWAP 메모리를 지정하고 사용했다.(RAM이 부족할 경우 HDD의 일정공간을 RAM처럼 사용한다) 근데 이번에는 docker 이미지를 다운 받고 openjdk를 다운 받는데 처음보는 에러가 나왔다. 너무 당황스러웠는데 이번에는 메모리가 아닌 디스크 부족으로 인해 다운 할 수 없었다. t2.small 설정할 떄 스토리지를 8기가로 설정하고 했었다. 근데 여기서 문제는 SWAP인 거 같았다. 메모리를 늘리려고 디스크를 사용하니 디스크 사용 가능 용량이 df -h로 조회하니 7.6기가 중에 7.6기가를 사용 중이었다. 그래서 해당 서버를  다시 내리고 t2.medium(4)에 스토리지 20기가로 진행했다.

E: dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.
//메모리 부족 에러

 

3. 도커 컨테이너 인코딩 문제 -> mysql을 도커 컨테이너로 실행했는데 호텔 이름들이 전부 ???? 로 나오는 결과가 나왔다. 웬만한 인코딩 설정이랑 컨테이너 실행할 때 설정까지 모두 하고 진행했는데도 당황스러웠는데 애초에 서버 인코딩 문제가 아닌 도커 컨테이너 문제였다.  해당 명령어로 바꿔주면 바로 해결된다.

docker exec -it <컨테이너_이름> bash
export LANG=en_US.UTF-8

 

 

다음부터 꼭 체크해야할 것

1. 경로에서 다음 경로로 넘어갈 떄 주어지는 파라미터 테스트 - > 비정상적 접근도 체크하는 테스트 코드가 필요하다.

2. 모든 기능은 UI로 동작할 수 있도록 만들어야 한다. 

3. 시간이 된다면 모든 테스트는 작성해한다. 아니라면 최소한 DB에 들어가는 값과 컨트롤러에서 넘어가는 파라미터저옫는 체크해야한다.

4. 배포 전 가상머신으로 테스트를 진행해야한다. -> 진행하면서 메모리, 디스크 용량을 얼마나 잡는지 체크가 필요하다.

 

배포 순서


 EC2 인스턴스를 빌릴 때 가장 중요한건 어떤 인스턴스인지와 각 메모리 스토리지 정도 꼭 체크해야 함

 

1. EC2 접속하면 가장 먼저 프로젝트에 적용된 jdk 다운

sudo apt-get update  # 패키지 목록 업데이트
sudo apt-get install openjdk-11-jdk  # OpenJDK 11 설치

 

2. Container를 사용하기에 docker를 다운하고 각 container를 실행해야 한다. 프로젝트에서는 Redis와 Mysql이 적용된다.

https://shanepark.tistory.com/237

 

Ubuntu 20.04 LTS ) Docker 설치하기

Intro Docker는 제가 회사에서 사용하는 노트북의 OS를 Windows 에서 Ubuntu 로 변경하게 된 트리거 였습니다. Docker를 사용하면 정말 편하게 격리된 컨테이너들을 구성해 가상화의 장점을 정말 잘 살릴

shanepark.tistory.com

 

MYSQL

docker run -d -e MYSQL_ROOT_PASSWORD=1234 -e MYSQL_DATABASE=hotel -e MYSQL_USER=user -e MYSQL_PASSWORD=1234 -e TZ=Asia/Seoul -e MYSQL_CHARACTER_SET_SERVER=utf8mb4 -e MYSQL_COLLATION_SERVER=utf8mb4_unicode_ci -p 3306:3306 --name mysql mysql:8.0.29

주의할 점 - 현 프로젝트 (Spring Boot)에 맞는 mysql 버전이 필요하다. -> 버전 호환 때문에 에러나서 버전을 맞췄음

또 주의할 점 - 컨테이너를 종료하고 rm시 데이터가 삭제된다. 그래서 컨테이너를 생성할 때 -v 옵션을 먼저 주는 것이 좋다. -v 옵션은 Docker 컨테이너와 호스트 시스템 간에 데이터를 공유하는 Docker 볼륨을 설정할 수 있도록 해준다.

docker run -d -p 3306:3306 \
-v /path/to/host/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=mysecretpassword \
--name my-mysql-container \
mysql:tag

/path/to/host/mysql/data 는 호스트 시스템의 디렉토리 경로

/var/lib/mysql는 컨테이너 내부의 데이터 디렉토리 경로

 

Redis

docker run -d --name redis-container redis:latest

Redis는 버전 상관없이 최신버전을 실행하면 문제없이 작동한다.

 

3. 프로젝트 git clone 

git clone 을 하려면 먼저 git을 ubuntu에 다운 받아야 한다. 

sudo apt-get update  # 패키지 목록 업데이트
sudo apt-get install git  # Git 설치

그러고 나서 바로 git clone을 진행 한다.

 

 

4. 프로젝트 빌드 

clone하고 프로젝트를 열면 프로젝트에 build 디렉토리가 존재하지 않는다. 해당 디렉토리는 build 후에 생기기 때문에 build를 해줘야한다. build는 gradlew를 통해 build를 할 수 있다. 하지만 전에 권한 설정이 필요

빌드 명령어에 여러가지 추가가 가능하다.

sudo chmod 777 gradlew
./gradlew build 
./gradlew build -x test
./gradlew clean build -x test

 

 

5. 우리 프로젝트의 경우 booking-module(Batch 프로그램)이기 때문에 해당 모듈로 서버에 데이터를 담아야 한다. 해당 모듈을 먼저 buiild하고 jar를 실행해야 하는데 이때 환경변수를 주입해야한다. 

java -DLOCALHOST=$PRIVATEIP4 -DREDISPORT=$REDISIP -jar booking-module-0.0.1-SNAPSHOT.jar

OS에 환경변수로 등록해서 해당 변수를 바로 주입해도 괜찮고 바로 넣어도 상관없다. 여기서 프라이빗 ip4의 경우 aws ec2에서 확인 가능하다 프라이빗 ip4 라고 적혀있는 주소를 적어주면 된다. 

redis port는 도커 컨테이너에 접속해 알아내야하는데 

docker inspect <컨테이너이름> | grep IPAddress

docker ps 로 확인한 컨테이너 이름을 통해 IP 를 알아낼 수 있다. 이렇게 배치 모듈을 실행하면 Mysql에 데이터가 미친듯이 들어온다.

 

그러고 같은 과정을 통해 back(메인) 모듈을 실행하면된다. S3 버킷 연결은 back에서 했기 때문에 IAM 계정에 대한 AccessKey, SecretKey 같은 정보는 해당 모듈에 넣어줘야한다. 그리고 이런 정보 또한 환경변수로 주입이 되던가 properties 파일을 따로 만들어 관리를 해줘야한다.

 

추가로 nuhup & 와 같은 명령어로 백그라운드로 실행시킬 수 있고 1> 2> 와 같은 옵션을 통해 로그를 따로 관리할 수 있다. 

nohup java -jar <파일명>.jar &

nohup는 프로세스를 실행하고 터미널 세션이 종료되어도 프로세스가 계속 실행되도록 하는 명령어이다.

여기서 로그관리를 하려면

nohup java -jar <파일명>.jar > <로그파일명>.log &

해당 방식을 통해 하면 된다. 확장자는 log가 아니라도 상관없다(애초에 모든 확장자 다 상관없음) 이렇게 하면 적힌 로그파일명으로 > 를 통해 표준출력이 파일로 리다이렉션된다. 2<&1 은 표준출력,표준에러를 리다이렉션 

nohup java -jar <파일명>.jar > <로그파일명>.log 2>&1 &

표준출력 표준에러 따로 관리

nohup java -jar <파일명>.jar 1><표준출력>.log 2><표준에러>.log &

파일 보기 

tail -f <로그파일명>.log

 

그리고 배포 후 인바운드 열어줘야 접근이 가능하다.

 

 

프로젝트 실행 결과

 

이미지들은 모두 S3 버킷에 저장된다.

 

'Spring' 카테고리의 다른 글

Spring - Feign Client  (0) 2023.04.24
Spring - MockMvc  (0) 2023.04.03
Spring - Filter  (0) 2023.03.30
Spring - DispatcherServlet  (0) 2023.02.24
Spring - 작성자 체크하기  (0) 2023.02.09