세미나/인프콘

멀티 모듈 프로젝트 구조와 설계( 1 ) - 김대성님

비뀨_ 2022. 9. 12. 22:52

출처 : INFCON 2022

https://www.inflearn.com/course/infcon2022/unit/126503?tab=curriculum 

 

학습 페이지

 

www.inflearn.com

 

이 글은 단순 정리를 위한 요약이며, 문제가 될 시 삭제하겠습니다.

 

왜(Why) 멀티 모듈 프로젝트 구조가 중요할까요??

 

아키텍쳐는 프로젝트 초기에 이뤄져야 하는 일련의 설계 결정이다.

아키텍쳐는 요소의 구조와 그 관계에 관한것이다.

 

를 바꿔보자 

 

멀티모듈 프로젝트는 프로젝트 초기에 이뤄져야 하는 일련의 설계 결정이다. -> 리스크를 줄이기 위한 시작

멀티모듈 프로젝트는 요소의 구조와 그 관계에 관한것이다. -> 나중에 변경하기 어렵다.

 

모든 서버들이 참조하는 Common이란 모듈이 있다.

프로젝트 초기에는 운영도 잘 되고 괜찮지만

 

서비스 팩이 많아지고 구현되는 코드가 많아지면

 

Core와 Common이 비대칭적으로 커지게 된다. 커진 이유는 API A, B, C, D와 같이 다른 Domain들이 생겨나면서 Service Spec이 늘어나고

그로인해서 공통적인 기능들이 많아지면서 자연스럽게 발생되었다.

근본적인 문제는 '중복을 제거해야 한다.' 라는 강박관념 때문에 생기지 않았을까 싶다.

 

Core와 Common에는

 

서비스의 복잡도가 높아지게 되면 여러 DataStore를 사용하게 되는데, 중복을 제거하기 위해서 

공통적인 구현을 Core와 Common 등 한곳에 구현하게 되면 많은 문제점을 갖게 된다.

 

4가지의 실제 문제점

Too Many Connections

Service가 커져가면서 다른 DomainService가 추가되고,

Traffic이 늘어나면서 Server 수를 늘리게 되면 Connection의 수도 늘어나게 된다.

 

NoClassDefFoundError

Log4j 보안이슈에서 1을 2로 업데이트 해야되는 상황에 이르렀다.

버전을 1을 2로 변경하고 Compile을 시도했더니 Log4j 1을 사용하는 라이브러리가 있었고 2로 업데이트 하기에 난감한 상황이 발생했다.

이처럼 특정 모듈이 하위버젼을 사용하면 전체적인 프로젝트의 업그레이드가 어려울 수 있다.

 

Copy & Paste

 

API 서버에서는 로그인한 유저가 자신의 ID나 생년월일을 볼 수 있지만 Admin과 같은 Service에서는 개인정보 보호를 위해

마스킹처리를 해야하는 Spec이 발생할 수 있음.

이 때 기존의 UserService의 구현체 로직을 변경하는게 아니라 특정 Parameter를 넘기고

분기해서 값을 변경시키는 구현을 자주 마주치게 됨.

 

이 때 참조하는 Class가 많다면 SideEffect가 어디서 나타날 지 모름.

당장 Release 해야하는 상황이라면 Type 분기를 통해서 구현한 부분이 기존 로직을 회피할 수 있도록 복&붙으로 수정해서 배포하는 상황이 발생하게 되는데, 이런 코드가 보이게 되면 깨진 창문 효과로 급속도로 퍼져나가게 되고 유사 코드들이 발생하게 됨.

 

 

All Build & Deploy

만약 특정한 Class의 Test를 수정해서 배포한 뒤 확인해봤더니 글자가 한개 오타가 있는 것을 확인했다.

이 내용을 수정해서 배포하려면 전체 빌드 후 배포를 해야하는 막대한 비용이 발생한다.

 

이렇게 멀티 모듈 프로젝트를 나누는 기준이 적절하지 않다면 위의 4가지 사례가 당장은 아니라도 언젠가는 발생할 수 있다.

그렇기 때문에 멀티 모듈 프로젝트를 다루는 적절한 방법에 대해서 생각해봐야 한다.

 

★어떤것 (What)을 기준으로 멀티 모듈 프로젝트 구조를 나눠야 할까요?

중요함!

 

위의 문제점들을 해결하기 위해서 위의 사진에서 어떤 것을 가장 고민해봐야 할까??

 

바로 '역할, 책임, 협력 관계가 올바른가?' 이다.

 

기술 베이스 지향적인 모듈 구조

Core, Common에 있었던 Data 관련 구현을 이제 DataStore 접근 기준으로 이와같이 추가적인 Data 기반의 멀티 모듈로 추가 구성될 수 있을 것 같다.

이 멀티 모듈 프로젝트는 Service, Domain 기반의 구조가 아니라 기술 베이스 지향적인 모듈 구조이다.

 

현재 상태가 적절한지 고민을 좀 더 해보겠다.

 

위의 구조에서 Music 서비스의 간단한 도메인을 추가해보면 

 

좌 : 묶기 전, 우 : Meta로 묶은 후

Artist Domain 기반으로 하위의 Album과 Track, Video가 존재하게 된다.

이런 Model들은 멀티 모듈 프로젝트로 어떻게 정리해야 할까?

우선, 오른쪽 이미지처럼 Meta라는 하나의  멀티 모듈 프로젝트로 구성해보겠다.

Meta라는 것은 Music Service의 기반이 되는 공통적인 도메인이고, 모든 모듈에서 필요로 할 것이다.

 

하지만 아래처럼 Track은 MySQL에, Lyric은 MongoDB에 저장되는 경우 META 도메인은 어디에 위치할 것인가?

기술 지향적으로 구조를 짜게 된다면 이런 문제가 발생할 수 있다.

 

이 META의 멀티 모듈들은 또 다른 멀티 모듈을 필요로 한다.

 

유관부서나 업체 연동을 구현한 Infra 모듈을 필요로 한다.

음원을 재생하기 위한 AOD, 비디오 재생을 위한 VOD 연동 모듈 등이 있다.

 

이처럼 연동 모듈들은 지속적으로 늘어날 수 밖에 없다.

처음 구현하게 되면 딱히 변경할 필요가 없다가 특정한 시점에 Version Up 요청이 온다면 큰 변화가 생기게 된다.

 

한 화면으로 모듈들을 나열

초록색 멀티 모듈들로 시작을 했지만, 오른쪽 빨간 영역의 모듈들이 추가되면서 자연스럽게

멀티 모듈은 2배 이상 커지게 된다.

 

점점 늘어나는 멀티 모듈들을 무슨 기준으로 나누고 규정해야할까??

 

결론은 문제의 근원인 Core와 Common을 삭제하고 시작해 본다.

 

Q : "그러면 공통적인 부분은 어떻게 개발하나요?"

 

A : 일부 코드에 대해서 어느정도 중복을 허용하면 어떨까?

 

코드가 일부 중복되는 것보다 Core와 Common이 잠재적으로 가지고 있는 위험성이 더 크기 때문이다.

우리가 겪는 지금은 10, 20년 전에 비해 엄청나게 복잡하고 고도화 되었다.

그때는 맞고 지금은 틀리다!

 

중복을 제거하는 것은 공감하지만, 중복제거를 위해 모든 것을 한 곳에 모아두는 방식은 옳지 않다.

 

너무 길어져서 2편으로 나누겠습니다.