2022. 12. 14. 15:02ㆍ아키텍처
최근 하나의 모듈로 개발했던 프로젝트를 멀티 모듈로 분할을 진행하면서 과연 올바른 방법으로 멀티모듈이 설계가 된건가... 라는 물음과 이게 과연 적절한 것인가...하는 물음이 발생했습니다. 자료를 찾아보면서 다시금 정리를 해본바... '싹다 갈아 엎을까?'라는 생각이 많이 들고 있습니다.
개인적인 경험으로 보았을 때, 멀티 모듈을 구성하는 이유(분산 아키텍처를 수용하는 이유)는 두가지라고 생각합니다.
- 단일 실패지점(SPOF)에 의해 전체 시스템이 마비가 되는 것을 방지
- 높은 응집도와 낮은 결합도를 가지고 유지보수성 증가
그래서 적용은 해보고 싶은데, 참 어렵습니다. 그래서 멘토링 경험을 계기로 인프콘 세션 중 '실전!멀티 모듈 프로젝트 구조와 설계' 라는 주제로 네이버 김대성님이 발표해주신 세션 내용을 참고하였습니다.
인프콘 세션에서는 아래 내용에 대해서 36분간 세션 발표가 이어집니다. 세션 내용을 간단하게 요약해보았습니다.
멀티모듈 프로젝트를 잘 못 나누었을 때 발생할 수 있는 문제
아래 문제가 발생 할 수 있다고 합니다.
- Too Many Connections 문제 : 서비스가 커지면서 Core & Common 사용하는 의존성 프로젝트는 커넥션 풀을 모두 할당 받는다.
- NoClassDefFoundError 문제 : 특정한 모듈이 하위 버전 라이브러리를 참조하는 경우 업그레이드 난해함
- Copy & Paste 문제 : Core & Common의 내용을 참조하는 곳이 너무 많아서 기존 로직을 회피하는 로직들을 추가하면서 코드가 복잡해짐
- All Build & Deploy 문제 : 수정 후 모두 빌드를하고 다시 배포를 해야됨
멀티모듈을 나누는 것
'역할, 책임, 협력관계가 잘 정의가 되어 있는가?'를 파악해야 하고 멀티모듈을 잘 정의해야 합니다. 그렇기 위해서 구체적인 방법론을 아래와 같이 제공합니다.
- Core & Common 을 제거한다.
- 경계를 잘 나누어야 한다. ( BOUNED CONTEXT )
- 경계는 크게 아래와 같이 BOOT, INFRA, DATA, CLOUD로 나눈다.
실무 프로젝트에 적용하기
(As-Is에 대한 설명이 조금 더 필요한 부분이 있습니다만) 결론부터 이야기를 하자면 바운디드 컨텍스트를 기준으로 저장소를 구분하라는 것입니다. 저장소를 구분함으로써 All Build & Deploy 문제를 예방할 수 있다고 합니다.
두번째는 DATA -> INFRA 멀티 모듈 프로젝트 관계 구현과 관련된 내용입니다.
갯수가 증가할 수 있는 서비스에서 DATA 접근을 위한 DB Connection을 가진다면 'Too Many Connections' 문제가 여전히 발생 할 수 있다는 점입니다.
이를 해결하기 위해서는 데이터의 접근을 하는 것은 INFRA가 아닌 DATA 모듈에서 접근을 하여 처리하도록 모아준다는 것입니다.
BOOT -> DATA 멀티 모듈 프로젝트 관계 구현 내용입니다.
이 경우에 Service를 어느 모듈에 배치를 해야되는지에 대한 물음이 발생합니다. 세션 발표자분께서는 두 모듈 모두에서 각각의 역할과 책임에 맞게 개발이 되어야 한다고 합니다. 그리고 상호 서비스간에는 규칙이 필요하다고 합니다.
발표자분이 제안하는 규칙은 ServletRequest를 계속 주입하여 사용하는 것을 형태로 코드를 작성하지 말라고 하였습니다. 즉 각 레이어간에 dto를 통해서 데이터를 전달하는 것이 좋다는 의미로 이해했습니다.
CLOUD -> BOOT 멀티 모듈 프로젝트 관계 구현
시스템 레벨 구현이 실제 서비스 애플리케이션과 밀접하게 연관되지 않도록 Istio와 같은 구현체를 사용하여 서비스 메시를 구성하라 였습니다. 이 부분은 아직 솔직히 이해는 안됩니다.
헥사고날 아키텍처
위 내용을 계속 듣다보니, 딱 헥사고날 아키텍처라고 할 수는 없지만 전반적인 모양세가 헥사고날 아키텍처라는 생각이 들었습니다.
육각형 아키텍처라고 불리는 헥사고날 아키텍처는 애플리케이션 표현 계층 대신 비즈니스 로직을 호출하여 외부에서 들어온 요청을 처리하는 인바운드 어댑터와 영속화 계층 대신 비즈니스 로직에 의해 호출되고 외부 애플ㄹ리케이션을 호출하는 아웃바운드 어댑터를 두는 형태의 아키텍처입니다. 비즈니스 로직이 어댑터에 전혀 의존하지 않는다는 것이 해당 아키텍처의 특장점입니다.
조금 더 구조를 잘 나타내는 도식은 아래와 같습니다.
헥사고날 아키텍처를 채택하면 위 세션에서 언급한 문제들 중 Too Many Request 문제와 Copy & Paste 문제를 적극 해결 할 수 있다고 생각했습니다.
위 그림만으로는 조금 애매한 설명일 수 있으나 하나의 육각형이 바운디드 컨텍스트라고 한다면, 바운디드 컨텍스트 별로 저장소를 구분한다면 All Build & Deploy 문제도 해결이가능하다고 생각합니다.
정리
멘토링을 하면서 기존 계층형 아키텍처를 사용하면서 발생할 수 있는 문제점에 대해서 알게되었고, 인프콘을 통해서 대안을 모색하여 본 경험이었습니다. 또한 세션 마지막에서 콘웨이의 법칙을 언급했는데, 이런 아키텍처의 수준이 결국 그 조직의 소통 구조를 닮는 다는 점에서 나 혹은 내가 속한 조직을 대표할 수 있다는 생각이 들었습니다.
참고자료
우아한 멀티 모듈 세미나 정리 - 현구막님 블로그
헥사고날 아키텍처 예제 - github repo
헥사고날 아키텍처 정리 - 코딩의 성지님 블로그
높은 응집도와 낮은 결합도 - Clint Jang님 블로그
스프링으로 육각형 아키텍처 구현 예제 - Covenant님 블로그
'아키텍처' 카테고리의 다른 글
[아키텍처] CQRS 패턴 (0) | 2022.12.20 |
---|---|
서버리스 아키텍처(Serverless Architecture) (0) | 2022.12.19 |
Event Driven Architecture - 이벤트 드리븐 아키텍처 (0) | 2022.12.07 |