개발

ec2에 mysql server를 이용해서 spring boot서버를 배포해보자.

yjs3819 2021. 9. 16. 23:06
728x90

안녕하세요.
다들 aws의 RDS제품을 이용해서 DB서버를 구축하지만, 저는 하나의 인스턴스에 mysql 서버와, spring boot서버를 배포해 보겠습니다.
글이 많이 없기도하고, 특히 ./gradlew build시 발생하는 에러를 해결하기 위해 삽질을 많이해서 해결법 등을 적어볼게요.

ec2에 인스턴스 만들기

저는 unbuntu 18(프리티어) 인스턴스를 만들었구요!
보안규칙은 ssh는 왠만하면 본인 ip로하구, http, https는 anywhere로 하였습니다!
이 과정은 너무간단하기에 생략합니다.(모르시면 생활코딩을 참고하세요!)

ubuntu 18에서 mysql-server 설치하구 외부에서 mysql-server에 접속하기

  • sudo su

를 통해서 슈퍼유저로 접속합니다.

  • apt-get update

해주셔서 apt-get을 업데이트해 줍니다.

  • apt-get install mysql-server

위 명령어로 mysql-server를 인스턴스에 설치해주시고요!

설치가 끝나면

  • mysql --version

으로 잘깔렸나 확인합니다.

보면 mysql 버전이 5.7.35일텐데요

외부에서 이 우분투 인스턴스의 mysql 서버에 접속하려면 뭔가 더해줘야합니다.!

  • cd /etc/mysql/mysql.conf.d

위 명령어로 해당 디렉토리로 이동한다음!

  • ls

하시면 mysqld.cnf가 있을 거에요!(mysql 서버의 설정 파일이라 생각하시면 됩니다.)

  • vim mysqld.cnf

를 통해서 vim으로 파일 열어주시고
bind-address 부분이 127.0.0.1 (localhost)로 되어있을 텐데, 0.0.0.0 (anywhere)로 바꿔줍니다.
우리는 외부에서 우분투 인스턴스의 mysql server로 접속이 되야하닌까요!!
(여담으로 mysql 8.xx 서버는 외부접속하기 위해 해당 설정파일을 변경할 필요가 없다고하네요.)

  • a

명령어를 누르시면 vim을 통해 편집할수 있구요

요렇게 수정하시고

  • esc

누른다음

  • :wq

명령어를 치고 나옵니다.(해당 파일 저장하고 나온다는 의미입니다.)

이젠 mysql-server를 외부에서 접근할수가 있는데요!, 접근할 계정이 없는상태입니다.
그래서 이번엔 mysql에 접근할 계정을 만들어볼게요

  • mysql

명령어를 치면 mysql> 이 뜰텐데, mysql cli client로 접속한 상태에요! (구냥, Mysql server에 접근할수 있는 클라이언트가 command line interface로 되어있다 생각하시면 됩니다.)

  • grant all privileges on *.* to root@'%' identified by '1234';

요렇게 어떠한 ip에서도 해당 mysql 서버에 접속가능한 계정을 만들어줍니다.
계정이 이름은 root이고 비번은 1234에요! 이부분은 수정하셔서 하면됩니다.

  • flush privileges

로 flush해주시고요!(별건아니고, mysql 설정 최신화 해주는겁니다.)

  • exit

으로 mysql cli client에서 나와볼게요!

이젠 외부에서 mysql 접속이 되나 확인해보겠숨다!!
그전에!!!!!! aws ec2 인스턴스의 보안규칙을 하나 더 추가해야합니다.

mysql서버는 기본적으로 포트 3306에서 실행되는 중인데요,, 해당 포트에대한 보안 규칙을 aws에서 열어야 외부에서 해당 포트로 접속할수 있어요!!

실행중인 인스턴스의 보안규칙에 요걸 추가해 줍니다!

이제 진짜로 외부에서 mysql서버에 접속이 되는지 확인해보겠습니다.
방법은 다양한데요, 저눈 다들 많이 사용하는 mysql workbench로 열어볼게요

