세미나/인프콘

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

비뀨_ 2022. 9. 13. 00:36

 

출처 : 인프콘 2022

 

이전 정리 : https://beetr.tistory.com/67

 

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

출처 : INFCON 2022 https://www.inflearn.com/course/infcon2022/unit/126503?tab=curriculum 학습 페이지 www.inflearn.com 이 글은 단순 정리를 위한 요약이며, 문제가 될 시 삭제하겠습니다. 왜(Why) 멀티 모..

beetr.tistory.com

 

멀티 모듈은 어떤 기준으로 나뉘어야 할까??

 

결론부터 말하면 경계라고 불리는 바운디드 컨텍스트를 생각해보면 어떨까 한다.

특정 Context 문맥하에서 완전한 의미를 갖는 경계의 기준을 잘 나누는 게 멀티 모듈 프로젝트를 설계할 때도 무엇보다 중요한 것 같다.

 

이 기준을 바탕으로 Multi Module Group이라는 4개의 일반적인 그룹을 정의해서 사용한다.

바운디드 컨텍스트

1. Boot ( Server )

서버 모듈 [잦은 변화]

- batch, admin, api

2. Data ( Domain )

데이터 모듈 [+도메인]

-meta, user, chart

서버 모듈과 밀접한 관계가 있고, Domain 영역으로 DataStore를 직접 다루게 된다.

 

3. INFRA

연동 모듈 [큰 변화]

- aod, vod, photo, billing 등 외부 라이브러리

유관 부서 및 업체 연동을 위한 Group 모듈

구현되고 나면 변화는 적지만, 버전이 높아지면 큰 변화가 있게 됨.

 

4. CLOUD

클라우드(시스템) 모듈 [변화 적음]

- config, gateway, discovery

- aws, gcp, azure

 

 

4개의 모듈은 각자의 Cycle과 특성을 갖고 있다.

그 기준으로 경계를 나누고 프로젝트를 구성하면 된다.

 

어떻게 (HOW) 실전 멀티 모듈 프로젝트를 구현해야 할까요?

우선 예시로 프로젝트를 생성했다고 가정해보자.

경계 나누기로 정의했던 4개의 멀티 그룹을 하위 폴더로 생성해본다.

 

 

그다음 멀티 그룹의 성격에 맞게 프로젝트를 각각 구성한다.

이렇게 구성하게 되면 Flat 하게 나열된 구성된 것보다 가독성이 좋아진다.

gradle과 같은 빌드 도구에서 group 폴더명을 기준으로 정의할 기술들을 일괄적으로 선언할 수 있는 장점이 있다.

 

위의 사진을 보면. gradle build script에 boot로 시작되는 프로젝트들에 대해서는 jib라는 Docker 플러그인을 일괄적으로 한 번에 선언해주는 것을 볼 수 있다.

 

조금 더 자세하게 보자면

이렇게 구성하면 가독성도 좋고 좋아 보이는데 또다시 문제점이 생기게 된다.

 

바로 모듈들이 늘어남에 따라 복잡도가 증가하고 > 빌드 시간이 늘어나는 등의 생산성에 문제가 생기게 된다.

 

멀티 그룹의 특성에 맞게 다시 한번 나눠볼 필요가 있을 것 같다.

 

멀티 모듈 그룹 분리하기

1. 변화가 가장 잦은 서비스 Git Repository에 Boot 멀티 그룹과 Data 멀티 그룹은 특성이 같기 때문에 한 곳으로 유지

2. cloud-system 멀티 그룹을 별도의 2개의 저장소로 다시 분리

  - 하나는 system 적인 프로젝트

  - 다른 하나는 webhook 이벤트를 필요로 하는 remote config 서버 프로젝트로 분리

3. Infra

 - 별도의 infra-libray라는 프로젝트로 분리

특성에 맞게 분리하게 되면 build 시간도 줄지만, project의 경계가 명확해짐으로써 실제 interface 구현 설계도

어떤 내용을 주고받아야 하는지 명확해 짐

 

이제 분리되어있는 각 저장소 별로 상호 구현을 어떻게 해야 되는지에 대한 이야기를 해볼 차례이다.

 

Data와 Infra 라이브러리 프로젝트 간의 경계 구현에 관한 내용이다.

 

Music 도메인에는 Track의 하위인 PlayBack 도메인이 존재한다.

PlayBack은 AOD 인프라 라이브러리의 모듈을 통해서 외부에 존재하는 AOD 서버에 재생 관련 데이터를 요청하고 응답받게 된다.

 

어떤 방식으로 실제 구현??

Data-meta 모듈에 playbackService를 선언 - 재생을 위한 서비스 (AOD, VOD) 

