-
우아한멀티모듈 by 권용근님세미나, 영상 요약정리 2022. 10. 12. 00:01728x90
우아한형제들 권용근님의 우아한멀티모듈을 보고 요약한 내용입니다.
https://www.youtube.com/watch?v=nH382BcycHc
멀티 모듈 프로젝트의 등장 배경
회원 시스템을 개발한다고 하면 다음과 같은 독립된 프로젝트 단위로 가지고 있습니다.
- member internal api
- member external api
- member batch
이렇게 서로 독립된 프로젝트를 가지고 있으면 시스템의 중심인 Member라는 Domain이 중복되는 문제가 발생합니다.
가장 쉬운 방법으로는 Copy & Paste로 개발이 가능하지만 언제나 3개의 프로젝트의 도메인이 동일하게 유지된다고 신뢰할 순 없습니다.
따라서 멀티모듈 프로젝트가 등장하게 됩니다.
멀티 모듈 프로젝트란?
시스템의 하나의 중신 도메인을 모듈로 분리하여 언제나 3개의 프로젝트의 도메인이 동일하게 유지되도록 할 수 있습니다.
MSA와 멀티모듈
MSA에서 멀티 모듈이 부각되는 이유는 역할, 의존성의 분리를 통해 시스템의 분리 통합하는 과정을 유연하게 만들어 줄 수 있는 좋은 아키텍처를 만들 수 있기 때문입니다.
"좋은 아키텍처는 시스템이 모노리틱 구조로 태어나서 관리되도라도 독립적인 서비스나 마이크로 서비스 수준까지 성장할 수 있도록 만들어져야 한다. 또한 원래 형태인 모노리틱 구조로 되돌릴 수도 있어야 한다" - 클린 아키텍처
멀티 모듈의 장점으로는 기존 모놀리식 서비스에서 공통적으로 사용하던 코드를 그대로 사용할 수 있습니다.
예를 들어 전역적으로 사용하던 에러 처리 코드가 있을 수 있습니다.
마이크로서비스로 나누면 사용하던 에러 처리 코드들을 서비스별로 복사해서 사용해야 할 것입니다.
하지만 멀티모듈을 사용하면 공통적으로 사용하는 코드를 util, common 등에 등록하여 사용할 수 있습니다.
실패한 멀티 모듈 프로젝트
"공통되는 코드를 제거할 수 있겠다"라고 간단하게 생각할 수 있으며 이런 것들은 common으로 뽑아내게 되고 common 지옥이 시작됩니다.
이제 요구사항이 점점 추가됨에 따라 Common 모듈에 점점 코드가 추가될 수 있습니다.
이렇게 되면 여러 단점들이 존재합니다.
1. 스파게티 코드
리팩터링이 매우 매우 힘들어지게 됩니다.
2. 의존성 덩어리
스프링 부트는 의존성을 기반으로 발동되는 AutoConfiguration들이 많이 존재합니다.
이때 공통 모듈로 인해 어디선가 발동되는 스프링 부트의 마법으로 애플리케이션은 최적화되어 돌아가지 못하게 되며, 이것은 곧 장애 포인트가 될 수 있습니다.
3. 공통 설정
외부 api는 100개의 Connection Pool이 필요하고 내부 api batch는 상대적으로 적게 필요합니다.
하지만 공통모듈에 100개의 설정을 해버리면 모두 100개의 Connection Pool이 할당되고 추후 Scale-out을 진행할 때 커넥션이 부족한 장애를 맞을 수 있습니다.
Thread Pool, Connection Pool Timeout 등의 설정도 가장 민감하고 중요한 어플리케이션 기준으로 들어갑니다.
모든 DB에서는 가질 수 있는 최대 Connection 개수가 정해져 있습니다.
이때 DB를 사용하지 않는 애플리케이션에서 공통 모듈을 사용하기 위해 사용되는 커넥션으로 인해 실제로 DB를 사용하는 애플리케이션을 포함하여 해당 애플리케이션까지 모두 문제가 생길 수 있습니다.
실패 이유 : 모듈에 대한 정의가 모호했다.
무엇을 중심으로 정의를 내려야 할까?
역할과 책임을 기준으로
역할도 크게 잡을 수도 적게 잡을 수도 있다.
라이브러리들을 염탐하기 시작!
대부분 내부적으로 계층을 두었다는 것을 알게 됨
멀티 모듈 구성하기
애플리케이션 비즈니스 : 요청 값 검증 -> 주문 요청 -> 주문 처리 -> 응답의 큰 Flow
도메인 비즈니스 : 주문 데이터 생성, 검증, 저장
레이어 구상
내부 모듈 계층
시스템 안에서 의미를 가지고 애플리케이션, 도메인 비즈니스의 로직은 모르는 계층
여러 개의 서버와 통신하게 되게 되면 다양한 HTTP 요청 응답 스펙을 가지게 됩니다.
이렇게 되면 스펙이 중복되는 일이 벌어질 수 있습니다.
따라서 환경별 시스템 Host, Header를 관리하고 요청, 응답 Spec을 관리하고 예외 처리에 대한 수준을 통일하는 모듈로 분리하였습니다.
이를 통해 스펙 변경에 대한 변경이 일어나면 내부 모듈만 바라보면 되기 때문에 변경 지점 추적이 매우 편리해집니다.
도메인 모듈 계층
만약 같은 도메인에 다른 인프라를 사용하는 경우가 존재할 수 있습니다.
인프라스트럭처를 분리하지 않으면 거대해지는 common과 같은 부작용이 존재할 수 있기 때문에 이를 분리하는 작업을 수행합니다.
domain-redis, domain-dynamo
이후 Domain Service Module을 따로 두어 의존성을 관리하고 cache, Fallback에 대한 작업을 처리해줍니다.
이렇게 되면 dynamo만 필요하면 dynamo만 사용하고 redis만 사용하려면 redis만 사용하고 둘 다 사용하기 위해서는 domain service module을 이용하면 됩니다.
독립 모듈 계층
시스템과 관련 없이 자체로서 독립적인 역할을 수행
data-dynamo-reactive라는 모듈을 두고 aws, db 관련 의존성들이 관리됩니다.
공통 모듈 계층
Type, Util 등을 정의합니다.
의존성을 전혀 가지지 않고 시간 범위 등을 관리합니다.
애플리케이션 모듈 계층
어플리케이션 모듈에서는 하위 모듈을 조립하는 작업이 수행됩니다.
이렇게 되면 최종적으로 다음과 같은 그림이 그려지게 됩니다.
효과
- 각 모듈이 갖는 책임과 역할이 명확하여 리팩토링 기능의 변경 영향 범위를 파악하기 용이
- 경계가 명확해짐으로써 기능의 제공 정도를 예측 가능하며 스파게티 코드 발생 가능성 저파
- 어떤 모듈에서 어느정도까지를 개발해야 할지 명확해짐
출처
https://jojoldu.tistory.com/123
https://techblog.woowahan.com/2637/
https://hyeo-noo.tistory.com/401
'세미나, 영상 요약정리' 카테고리의 다른 글
[우아콘2020] 배달의민족 마이크로서비스 여행기 - 김영한 (0) 2022.11.29 우아한 ATDD (0) 2022.10.15 실전! 멀티 모듈 프로젝트 구조와 설계 - 김대성 (0) 2022.10.11 어느 날 고민 많은 주니어 개발자가 찾아왔다 - 김영한 (0) 2022.10.10 개편의 기술 - 배달 플랫폼에서 겪은 N번의 개편 경험기 - 권용근 (0) 2022.10.09