1. 멀티 모듈이란?
멀티모듈이란 하나의 프로젝트를 여러 개의 독립적인 모듈로 나누어 개발하는 방식입니다.
기존 단일 모듈 구조에서는 모든 소스코드와 리소스가 하나의 프로젝트 안에서 포함되어 관리되었지만 멀티모듈에서는 필요한 기능이나 역할 별로 모듈을 분리하고 각각 독립적으로 관리할 수 있습니다.
1-1 멀티모듈의 장점
단일 모듈 멀티 프로젝트가 존재한다고 생각해봅시다.
각각 나뉘어진 A,B,C 프로젝트는 동일하게 다뤄지는 Member라는 도메인을 사용중입니다. 이 때 Member 도메인의 변경 요청사항이 있어 변경이 생긴다면, 서로 다른 3개의 프로젝트를 하나하나 오픈해 복사 붙여넣기 하거나, 직접적으로 수정해야하는 불편함이 발생하게 됩니다.
멀티 모듈의 단일프로젝트로 구성되어 있을 경우는 어떨까요?
하나의 프로젝트 안에서 중복된 코드를 공통 모듈로 추출한 후 각 모듈에서 Common Module을 가져와 사용할 수 있다는 장점이 있습니다. Member의 변경이 발생하면 Common Module 내의 코드만 변경하면 되고, 이전과 달리 단일 프로젝트로 관리되므로, 각 프로젝트를 open해서 변경할 필요 없이 하나의 IDE 창만 띄워놓고 사용할 수 있다는 장점이 있습니다.
또한 모듈별로 독립적인 변경이 가능하므로 특정 모듈에 문제가 발생했을 때 다른 모듈에 영향을 주지 않고, 독립적으로 배포 또한 가능하다는 장점이 있습니다.
1-2 멀티모듈의 단점
하지만 단점 또한 존재하는데...
공통적으로 사용되는 코드가 결국 Common으로 하나 둘씩 모이게 되는데, 이 로직들이 모이다보면 Common이 갈수록 방대해지고 갈수록 각 모듈들의 Common에 대한 의존성이 커지는 문제가 발생하게 됩니다.
(ex 특정 모듈이 여러 모듈에 참조될 때 버전 충돌이 발생하거나 의존성이 꼬여서 빌드 오류가 발생)
각 모듈의 책임을 올바르게 나누지 않으면 모듈 간 경계가 모호해지고, 오히려 중복된 코드들이 늘어나거나 의존성 문제의 복잡해질 수 있기 때문에 설계 단계에서 명확한 역할과 책임을 나누는 것이 중요합니다.
2. 멀티 모듈 구성하기
지금까지 멀티모듈에 대해 알아보았는데요. 이번에 MSA전환을 위해 멀티 모듈을 도입하게 되었습니다.
멀티모듈 구조를 선택한 이유는 위에서 알아보았듯 다음과 같습니다.
- 재사용성 증가 : 공통 응답 및 예외 처리, 설정 들을 Common 모듈로 관리하며 코드 중복을 최소화할 수 있다.
- 모듈별 독립성 : 티켓, 유저, 결제 등 도메인별로 모듈을 분리해 독립적으로 개발하고, 빌드 및 배포가 가능하다.
- 개발 편의성 : 하나의 IDE에서 모듈을 통합적으로 작업할 수 있다.
지금부터는 본격적으로 멀티모듈을 구성하는 방법에 대해 알아보겠습니다.
2-1 멀티 모듈 생성하기
본격적으로 멀티 모듈을 적용해보겠습니다.
NEW -> Module 선택하기
모듈 이름, 필요한 디펜던시 선택 후 CREATE
root 프로젝트의 settings.gradle에 아래와 같이 하위 모듈을 추가해줍니다.
rootProject.name = 'tickettalk'
include 'common'
include 'user-service'
include 'ticket-service
~~모듈 추가
이 때 주의할 점은 각 모듈안의 settings.gradle이 우선순위가 더 높아 적용되기 때문에 루트 프로젝트의 settings.gradle을 제외한 각 모듈의 settings.gradle 파일을 제거해줍니다.
2-2 각 모듈 간의 의존성 설정하기
설정 후 빌드를 하면 아래와 같은 문제가 발생하는데 common과 user-service의 의존성 설정이 되어있지 않기 때문입니다.
user-service의 gradle 설정에 아래와 같은 코드를 추가해줍니다.
implementation project(':common')
이 때 root project의 settings.gradle에서 설정한 값과 동일하게 입력해주어야 합니다.
이후, 다시 한번 빌드를 진행하고 아래와 같은 문제가 발생한다면
gradle에 아래와 같은 설정을 추가해줍니다.
tasks.register("prepareKotlinBuildScriptModel")
2-3 공통모듈에서 사용되는 스프링 빈 객체 사용을 위한 컴포넌트 스캔 설정
추가로 해줘야할 작업은 서비스에서 common에서 사용되는 Spring Bean 객체를 주입 받아 사용할 수 있도록 컴포넌트 스캔 설정을 추가해줍니다.
@SpringBootApplication (
scanBasePackages = { "kr.doridos.common", "kr.doridos.userservice"}
)
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
3. 멀티모듈 생성 완료
1차적으로 멀티모듈로 분리한 후의 모습은 아래와 같습니다.
common 모듈에는 서비스에서 공통적으로 사용되는 응답 및 예외 처리, config 같은 코드들이 위치해 있고 각 서비스들이 해당 모듈을 의존해 사용할 수 있도록 구성되어 있습니다.
나머지 user-service, ticket-service, reservation-service, payment-service는 기존 모놀리식 구조에서 소스코드를 도메인 별로 분리하여 독립적인 서비스로 구성했습니다.
이렇게 구성된 멀티 모듈을 기반으로 각 서비스간 통신, api-gateway 등의 작업들을 진행해보도록 하겠습니다.

참고
'Backend > MSA 전환' 카테고리의 다른 글
[MSA 전환하기 6편] OpenFeign을 활용한 서비스 간 통신하기 (0) | 2025.01.29 |
---|---|
[MSA 전환하기 5편] Spring Cloud Config 도입하기 (+ Spring Cloud Bus) (0) | 2025.01.20 |
[MSA 전환하기 4편] Spring Cloud Gateway 구현하기 (API Gateway) (0) | 2025.01.15 |
[MSA 전환하기 3편] Service Discovery 적용하기 (0) | 2025.01.13 |
[MSA 전환하기 1편] 모놀리식 아키텍처와 MSA란 무엇인가? (1) | 2024.11.26 |