요렇게 실행중인 인스턴스의 퍼블릭 아이피를 넣어주시고, 외부에서 접속할 계정! 입력해주시고 test connection 클릭!

어?

연결에 실패했다고 뜨네요,,

이럴땐 당황하지말고 인스턴스의 mysql 서버를 재구동해봐요, 뭔가 설정 변경한게 적용이 안되었을수도 있으닌까요!

  • sudo service mysql restart

명령어를 쳐주세요.

그리고 다시 mysql workbench로 우리의 mysql server에 접속하면
잘접속이 될거에요!! ㅎㅎ

이젠 외부에서 우리의 인스턴스 mysql server에 접속이 잘되닌까
우리의 스프링 부트 프로젝트에서 방금 만든 mysql server를 통해 테스트를 돌려볼게요

spring boot에서 방금 만든 mysql-server를 통해 테스트해보기

먼저 database부터 만들게요
mysql workbench에서 'test'라는 이름의 database를 만들어봐요
우리는 이 database에서 테스트를 할거에요!

  • create database test;

를 mysqlworkbench에 입력해주세요

  • show databases

로 test라는 database가 만들어졌는지 확인해볼게요.

잘 만들어졌네요!!

이제 우리의 스프링부트 프로젝트의 설정파일인 application.yml을 우리의 인스턴스 url과 3306 포트번호, 그리고 방금 만든 test로 최신화해봐요

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://(인스턴스 퍼블릭 ip):3306/test?serverTimezone=Asia/Seoul
    username: root
    password: 1234
  h2:
    console:
      enabled: true
  jpa:
    hibernate:
      ddl-auto: create
    properties:
      hibernate:
        format_sql: true

logging.level:
  org.hibernate.SQL: debug

이제 테스트를 돌려봐요!
물론 테스트는 해당 db를 이용하는 테스트여야합니다. (단위테스트는 당연히 패스하겠지만, 스프링 부트를 통해서 우리의 mysql server를 이용하는 테스트여야 예시에 적합합니다!)

어? 스프링부트를 이용하는 테스트는 다 fail이 되었네요.. 왜그럴까요?
저는 db에 한글데이터를 넣기 때문에 database 인코딩을 해야합니다.

mysql workbench에서 test라는 데이터베이스의 인코딩을 해볼게요

  • alter database (db이름) default character set utf8 collate utf8_general_ci;

sql을 입력해봅시다! 우리는 (db이름)에 test를 넣으면 됩니다.

이제 다시 스프링부트 테스트를 돌려봐요

(기분이 좋아지는 초록색!)

테스트를 모두 통과했네요, 그말은 즉슨, 스프링 부트에서 우리 인스턴스의 mysql server를 잘 접속한다는 의미겠죠!?

이제 남은건 ec2 인스턴스에 java를 설치하고 spring boot프로젝트를 git을 이용해 인스턴스에서 클론받을거에요.
가봅시다!

인스턴스에서 spring boot 배포하기

먼저 자바를 설치해볼게요.
저는 자바 8을 이용해볼거에요!

  • sudo apt-get install openjdk-8-jdk

를 입력해서 java8을 우리의 인스턴스에 깔아보자구요.!

설치가 완료되면

  • java -version

으로 버전 확인해봐요!

잘 뜰겁니다! ㅎ.ㅎ

이제 git clone을 이용해서 자신의 스프링 부트 프로젝트를 클론받아볼게요.
참고로, username 에는 깃허브의 이메일과, password에는 personal access token을 입력해야하는데요!
구글링하면 정말 많은 정보들이 나옵니다. 구글링해서 해당 방법을 찾고 다시오세요!

이제 거의다 됐습니다.

클론받은 프로젝트의 ./gradlew의 권한을 이제 줘볼게요

  • chmod 777 ./gradlew

아래 부분은 에러가 발생할수 있는 부분입니다. 바로 방법을 해결하시고 싶으신분은 아래 명령어는 입력하지 말아주세요
이제 한번

  • ./gradlew build

를 해봐요!! (하기전에 yml파일에 연결하는 db정보가 올바른지 확인!!)