외부의 AOD 서버는 infra-aod 라이브러리 프로젝트 내의 AodApiClient라는 것을 통해서 요청을 받게 된다.

그다음 TrackPlayBackService를 구현하고 AodApiClient를 호출

 

일반적으로 외부 서비스를 연동하기 위해서는 내부적인 trackId와 aodId와 같은 필요 저장소를 사용하게 될 것이다.

 

맞는 것 같았지만... 만약 해당 라이브러리에서 사용하는 batch job의 개수가 50~200개 라면 Too Many Connections 문제가 발생하게 된다.

 

이것을 해결하기 위해서는 아래와 같이 나눠보자.

Too Many Connection 오류를 피해기 위해서는 어쩔 수 없이 DB 접근을 Data 모듈 쪽으로 이동해서 구현을 해야 한다.

다음 TrackPlayBackService는 DB 호출을 해야 하기 때문에 Data 메타 모듈에 있어야 한다.

마지막으로 Infra AOD 모듈에서 AodPlayBackService를 구현해서 요청과 응답에 대한 책임을 지게 한다.

 

결국 모듈을 나누는 경계로 생각해보면, Infra 라이브러리 프로젝트는 호출하는 프로젝트와 관계없이

자신의 역할과 책임인 AOD 서버를 올바르게 호출되기 위해 구현이 되어야 한다.

 

협력관계에서  주고받는 메시지가 객체의 책임을 결정한다.

책임을 자율적으로 만드는 것이 애플리케이션에 성질을 결정하는 좋은 방법론인 것 같다.

 

 

BOOT와 DATA

Boot와 Data 프로젝트를 생각할 때 Service를 어디에 두어야 하는지 많이 궁금할 수 있다.

Java로 Spring 개발을 진행하다 보면 일반적으로 요청받게 되는 Controller -> Service 구현 -> Repository 구현 순으로 할 텐데 아래를 보면서 생각해보도록 하자.

 

다음은 Naver Vibe의 가사보기 화면이다. 화면에 Sink 가사라는 것이 없는 경우 후처리로 생성하는 기능이다.

 

runtime에 이벤트를 전달해서 후처리로 생성해주고자 하는데 일반적으로 요청이 오면

boot-meta 프로젝트의 Controller 에서  data-meta 프로젝트의 TrackLyricRepository를 통해서 가사 데이터를 응답받게 된다.

이때 가사 데이터에 TimeStamp 값이 없다면 생성되도록 요청이 됨.

 

Service는 boot-meta와 data-meta 모두에 구현시켜야 한다.

Sink 가사를 생성하는 Event는 boot-meta의 CreateLyricService를 통해서 발생되어야 하고, 

TimeStamp 값이 만들어지게 되면 데이터를 data-meta 모듈의 TrackLyricService 를 통해서 저장되어야 할것 같다.

 

이처럼 Service 구현체는 프로젝트 별로 역할에 맞도록 각각 구현될 수 있을 것 같다.

boot-meta와 data-meta 간에는 한가지 규칙이 필요할 것 같은데

data-meta 프로젝트에서는 반드시 ServletRequest와 같은 메서버??에 의존적인 객체를 전달하지 않는 것이다.

ServletRequest 객체가 말단 Layer까지 전달해서 그것을 가지고 운용하는 Service들을 많이 봤는데

그것은 역할과 책임, 협력관계에 올바르지 않다고 생각합니다.

 

Data-meta 모듈은 batch에서도 사용될 수 있고, web-app 에서도 사용될 수 있고, One-time App에서도 사용할 수 있다.

모두가 WebServer를 기반으로 동작하지 않을 수 있기 때문에 ServletRequest 의존적인 web과 의존적인 class들을 전달하지 말아야 한다.

 

 

결론

 

멀티 모듈 프로젝트 역시 조직의 소통 구조를 닮은 구조를 가진 시스템으로 설계할 것이다.

그렇지만 적절한 나만의 기준이 있다면 변화에 유연하게 대처할 수 있지 않을까라는 생각이 든다.

 

 

 

요약 후 내 생각

우선 36분 짜리 영상을 요약하는데 3시간이 넘게 걸렸다..

모르는 말도 많고, 발음 못알아들은 것도 많아서 오래 걸리면서 진이 조금 빠졌는데, 

저는 멀티 모듈 프로젝트에 관심이 많지만,

당장에 이 것을 알려고 요약하는게 아니라, 일단 읽어보고 더 깊게 이해하는 것은 나중에 쉽게 하려고 요약하는 것이기 때문에 부족한 부분은 꼭 인프런 가서 확인해주세요.

 

열심히 해서 스킬 업을 하고 싶다는 생각이 듭니다.

읽어주셔서 감사합니다.