본문 바로가기

Dev.BackEnd/Spring Boot

#SLiPP Spring Boot, JPA 강의 - 반복주기 1

 

이 포스팅은 다음 강의를 바탕으로 작성되었습니다.

>> SLiPP 자바 웹 애플리케이션 개발 >>


반복주기 1

Spring boot에 대해서
초기 스프링은 구성에 필요한 XML 코드가 많았다. 이를 극복하기 위한 수 많은 노력들이 있었다. 그러나 스프링 고유의 복잡한 구성에서 벗어나지 못했다. 모든 구성 작업은 개발 저항으로 타나난다. 애플리케이션 로직 작성 대신 구성 작업에 쓰는 시간은 모두 낭비다. 스프링 기능 구성에 신경을 쓰게 되면 비즈니스 로직을 설계하는데 방해가 되기 때문이다. 스프링은 많은 일을 대신 처리하지만, 개발자가 해야 할 부분도 함께 늘어나는 것이다. 게다가 어떤 라이브러리를 프로젝트 비륻에 포함해야 하는지 결정하는 일은 까다롭다. 의존성 관리는 중요한 문제지만, 또 다른 저항이 된다. 의존성 관리에서 발생하는 호환성 문제는 생산성을 망치는 주범인 것이다. 스프링 부트는 이 모든 것을 바꾸어 놓았다.

스프링 부트는 스프링 애플리케이션 개발에서 많은 부분을 스스로 처리한다.
1. 자동 구성
스프링 부트는 많은 스프링 애플리케이션에 공통으로 필요한 애플리케이션 기능을 자동으로 구성한다. 이런 공통 구성 시나리오를 자동으로 구성해주는 수십 가지 방법을 제공하며, 여기에는 API(JPA), Thymeleaf 템플릿, 보안, 스프링 MVC 자동 구성도 포함되어 있다.
2. 스타터 의존성
스프링 부트에 어떤 기능이 필요한지 알려주면 필요한 라이브러리를 빌드에 추가한다는 것을 보장한다. 즉 스프링 부트의 스타터 의존성을 사용하면 필요한 라이브러리의 버전을 고민할 필요가 없다. 스타터가 끌어오는 라이브러리 버전은 이미 테스트를 거쳐 라이브러리 간에 호환성 문제가 없다고 확인했기 때문이다.
3. 명령줄 인터페이스
애플리케이션 코드만 작성해도 완전한 애플리케이션을 개발할 수 있도록 도와준다. CLI는 강력하고 간결한 스프링 개발 방식을 제공하지만, 전통과는 다소 거리가 있는 개발 모델이기 때문에 선택적인 요소이다.

4. 액추에이터
스프링 부트 애플리케이션을 실행할 때 내부에서 어떤 일이 일어나는지 이해할 수 있다. 스프링 부트의 다른 부분이 간편하게 스프링 개발을 할 수 있게 한다면, 액추에이터는 그 내부를 보여주는 역할을 하는 것이다. 스프링 애플리케이션 컨텍스트에 구성된 빈, 스프링 부트에 의해 자동으로 구성된 것, 환경변수, 시스템 프로퍼티, 현재 구동 중인 스레드의 현재 상태 등 많은 정보를 제공한다.

스프링 부트도 본질적으로는 스프링이다. 내부에 스프링 부트가 없었을 때 스프링에 빈을 구성했듯이 스플이 부트가 동일한 작업을 할 뿐이다. 스프링 부트는 명시적인 보일러 플레이트 구성에서 자유롭게 해주며 애플리케이션의 고유한 로직에 집중할 수 있게 도와주는 친절한 스프링인 것이다.
 
스프링 부트를 이용하면 standalone으로 실행되는 스프링 기반 애플리케이션을 쉽게 만들 수 있다. 최소한의 설정으로 스프링 플랫폼과 서드파티 라이브러리들을 사용할 수 있도록 도와주고 있다. 톰캣을 내장하고 있으며 설정을 위한 XML 코드를 요구하지 않는다. 서블릿 컨테이너가 내장될 수 있으므로 프로젝트를 .jar 파일 형태로 간단히 만들어 배포할 수 있다. 기존의 스프링 프레임워크를 이용한 개발환경 구축은 제법 많은 XML 설정을 요구했다. 그래서 잘 만들어놓은 설정파일을 복사해서 사용하는 경우가 많았다. 이러한 반복적인 작업을 스프링 부트에서는 최소화시킨 것이다.
- '스프링 부트 코딩 공작소'에서 요약
 

