목차
1. 교재 내용 실습하기
1-1. EC2에 프로젝트 clone 하기
1-2. 배포 스크립트 만들기
1-3. 외부 Security 파일 등록하기
1-4. 스프링 부트 프로젝트로 RDS 접근하기
1-5. EC2에서 소셜 로그인 하기
2. 실습 중 에러 해결하기
2-1. mysql 드라이버 에러
2-2. test 애플리케이션 빌드 에러
3. 자바 웹 애플리케이션의 동작과 배포
3-1. 자바 웹 애플리케이션 배포
3-2. 웹 애플리케이션이 동작하는 방법
3-3. 지속적인 통합과 배포
1. 교재 내용 실습하기
1-1. EC2에 프로젝트 clone 하기
깃허브 프로젝트 clone 하기
-EC2에 git 설치하기
sudo yum install git
-레포 저장할 디렉터리 생성
mkdir ~/app && mkdir ~/appstep1
-생성한 디렉터리로 이동
cd ~app/step1
-git 레포 clone 하기
git clone [레포링크]
-프로젝트 디렉터리로 이동
cd GDSC_Spring_study/박소윤/freelec-springboot2-webservice
기존의 코드 검증
-테스트 코드 실행하기
./gradlew test
1-2. 배포 스크립트 만들기
쉘 스크립트 작성하기
-프로젝트 디렉터리로 이동 후 파일 생성
cd ~/app/step1
touch ./deploy.sh
-코드 추가하기
-생성한 스크립트에 실행 권한 추가
chmod +x ./deploy.sh
-스크립트 실행
./deploy.sh
-애플리케이션 로그 살펴보기
vim nohup.out
1-3. 외부 Security 파일 등록하기
서버에 ClientId와 Client Secret 저장하기
-app 디렉터리에 properties 파일 생성
vim /home/ec2-user/app/application-oauth.properties
-로컬의 application-oauth.properties 파일 내용 복붙하기
-./deploy.sh 파일 수정
nohup java -jar -Dspring.config.location=classpath:/application.properties,/home/ec2-user/app/application-oauth.properties $REPOSITORY/$JAR_NAME 2>&1 &
-애플리케이션 로그 살펴보기
vim nohup.out
1-4. 스프링 부트 프로젝트로 RDS 접근하기
RDS 테이블 생성하기
1. schema-mysql.sql 파일에서 mysql 전체 쿼리를 복사 후 Database Sources 에서 실행
프로젝트 설정하기
1. build.gradle 파일에 다음 코드를 추가
implementation 'org.mariadb.jdbc:mariadb-java-client'
2. src/main/resources에 application-real.properties 파일 생성
spring.profiles.include=oauth,real-db
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.session.store-type=jdbc
EC2 설정하기
1. EC2 서버에서 app 디렉터리에 application-real-db.properties 파일 생성
spring.jpa.hiberante.ddl-auto=none
spring.datasource.url=jdbc:mariadb://gdsc-db.cnghkyxhgovg.ap-northeast-2.rds.amazonaws.com:3306/gdscdb
spring.datasource.username = admin
spring.datasource.password = 123123123
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
- spring.jpa.hiberante.ddl-auto=none
- jpa로 테이블이 자동 생성되는 옵션을 none으로 지정한다.
- rds에는 실제 운영으로 사영될 테이블이니 절대 스프링 부트에서 새로 만들지 않도록 해야 함
2. deploy.sh 파일이 real profile을 쓸 수 있도록 수정
nohup java -jar -Dspring.config.location=classpath:/application.properties, /home/ec2-user/app/application-oauth.properties, /home/ec2-user/app/application-real-db.properties, classpath:/application-real.properties \
-Dspring.profiles.active=real \
$REPOSITORY/$JAR_NAME 2>&1 &
3. application-real.properties 파일을 EC2 서버의 깃허브 프로젝트 src/main/resources 로 이동
mv application-oauth.properties ./step1/GDSC_Spring_study/박소윤/freelec-springboot2-webservice/src/main/resources
4. deploy.sh 파일 실행
~app/step1/deploy.sh
5. 포트포워딩 확인
curl localhost:8080
1-5. EC2에서 소셜 로그인 하기
AWS EC2 도메인으로 접속하기
주소 [EC2 퍼블릭 DNS]:8080으로 접속
구글에 EC2 주소 등록하기
1. 구글 웹 콘솔에 접속 후 해당 프로젝트로 이동, API 및 서비스, 사용자 인증 정보 클릭
2. OAuth 동의 화면 클릭 후 승인된 도메인에 EC2 퍼블릭 DNS를 추가
3. 사용자 인증 정보 클릭 후 OAuth 2.0 클라이언트 ID에서 해당 프로젝트 클릭
4. 승인된 리디렉션 URI에 EC2 퍼블릭 DNS에 :8080/login/oauth2/code/google 주소를 추가하여 추가
5. 구글 계정으로 로그인 하기
네이버에 EC2 주소 등록하기
1. 네이버 개발자 센터 접속 후 내 애플리케이션, API 설정 클릭
2. 로그인 오픈 API 서비스 환경의 PC 웹에서 서비스 URL을 http://EC2 퍼블릭 DNS로, Callback을 http://EC2 퍼블릭 DNS:8080/login/oauth2/code/naver 로 수정
3. 네이버 계정으로 로그인 하기
2. 실습 중 에러 해결하기
2-1. mysql 드라이버 에러 해결
Execution failed for task ':test'. > Could not resolve all files for configuration ':testRuntimeClasspath'. > Could not find com.mysql:mysql-connector-j:. Required by: project :
build.gradle 파일에서 기존 코드를
runtimeOnly 'com.mysql:mysql-connector-j'
다음과 같이 수정함
runtimeOnly 'mysql:mysql-connector-java'
2-2. test 애플리케이션 빌드 에러 해결
로컬에선 gradle로 빌드 성공했는데 EC2 서버에서는 에러
FAILURE: Build failed with an exception. FreelecSpringboot2WebserviceApplicationTests > contextLoads() FAILED
FreelecSpringboot2WebserviceApplicationTests 파일에서 @SpringBootTest 를 주석처리
3. 자바 웹 애플리케이션의 동작과 배포
3-1. 자바 웹 애플리케이션 배포
jar로 웹 애플리케이션 배포하기
Jar은 자바 프로젝트의 압축 파일 포맷으로 자바 클래스 파일과 리소스, 메타 데이터를 모아 배포하기 위해 사용된다. like 실행 파일!
컴파일, 빌드, 배포
자바 프로젝트를 서버에 배포하기 위해서는 1.컴파일 2.빌드 3.배포의 순서를 거친다.
1. 컴파일
- 소스 코드를 기계가 읽을 수 있게 번역한다. (자바의 경우 바이너리 코드이다.)
- .java가 .class로 변환된다.
+ 자바의 바이너리 코드는 JVM(Java Virtual Machine)이 해석하므로 운영체제에 독립적이다!
2. 빌드
- 컴파일 된 코드(.class)를 실행 가능한 독립적인 소프트웨어로 변환한다.
- 변환에는 1.클래스 파일들을 연결하고 2.클래스가 참조 가능한 위치로 리소스를 옮기고 3.메타 데이터 파일을 모으는 과정이 있다.
- 위의 과정에서 빌드 도구인 Gradle이 사용된다.
- 이후 JAR, WAR* 같은 실행 파일을 만들게 된다.
3. 배포
- JAR, WAR 같은 실행 파일을 사용자가 접근할 수 있는 환경(서버)에 배치한다.
- ex) EC2 인스턴스에 코드를 clone해 jar 파일을 생성하고 실행한다. -> 스프링 부트 프로그램이 인스턴스의 8080 포트에서 실행된다.
JAR와 WAR
JAR와 WAR는 빌드의 산출물로 소스 코드와 리소스가 압축되어 있다. JAR는 Java Archieve로, 자바 프로그램이 동작할 수 있도록 하는 데에 목적을 두며 WAR는 Web Application Archieve로, 웹 애플리케이션 전체를 패키징하는 데에 목적을 둔다. 따라서 WAR는 자바 코드(JAR, CLASS)와 웹 자원(JSP, HTML, JAVASCRIPT)을 모두 포함하며 톰캣과 혹은 WAS를 필요로한다. (JAR는 JRE만으로도 가능하다. 이는 자바 프로그램과 웹 애플리케이션의 차이로 생긴 것!)
Spring Boot의 Executable JAR
스프링 부트는 내장 서버(톰캣)를 가지고 있기 때문에 WAR이 아닌 JAR 파일로 웹 애플리케이션을 배포할 수 있다. 이런 간편함 덕분에 JAR 파일을 도커이미지로 생성해 배포하기에 유리하며 개발자는 서버 구축과 배포보다 애플리케이션 개발에 집중할 수 있다!
3-2. 웹 애플리케이션이 동작하는 방법
기본적으로 클라이언트 – 서버 구조로, 원리는
- 클라이언트가 서버에 Request를 보낸다
- 서버는 받은 요청을 Web Server*, WAS*, DB 등을 통해 처리한다
- 처리가 완료되면 서버는 클라이언트에게 Response를 보낸다
- 클라이언트는 Response를 해석해 출력한다
Web Server와 WAS의 개념적 구분
Web Server는 클라이언트로부터 HTTP 요청을 받고 응답한다. 요청이 정적 컨텐츠(HTML, CSS, JS, 이미지, 영상 등)일 경우 해당 파일을 반환하고, 동적 컨텐츠(비즈니스 로직, DB 등 외부 서버 조회가 필요)일 경우 WAS가 요청을 넘겨 받아 동적 컨텐츠를 반환하게 된다. 그러나 WAS 내부에 웹 서버가 존재하기 때문에 Web Server와 WAS를 반환 컨텐츠 차이가 아닌 HTTP 프로토콜을 사용해 더 복잡한 작업을 할 수 있느냐 없느냐의 차이로 알고 있으면 되겠다!
Web Server와 애플리케이션의 데이터 교환
HTTP 프로토콜 기반의 웹 서버와 프로그램이 데이터를 주고받는 인터페이스를 CGI라고 한다. 많은 언어가 이 인터페이스를 지원하지만 자바는 예외이다. 이를 해결하기 위한 것이 Servlet이다.
Servlet은 자바를 사용해 웹 페이지를 동적으로 생성하는 서버 측 인터페이스이다. 스프링 이전 자바 웹 개발에서는 서블렛 구현체 클래스를 모두 직접 xml로 설정해야 했다. 이를 스프링 부트는 DispatchServelt으로 서블렛 매핑 구현체를 지원한다. 서블렛의 생명 주기는 1.초기화(init) 2.구현체의 메소드 실행(service) 3.메소드 실행 후 리소스 반납(destroy)으로 구성된다. 서블릿 구현체은 서버가 뜰 때 생성 및 초기화 되어 요청이 들어올 때마다 실행된다. 이 생명 주기를 Servlet Container가 담당하며 WAS가 요청을 처리할 스레드를 스레드 풀에서 꺼내 서블릿 구현체의 service()를 호출하도록 컨테이너에 요청하는 것까지 맡게 된다. Servlet Container는 Web Container이며 이를 제공하는 실제 제품이 톰캣이다! Executable JAR가 내장 톰캣을 가지고 있는 것이 서블릿 컨테이너를 제공하는 WAS인 것이다!
WAS 앞에 붙이는 Web Server의 역할
WAS 내에 웹 서버가 있음에도 WAS 앞에 Web Server가 붙어 있는데, 그 이유는
- 서버 부하 방지를 위한 책임 분할 : Web Server와 WAS가 컨텐츠 종류를 나눠 담당하기 때문에 WAS의 부담이 줄어든다
- 여러 대의 WAS를 묶어 로드밸런싱하고 헬스 체크 : 여러 대의 WAS 앞에 Web Server를 두어 클라이언트로부터 받은 요청을 WAS로 분산해 나눈다
- 실제 서버를 외부에 노출되지 않게 하기 : WAS는 애플리케이션 로직, DB 로직을 포함하기 때문에 클라이언트가 직접 접근하는 것은 보안적으로 좋지 않아 Web Server를 두어 외부로부터 실제 서버를 숨길 수 있다
3-3. 지속적인 통합과 배포
스프링 부트의 배포는 JAR을 생성해 인스턴스에 업로드하고 실행하면 되지만 JAR을 업로드하는 데에 시간이 오래 걸릴 뿐만 아니라 귀찮다는 단점이 있다. 따라서 배포를 자동화해 서버를 운영할 수 있도록 도입된 것이 CI/CD이다. CI는 VCS 시스템(Git)에 Push가 발생하면 자동으로 테스트와 빌드를 수행해 배포 파일을 만들고, CD는 CI로 만든 빌드 결과를 자동으로 운영 서버에 중단 없이 배포하여 서비스한다.
'Group Study (2022-2023) > Spring 입문' 카테고리의 다른 글
[spring 입문] 토이프로젝트 - TwoYeon (1) | 2022.12.20 |
---|---|
[spring 입문] 토이 프로젝트 - BDNSook (1) | 2022.12.20 |
[spring 입문] 5주차 스터디 - AWS EC2, RDS (0) | 2022.11.13 |
[Spring 입문] 4주차 스터디 - 스프링 시큐리티와 OAuth 2.0으로 로그인 기능 구현하기 (0) | 2022.11.09 |
[Spring 입문] 3주차 스터디 - 머스테치로 화면 구성하기 (0) | 2022.11.01 |