멀티 모듈이란 무엇이고, 왜 사용하는걸까?

Posted by , March 13, 2023
멀티모듈아키텍처gradleMSA
Series ofHexagonal Architecture

학습배경

최근 진행하는 프로젝트가 Hexagonal Architecture(헥사고날 아키텍처) 에 기반하여 진행하게 되면서, 멀티 모듈에 대한 지식을 뺴놓을 수 없게 되었습니다. 멀티모듈이 무엇인지 먼저 학습을 진행하고자 이렇게 포스팅을 진행합니다. 헥사고날과 관련한 내용은 추후 학습을 하며 포스팅을 올릴 예정이고, 이번 포스팅에서는 멀티 모듈의 컨셉에 대해서만 다루어보고자 합니다.


멀티 모듈(Multi Module)

멀티모듈이란 하나의 단일 프로젝트를 여러개의 모듈로 분리해서 구성하는 기법입니다. 각 모듈은 개별적으로 컴파일되어 라이브러리 또는 실행가능한 파일로 생성됩니다.

모듈(Module) 이란?

오라클 자바 도큐먼트에서는, 모듈을 패키지의 한 단계 위의 집합체이며, 관련된 패키지와 리소스들의 재사용할 수 있는 그룹이라고 정의하고 있습니다. 이렇게만 말해선 이해가 잘 안가실겁니다. 지금부터 멀티모듈이 왜 등장했으며, 등장배경과 함께 왜 사용해야하는지를 알아봅시다.


단일모듈 멀티 프로젝트 & 사설 레포지토리 공유

멀티 모듈의 개념이 적극적으로 활성되기전에, 기존에는 여러 프로젝트에서 공통되는 코드와 Dto, 도메인등을 Nexus 와 같은 하나의 사설 Maven 레포지토리에 올려둠으로써 시스템의 일관성이 보장되는 것 처럼 보이게 했습니다.

중복되는 코드와 기능에 대한 관리 주체가 기존에는 인간이 직접 일일이 개입해야 했다면, 이로써 주체자가 시스템으로 바뀌게됩니다. 이 방식을 통해 위와 같이 주문 관련 다중 프로젝트 OrderA, OrderB, OrderC 는 하나의 사설 저장소로 공통된 내용을 공유함으로써 흔히 말하는 복.붙 의 과정을 제거할 수 있게 됩니다.

하지만 Nexus 등을 활용하는 방식은 변경사항이 일어날때마다 코드를 업로드시키고, 그 Nexus 에 최신회된 내용을 다운받는 개발 사이클이 너무 번거롭다는 단점이 있었습니다.


단일 프로젝트에서 멀티모듈 도입

앞선 방식은 여러개의 프로젝트가 하나의 저장소를 공유하는 방식이였다면, 이러한 다중 프로젝트를 하나의 자그마한 "모듈" 단위로 쪼개자는 아이디어가 등장하게 됩니다.

멀티모듈이란 여러 프로젝트 각각을 하나의 모듈(서브 프로젝트) 로 모듈화 시키는 방식입니다. 결국 기존의 여러 프로젝트들은 모듈화되었고, 여러 멀티모듈들이 모여서 하나의 단일 프로젝트를 구성하게 되는 구조입니다. 즉, 하나의 프로젝트 내에 여러 모듈을 설치해서, 시스템의 일관성을 보장하고 빠른 개발 사이클도 가져가는 방식이죠.

위 그림처럼 기존의 OrderA, OrderB, OrderC, Order 프로젝트는 각각 모듈화 되었으며, 이들이 하나의 프로젝트를 구성하게 되는 것입니다. 그런데 실제 운영 서비스라면 한 서비스에는 주문 관련 기능외에도, 결제 기능, 쿠폰 기능등 여러 기능이 추가되어서 여러 집군들이 하나의 서비스로써 구성될 수 있겠죠? 이때 바로 MSA 가 등장하게 됩니다.


Monolithic Architecture & MSA

Monolithic

기존의 여러 서비스들은 Monolthic(모놀리틱) 아키텍처 방식으로써, 멀티 프로젝트에서 단일 모듈을 사용하는 방식을 채택했습니다. 하나의 프로젝트안에 API 및 웹서버, 캐시와 DB 등을 모두 집어넣는 방식이였죠. 하지만 그 규모가 커지고, MSA 로 전환되면서 각 서비스들을 마이크로서비스 단위로 쪼개는 방식으로 진화하게 되었습니다.

MSA (Micro Service Architecture)

