마이크로서비스의 복잡성
모든 것이 분리된 마이크로서비스는 정말 복잡하다.
장점을 100% 사용하려고 하면 그만큼 프로젝트가 복잡해지고 많은 리소스 비용이 발생한다.
예를 들어 서비스를 도메인 별로 분리한다고 생각해보자.
이때 들어가는 비용으로는 다음과 같은 것들이 있을 수 있다.
1. 인스턴스 생성 또는 컨테이너 생성 비용
2. MS간 통신에 사용되는 네트워크 I/O
3. 데이터 동기화
4. CI/CD 운영의 복잡도 증가
5. 도메인에 대한 비즈니스 로직 fragmentation
기존 모놀리식 서비스에는 모든 코드가 서로 섞여있을 수 있다.
그러면 스파게티같은 의존성때문에 함부로 마이크로서비스로 나누기 힘들 수 있다.
이때 점진적으로 서비스를 나누기 위해서 Spring의 멀티모듈을 사용할 수 있다.
왜 멀티모듈을 쓸까?
멀티 모듈의 장점으로는 기존 모놀리식 서비스에 공통적으로 사용되던 코드를 그대로 사용할 수 있다.
예를 들어 전역적으로 사용하던 에러 처리 코드가 있을 수 있다.
마이크로서비스로 나누면 사용하던 에러 처리 코드들을 서비스별로 복사해서 사용해야 할 것이다.
하지만 멀티 모듈 프로젝트를 사용하면?
공통적으로 사용되는 코드를 util 라는 모듈(ex.)에 등록해서 사용할 수 있다.
특징으로는 IDE를 하나만 사용하기 때문에 개발을 빠르게 할 수 있고 각 서비스에 사용되는 기능을 일관적으로 수정할 수 있다.
만약 싱글 모듈 멀티 프로젝트라면?
IDE를 서비스별로 켜놓고 A-api를 수정해서 테스트할 때 B-api에서 수정된 내용을 테스트 하기위해 빌드하고..
하나의 기능을 개발하는데 IDE를 왔다갔다 하는 비용을 무시할 수 없다.
멀티 모듈의 빌드 방법
spring 프로젝트가 빌드되기 위해서는 gradlew 또는 gradle.bat 스크립트를 실행시킬 수 있다.
gradlew build
명령을 실행하면 gradlew 스크립트가 위치한 폴더에 있는 gradle-wrapper와 settings.gradle 파일을 참고해 프로젝트를 빌드한다.
아래 settings.gradle 파일을 보자.
// settings.gradle
include ':api'
include ':util'
include ':microservices:product-service'
include ':microservices:review-service'
include ':microservices:recommendation-service'
include ':microservices:product-composite-service'
include ':spring-cloud:eureka-server'
settings.gradle 파일에 보이는 콜론(:)은 폴더를 뜻하는 (/) 와 동일한 의미이다.
/api, /util, /microservices/product-service 등등에 대해서 빌드를 수행하라고 선언해 놓았다.
/microservices/product-service 의 파일 구성은 위와 같다.
빌드를 통합으로 수행할 때, 각 서비스는 자신의 build.gradle에 있는 정보대로 빌드된다.
라이브러리 모듈 사용법
dependencies {
implementation project(':api')
implementation project(':util')
}
외부 모듈의 api나 util는 라이브러리 모듈 이라고 부를 수 있다.
자체적인 서비스를 가지고 있지 않고 외부 모듈에 의해서 호출되어 사용되는 기능을 모아두었기 때문이다.
gradle dependencies에 위와 같이 설정하면 api나 util에 있는 기능을 불러와 사용할 수 있다.
멀티모듈 구성
라이브러리 모듈 gradle 설정
bootJar {
enabled = false
}
jar {
enabled = true
}
jar : Java Archieve
- Java 어플리케이션을 배포하고 동작할 수 있는 형태로 패키징(압축)한 파일 형태
- Java 클래스 파일, EJB, 리소스, 설정, 의존 파일 등을 포함한다.
- path 등의 경로를 유지하기 때문에, JVM 위에서 단독으로 실행 가능하다.
bootJar : 실행가능한 jar 파일로 build 하는 작업
라이브러리 모듈은 실행할 필요가 없지만 동작할 수 있는 형태로 패키징되어야 하기 때문에 bootJar 설정을 false로 수정해야 한다.
api 라이브러리 사용법
ProductService, RecommendationService, ReviewService는 각 마이크로 서비스에 대한 컨트롤러 인터페이스이다.
그리고 dto 폴더에 데이터 전송 포맷을 위한 도메인 별 dto를 생성해 둘 수 있다.
dto와 api의 response는 매우 밀접한 관계를 가지고 있으므로 같은 계층에 둘 수 있다고 생각한다.