프로젝트 진행에 앞서 AWS EC2를 이용해서 서버 구축 및 배포,재배포를 테스트 해볼것이다.
💡참고로 CI/CD를 하기위해서 사이드 프로젝트 마지막에 배포시
gitAction
,jenkis
등의 tool를 사용하여 해볼 예정이다. 또한 필요한 프로그램을 지금은 직접 설치하는데 AWS가 제공하는엘라스틱빈 스톡
을 사용하여 직접 필요한 기능들을 설치하지 않을것이다.지금은 서버구축, 배포, 재배포를 하나씩 명령어를 통해 해보고 github 소스코드를 다운 받아 빌드하는 방식으로 해보겠다. 마지막에 자동재시작, 재배포를 스프립트로 작성하여 쉽게 할수 있게 해볼것이다.
AWS 페이지에 접속하여 기본적인 회원가입을 한다.
ubuntu 20.0.4
버전과 인스턴스 유형을 t2.micro
로 설정하였다.
💡참고
AWS는 서버를 대여해주는 서비스 이며 각 서버들을 인스턴스라고 멸칭한다.
최초 회원가입시 1년간 한달에 750시간 무료로 서버를 사용가능하다. 또한 인스턴스 유형이t2.micro
에 한해서만 무료이다.
이부분은 많은곳에서 정보를 찾아볼수 있으니 넘어가겠다.
웹으로 해당 AWS EC2 서버에 접속을 하기위해서 해당 ip의 port를 개방해야 된다. 이부분은 인바운드 규칙에서 설정할 수있다.
tomcat를 통한 웹애플리케이션의 포트 번호를 "8888"로 설정하였고 아래 포트는 규모가 크지않은 프로젝트 이기 때문에 AWS EC2 RDS
를 사용하지 않고 서버내에서 MySQL을 설치하여 가동하는 구조이다.
그렇기 때문에 MySQL를 MysqlWorkbench
를 통해 외부에서 접속할수 있도록 하기 위해서 "3306" 포트를 열어두었다.
💡더불어
프로젝트 배포 단계에서 시간이 된다면AWS EC2 RDS
서버를 따로 구축해서 연결해보겠다!!
지금 안한 이유는 이건 쉬울거 같아서 사실 넘어감...ㅎㅎ 그리구 서버를 2개 대여하니깐 추가로 비용이 발생하지 않을까?? 싶어서..ㅎㅎ
사실 AWS EC2 서버내에 DB를 설치하여 가동하는 것은 좋지 않은 것이다.
일반적으로 AWS RDS 서버를 따로 DB로 구동하게된다. 하지만 해당 프로젝트는
프론트엔드 개발자 한분과 협업하여 진행되기 때문에 프로젝트 규모가 크지않아 이러한 방식으로 진행하였다.
sudo apt update
sudo apt install || mysql-server
mysql --version
sudo apt-get install net-tools
: "nply"과 같은 명렁어를 나중에 사용하기 위해 다운
netstat
-nlpt : 실행중인 포트 확인 -> "127.0.0.1:33060"가 나오니 작동중인걸 확인됨!
서버내에서 DB를 확인하고 할수 없으니 외부에서
mysqlworkbench
를 통해서 접속하여 볼수 있게 하기 위해서
(1) mysqld.cnf 파일 수정
cd /etc/mysql/mysql.conf.d
sudo vi mysqld.cnf
: bind-address를 127.0.0.1 -> 0.0.0.0으로 변경
(2) mysql 접속
sudo mysql -u root -p
: 패스워드를 설정했으면 입력하고 접속
(3) 외부 접속 계정 설정 및 권한 부여
create user '계정이름'@'%' indentified by '패스워드'
;
grant all privileges on *.* '계정이름'@'%' with grant option;
(4) AWS EC2 인스턴스에 mysql 접속 포트 추가
이부분은 위에 그림에서 보듯이 설정을 해놓았다.!
sudo apt-update
sudo apt install openjdk-11-jdk
해당 글은 AWS EC2 서버를 구축하는 것이 목표이기 때문에 JDK의 역할,기능들은 넘어가고 필요한 단계별 해야할 일을 설명할것이다.
💡참고
지금은 github에 소스코드을 올리면 해당 소스코드를 서버로 다운받아 build 하는 방식으로 하였다. 하지만gitaction
을 나중에 사용하여 github에 소스코드를 업데이트 할때마다gitaction
이 이를 감지하여AWS EC2
환경과 동일한 환경에서 build test를 하여 정상적이라면 AWS EC2 서버로 build 된.jar.
파일만 전송하도록 할 것이다.
git clone https://github.com/https://github.com/BonSik-Koo/AMS_Algoritrim-Mannage-Service.git
: 해당 주소에서 소스코드를 서버로 다운 받는다.
초기에는 해당
gradlew
를 실행할수 있는 권한이 없기 때문에 권한을 줘야된다.
cd ~/AMS_Algoritrim-Mannage-Service
: 해당 디렉토리로 이동
chmod u+x gradlew
: 실행권한 주기
./gradlew build
: test코드를 포함해서 프로젝트를 실행파일(jar파일)로 만든다.
정상적으로 마치면 build
라는 디렉토리가 새로 생기게 된다.
현재 AWS EC2 서버를
MobaXterm
이라는 프로그램으로 원격접속하여 사용하고 있다.
이러한 상황에서 그냥 java jar를 실행하게 되면Mobaxterm
프로그램을 종료하게 되면 자동으로 jar파일도 종료되게 된다. 이러한 문제점을 막기 위해 "백그라운드 실행"을 해야된다.
`cd ~/AMS_Algoritrim-Mannage-Service/build/libs` : 해당 디렉토리로 이동
`nohup java -jar /home/ubuntu/AMS_Algoritrim-Mannage-Service/build/libs/AMS-0.0.1-SNAPSHOT.jar 1>~/log.out 2>~/error.out &`
해당 jar파일을 시작했을때 출력되는 문구에 대해서 표준출력은 log.out
파일에 쓰고, 에러출력은 error.out
파일에 쓰게 한다. 이렇게 분리하게 되면 *.jar
파일 실행시 정상적으로 실행이 안된 경우 error.out
파일만 확인하여 이유를 확인하면 된다.
또한 마지막에 &
기호가 백그라운드로 실행하겠다는 의미가 된다.
💡추가
기본적으로 AWS EC2는 미국기준의 시간으로 되어있기 때문에 로그같은 것을 찍을때 시간이 미국시간이 나타난다. 그렇기때문에 한국 시간으로 바꾸어 주는것이 좋다.
timedatectl
: 미국시간으로 되어있는지 확인
timedatectl list-timezones | grep Seoul
: 타임리스트에서 Seoul이 있는지 확인
sudo timedatectl set-timezone Asiz/Seoul
: 설정 변경
crontab 은 리눅스서버에서 예약된 작업을 실행시키는 스케쥴러의 역할을 한다.
💡여기서 사용하는 이유?
: 실행중인(배포된) 프로그램이 종료되었을때 자동으로 재시각이 되지않는다. 그렇면 관리자가 직접 프로그램을 실행시켜야된다. 이러한 과정이 번거롭기 때문에 필요한 기능을 스크립트 을
작성하여cron
으로 등록하여 주기적으로 실행되게 한다.
(1) 재시작을 위한 스크립트(spring.restart.sh)
SPRING_PID=$(pgrep -f AMS-0.0.1-SNAPSHOT.jar)
SPRING_PATH="/home/ubuntu/AMS_Algoritrim-Mannage-Service/build/libs/AMS-0.0.1-SNAPSHOT.jar"
echo $SPRING_PID
echo $SPRING_PATH
if [ -z "$SPRING_PID" ]; then
echo "스프링 종료된 상태...."
echo "스프링 재시작 ...."
echo "스프링 재시작 - $(date)" 1>>/home/ubuntu/cron-restart/spring-restart.log
nohup java -jar $SPRING_PATH 1>/home/ubuntu/log.out 2>/home/ubuntu/error.out &
else
echo "스프링 시작된 상태...."
fi
(2) 종료를 위한 스크립트(spring.stop.sh)
echo "SPRINGBOOT STOP...."
SPRING_PID=$(pgrep -f AMS-0.0.1.SNAPSHOT.jar)
kill -9 $SPRING_PID
(3) 종료시 재시작되는 스크립트를 포함한 cron 등록 스크립트(display.sh)
# 1. 최초 배포 프로세스
echo "depoly start ..."
echo "1. JDK install"
echo "2. github project download"
echo "3. gradlew 실행 권한 주기"
echo "4. project build 하기"
echo "5. ubuntu timezone setting 하기"
echo "6. nohup으로 springboot 실행시키기"
#2. 스프링 서버종료시 재시작
echo "crontab 등록 - spring restart..."
crontab -l > crontab_new #crontab의 주석을 복사
echo "* * * * * /home/ubuntu/cron-restart/spring.restart.sh" 1>> crontab_new #지속적으로 실행시킬 스크립트 설정
crontab crontab_new #cron 으로 등록
rm crontab_new
위 (1),(2),(3) 개의 스크립트 생성후 모두 chmod u+x 스크립트이름
으로 실행권한을 부여해준다.
* * * * *
의 의미는 cron 1분 간격으로 등록한 스크립트를 실행한다는 의미이다.
depoly.sh
을 한번 실행하게 되면 Linux cron
으로 등록되게 되고 매 1분마다 프로그램 실행여부를 확인하고 종료시 자동으로 지속하여 실행 시켜준다.
(4) 재배포를 위한 스크립트(redeploy.sh)
echo "Springboot redelopy..."
echo "Springboot Stop..."
SPRING_PID=$(pgrep -f AMS-0.0.1-SNAPSHOT.jar)
kill -9 $SPRING_PID
echo "file delete"
rm -rf /home/ubuntu/AMS_Algoritrim-Mannage-Service
echo "git clone download"
git clone https://github.com/BonSik-Koo/AMS_Algoritrim-Mannage-Service.git
cd /home/ubuntu/AMS_Algoritrim-Mannage-Service
chmod u+x gradlew
echo "build..."
./gradlew build
nohup java -jar /home/ubuntu/AMS_Algoritrim-Mannage-Service/build/libs/AMS-0.0.1-SNAPSHOT.jar 1>/home/ubuntu/log.out 2>/home/ubuntu/error.out &
재배포를 해야되는 상황이면 github
에 소스코드를 업데이트 하고 해당 redeploy.sh
을 실행하게 되면 서버에서 실행되고 있는 프로그램을 종료하고 디렉토리 또한 삭제한 후 github
에서 변경된 소스코드를 다운받은뒤 빌드하여 실행시켜준다.
처음에 deploy.sh
을 실행시켜 자동 재시작이 되게 만들었기 때문에 여기서는 해당 스크립트를 실행시켜주지 않아도 된다.
✅마치며...
지금은 단순히 서버 구축, 배포, 재배포를 직접 명령어를 통해 하고 스크림트와 cron을 통해 구현해보았다. 다시 한번 말하자면 나중에 프로젝트 배포할때는gitaction
tools을 사용하여github
에 소스코드를 업데이트 하면 자동으로 build를 하여 jar 파일만AWS EC2
서버에 배포되게 할것이다.
해당 tools을 사용하게 되면 재배포 할때 기존 서버를 종료시키지 않고 CI/CD를 할수 있을 것이다.시간이 있다면
AWS RDS
서버를 사용하여 DB전용 서버를 구축하여 연결해볼것이고엘라스틱빈 스톡
을 사용하여 기본적인 필요한 프로그램이 설치된 서버를 사용해볼 것이다. 또한 서버를 여러대 구축하여AWS 로드 밸런서
를 사용하여 이용자들의 수가 급증했을때 이용자를 여러서버에 분배시킬수 있게 해볼것이다.