MSA 를 채택한 대규모 서비스에서 시스템을 분리했다가 통합하는 일들이 많아지면서, 멀티모듈을 활용하면서 분리와 통합을 더 유연하게 만들 수 있기 때문에 MSA 에서 멀티모듈이 많이 활용되고 있습니다.

MSA 의 각 구성단위인 마이크로서비스는 하나의 독립적인 기능을 수행하는것이 중요합니다. 멀티모듈을 도입시, 각 마이크로서비스에 멀티 모듈로 구성하는 방식입니다. 예를 들어, 주문 관리 서비스는 주문, 결제, 배송 등 다양한 기능을 제공할 수 있으므로 각각의 기능에 해당하는 모듈로 분리할 수 있습니다.

앞서 설명했듯이, 멀티모듈은 하나의 프로젝트 안에서 여러 개의 모듈로 구성되어 있는 구조입니다. 각각의 모듈은 독립적으로 개발, 빌드, 배포가 가능하며, 다른 모듈과의 의존성을 정의할 수 있습니다. 이를 통해, 마이크로서비스 간의 의존성을 적절하게 관리할 수 있습니다.

MSA 에서 멀티모듈을 어디에 도입한다는 거야 !?

멀티모듈과 MSA 를 처음 학습하며 개인적으로 햇갈렸던 점은, MSA 에 기반한 아키텍처를 구성시 멀티모듈에 어디에, 어떤 범위에 적용되는가입니다. 지금까지 이해한바로는, 보통 MSA 에서의 멀티모듈 도입시 각각의 마이크로서비스가 멀티 모듈로 구성됨을 의미합니다.

앞서 설명했듯이 하나의 프로젝트 및 서비스를 멀티모듈로 구성하면, 각 서비스(정확히는 여기선 마이크로서비스) 끼리는 서로 의존적이지 않고 독립적으로 개발 및 배포가 가능해지는 것이죠. 또한 각 서비스의 모듈끼리도 서로 다른 의존성을 지니며, 독립적으로 빌드 및 테스트, 배포가 가능해지는 것입니다.


객체지향으로 귀결되는 멀티모듈

멀티모듈 프로젝트를 구성하는 방식은 개발자 나름이겠지만, 보통 계층 구조로 모듈들이 구성되는 것이 일반적입니다. 이는 각 모듈의 역할과 책임 분리하고, 모듈간의 의존성을 최소화하여 유연하고 확장성있는 애플리케이션을 개발하기 위함입니다.

결국 모듈의 정의는 객체지향으로 귀결되는듯 했습니다. 멀티모듈에서의 각 모듈은 역할과 책임 이 명확히 부여되어야지 적절한 계층에 배치되고, 각 계층간의 의존적인 흐름이 생기게 되는 것입니다. 객체지향을 아는척하지 말자 : 오해하고 있었던 객체지향의 정체 에서도 설명했듯이, 모듈도 하나의 객체로써 바라보고 서로 협력하는 관계로 바라보면 좋을듯합니다.

객체지향을 살리지못한, 실패한 멀티모듈 프로젝트

만약 객체지향을 살라지 못한 멀티모듈 프로젝트라면 어떻게 될까요? 우선 1. 스파케티 코드 가 발생할 수 있습니다. 하위 계층의 모듈이 상위 계층의 모듈을 공통 모듈로써 바라보고 있을텐데, 각 모듈에 대한 역할과 책임이 적절히 분배되지 않았으므로 애매모호한 모듈의 정의로 인해 공통모듈에다 필요 이상의 기능을 추가해버리는 것입니다. 결국 해당 공통모듈에 의존적인 상황이 발생해버리는 것이죠.

이렇게 되면 공통모듈의 수많은 클래스가 생성될 것이고, 각 클래스끼리는 서로 의존하고 영켜있는 스파게티 코드가 발생해버리는 것입니다. 가령 클래스A를 수정하려해도, A를 의존하고 있는 몇십개의 클래스를 변경해야하는 번거로움이 생길 수 있게 되는것입니다.

다음으로 2.대규모의 의존성 덩어리가 발생 할수도 있습니다. 공통모듈에 모든 의존성을 주입하는경우, 하위 모듈들중에 사용하지 않는것에 대한 의존성이 생길수도 있는것입니다. 각 모듈에 대해 의존성의 무개가 커지고, 추후 잡을수없는 에러가 터질 수도 있는것입니다.


더 학습해볼 키워드

  • DDD(도메인 주도 설계)
  • 클린 아키텍처
  • Hexagonal Architecture
  • 스프링부트 애플리케이션에서의 gradle 및 멀티모듈 적용법
  • MSA, Monolithic

참고