새 Spirng Boot Project 생성하기

Error Report 1. 새 프로젝트를 생성하는 과정에 있어서 Error가 발생했다.

ArtifactTransferException:Failure to transfer 라는 에러다.
발생한 에러를 외면하지 않고 부딪혀보았다.
STS 가 설치된 경로가 이상한가 생각해서 bundle 폴더를 프로젝트 파일이 있는 폴더로 이동시켜봤다. sts-bundle 폴더 안으로도 이동시켜봤다. STS를 지웠다가 다시 깔아도 보고 기존에 설치되어있던 Tomcat도 삭제해봤다. 안된다. (아 도대체 뭐가 문제일까, 나랑 서버랑 안 맞는 것인가) 믿었던 스택오버플로우에는 새 프로젝트 생성에 대한 이야기가 없었다. 스택오버플로우가 모르니 이건 뭐 정말 답이 없다.

그런데 예상치 못한 OKKY에서 그 해답을 찾았다. (OKKY만세!) 메이븐 저장소에 문제가 생긴 것이었다.
다음 경로를 따라가서 2.6 폴더를 삭제한 다음에 다시 프로젝트 설정을 해주면 Error없이 프로젝트를 생성할 수 있다. 
cf> .으로 시작하는 파일들은 terminal에서만 볼 수 있기 때문에 터미널을 통해 접근해야 한다.
.m2 / repository / org / apache / maven / plugins / maven-resources-plugin
terminal 캡쳐 사진>


예상해보건데, 이 프로젝트를 생성하기 전에, 언젠가 Maven을 설치했다거나 Maven Project를 생성한 적이 있어서 새로 만들게 된 프로젝트에서 Maven Dependency를 설정할 때 충돌이 발생한 것 같다.

추가적으로 Chrome Extension Application 중 reload develop tool이 있는데, 정말 편리했다!



원격서버에 배포하기

github에 생성한 저장소를 배포한다고 생각하면 된다.

원격 서버에서 git 저장소에 있는 코드를 원격 서버에 다운받기 위한 최초 명령어는 git clone이고 만약 소스에 변경이 생기면 git pull 이라는 명령어를 통해 변경된 소스코드를 가져와 빌드를 해서 배포하는 과정이다.

원격 서버로 ubuntu를 사용하고 원격 서버에 접속하여 터미널 창에서 모든 작업이 이루어지므로 리눅스 명령어와 vi 명령어들이 조금 필요한 부분이다. 원격 서버에 접속하면 root 계정은 보안 문제상 활성화 시켜두지 않기 때문에 새로운 계정을 생성한다. 그리고 생성한 계정을 통해 배포 작업을 해야하기 때문에 생성한 계정에 sudo 권한을 부여하자. 작업을 모두 마쳤으면, 새로 생성한 계정으로 원격 서버에 접속하자.

cf) sudo란 Super User do의 약자로, 최고 관리 권한으로 실행한다는 뜻이다. 리눅스 기본 명령어 앞에 sudo를 붙일 경우 그 하나의 명령에 대해서 일시적으로 최고 권리 권한을 갖는다. sudo는 리눅스 기본 명령어가 아니기 때문에 해당 OS가 sudo 명령어를 지원하는지 확인하는 과정이 필요하다. 본 수업은 Ubuntu를 기반으로 진행되고 ubuntu에서는 sudo 명령어를 지원한다.

계정에 sudo 권한을 부여하는 방법은 다음과 같다.
vi etc/sudoers 로 접속하여 User privilege spectification 부분에 루트 권한 사용자를 추가해준다. 그리고 :wq로 가볍게 저장~하면 될 줄 알았는데 readonly 파일이라고 저장할 수 없다고 뜬다. wq로 할 때는 안됬는데, wq! 로 하니까 됬다!

!의 역할은 무엇인가
vi 에서 !는 강제로 실행하게 만드는 명령어이다.
reandonly 파일이라서 수정이 불가능했는데, :wq 명령어에 !를 붙여줌으로써 가능해진 것이다! 