그런데, 우리의 인스턴스의 mysql server를 이용하는 테스트가 진행이 안되고 멈춰있습니다... 파카 유튜브 한편을 보고와도 그대로네요..
뭐가 잘못된건지...
저는 이 에러때문에 하루 종일 삽질했습니다.
일단
ctrl c
를 해서 영원히 끝나지 않을 것 같은 테스트에서 나옵니다.

여기는 해결 하는 부분입니다.
프리티어 인스턴스를 이용하는 경우, db를 타는 스프링부트를 이용하면 메모리 부족으로 실행이 되지 않아서입니다. ㅠ.ㅠ

  • free -h
    명령어를 입력해서 인스턴스의 가용 메모리를 확인해봐요.
    실제 우리가 가용할 수 있는 메모리가 너무 적다는걸 확인할수 있습니다.

그런데 아래보시면 Swap이라는 게 있을거에요!

일단 swap device가 뭔지부터 알아봐요.

우리의 컴퓨터는 register, cache, main memory, 보조메모리가 있어요!
메인메모리만으로는 부족해서 보조메모리를 이용하는데요, 그게 swap device라 생각하시면됩니다.

맥을 사용하시는 분은 활성상태보기에서 아무 프로세스나 눌러서 정보를 보시면
실제 메모리크기는 너무 작은데 비해 가상 메모리 크기가 엄청 큰걸 볼수있는데요!

이 swap device(보조 메모리, 가상 메모리)를 이용하는 겁니다.

우리의 인스턴스도 컴퓨터닌까 가상메모리(swap device)를 통해서 가용할 메모리를 늘려줄수있어요. 실제 메인메모리를 늘리는게 아니라 가상 메모리를 이용해서 메모리 활용도를 높이는 건데요! 실제 사용되는 프로세스의 블럭(프로세스를 잘게 자른 블럭입니다. 이 부분에 대해서 공부하시고 싶으시면 virtual memory의 paging system, sementation system을 공부하시면 도움이 될거에요.)을 메인메모리에, 현재 실제로 사용되지 않는 블럭은 swap device(보조기억장치, 가상 메모리)넣음으로써 메인 메모리의 활용도를 높이는 거에요

우리가 만든 인스턴스에 가상메모리 (swap device) 를 만들어봅시다! 그리고 이를 통해서 문제를 해결해봅시다!

인스턴스에 swap device를 설정하는 링크는

https://transferhwang.tistory.com/506
에 잘나와있어서 따라하시면 됩니다!!

잘 따라하고 오셨으면

  • ./gradlew clean build

로 시원하게 빌드한 파일 다 지우고 다시 빌드해봐요. 이 과정에서 테스트가 진행이 될거에요.

두둥! 테스트가 성공하여 빌드가 완료된걸 확인할수 있습니다.

  • cd /build/libs

로 가셔서

  • java -jar worldcup-0.0.1-SNAPSHOT.jar

하시면!! 배포가 잘되는걸 확인할수 있습니다!!
물론 이때 aws ec2의 8080포트에대한 보안규칙을 설정 해야합니다!(스프링 부트는 기본적으로 8080포트 사용하닌까요!)

배포가 잘되었네요!!

swagger 문서도 잘열리네요!!

결론

지금까지, aws ec2제품을 이용해서 하나의 인스턴스에 mysql server를 실행하고 해당 인스턴스에 spring boot 서버를 배포해 보았는데요, RDS제품을 이용하면 이상하게 요금이 조금씩 나가길래, '하나의 인스턴스에 db서버를 깔아서 설치해보자'라는 생각으로 시도해본 것이고, 간단할줄 알았는데 생각보다 막힌 부분이 많아서 해결하면 꼭 블로그에 포스팅해야겠다는 생각을 했고, 결국 포스팅했네요! 막히더라도 당황하지말고 하나씩 어떤 설정을 잘 못했는지 곰곰히 생각하고 확인하면 금방 해결할수 있다고 생각합니다! 이 글을 보고 많은 도움이 되었으면 좋겠습니다.

728x90