배포하기 위한 작업들로 이 수업에서는 기본적인 3가지를 다룬다.
UTF-8로 인코딩을 설정해야 하고, 자바 프로젝트를 배포하므로, jdk를 설치해야 한다. 그리고 원격서버로 우리의 프로젝트를 내려받기 위해 git을 설치한다. jdk를 설치할 때는 주의해야할 사항이 있다. 우선 license Accept하는 부분을 원격서버에 전달하기 위해 header에 cookie를 추가해줘야 한다. 또 jdk를 설치할 때 환경 변수 설정이 중요하다. 인코딩 설정할 때도 마찬가지로 .bash_profile 파일에 설정 사항을 입력해줘야 한다. 꼭 java -version 명령어를 통해 jdk가 제대로 설치되었는지 확인해보자.(환경 설정을 하지 않고 java-version을 통해 확인하면 아직 설치가 되지 않았다고 한다!)

git을 통해서 원격 저장소로부터 소스코드를 내려받았다면 빌드를 해보도록 하자. Spring 프로젝트 소스 코드를 내려받았기 때문에 원격서버에 따로 maven ( 빌드 도구 )를 설치하지 않았다. 빌드 하기 전에 잠깐 확인해야 할 사항이 있다. 원격 서버는 기본적으로 firewall(방화벽) 설정을 해두기 때문에 빌드를 해서 프로젝트를 running 시켜도 우리가 만든 웹 사이트에 접속할 수 없다. 방화벽 설정을 통해 포트를 열어줘야 한다.

./mvnw clean package 명령어를 실행하면... 에러가 발생한다.

Error Report 2. 빌드 과정에 있어서 Error가 발생했다.


네트워크가 불안정하면 발생할 수 있는 문제라고 한다. 다시 한 번 빌드를 하면 제대로 빌드가 된다.

빌드가 제대로 되면 target 폴더가 생성된다!

target 으로 이동하여 생성된 jar파일을 java 명령어를 통해 실행시킨다.
역시 이번에도 그냥 넘어가지 않는다.

Error Report 2. jar 파일을 실행시키는 과정에 있어서 Error가 발생했다.



Error를 회피하지말고 log 찍힌 것을 잘 살펴보면 어떻게 해결하면 되는지 알려준다.
8080 port가 어디에서 connet되었다고 한다. 그래서 conflict가 발생한 거라고 한다.
sudo lsof -i :8080 # checks port 8080
명령어를 통해서 현재 8080 port에 connect되어 있는 process의 id 값을 알아낸다.
그런 다음 그 프로세스를 kill 해준다.
kill -9 (프로세스 Id)
그리고 다시 java 명령어를 통해 프로젝트를 run시키면 제대로 된다!!!
한 가지 팁! java 명령어를 통해 프로젝트를 run시킬 때 명령어 뒤에 & 를 붙여주면 background에서 프로젝트를 run 시킬 수 있다. 이렇게 하면 원격 서버에 logout을 해도 서버는 running 상태를 유지하게 된다! 물론 stop을 할 때는 위와 같은 방법으로 포트에 연결된 프로세스 id 값을 잡은 다음에 kill 해주면 된다.


++ 오늘 배운 Linux 명령어 ++

 파일 내용 확인하기

 cat .bash_profile(파일명) 

 파일 작동 시키기 

 source .bash_profile

 소프트 링크 추가하기

 ln -s jdk1.8.0_05/java

 원격 서버 환경 설정 상태 확인하기

 env

 방화벽 상태 확인하기

 sudo ufw status verbose 

 방화벽 접근 허용하기 

 sudo ufw allow 8080/tcp 

 해당 port에 연결된 프로세스 잡기 

 sudo lsof -i :8080 # checks port 8080 

 프로세스 죽이기 

 kill -9 (프로세스 id) 

 네트워크에서 데이터 가져오기

 wget 

 .gz 확장자 파일 압축 해제하기 

 gunzip 

 .tar 확장자 파일 압축 해제하기 

 tar -xvf 

 .tar.gz 확장자 파일 압축 해제하기 

 tar -xvzf

 UTF-8 인코딩 설정 

 sudo locale-gen ko_KR.EUC-KR ko_KR.UTF-8 

  

 sudo dpkg-reconfigure locales 

 

+추가적으로 .bash_profile에 설정 추가하기 

 기존에 있던 target 폴더 삭제하기

 ./mvnw clean  

 컴파일하고 배포할 수 있는 jar 파일 생성하기 

 ./mvnw package 

 위 두 가지 작업을 한 번에 수행하기 

 ./mvnw clean package 



항상 좋은 강의를 해주셔서 감사합니다!