동현 유
척척석사
동현 유
전체 방문자
오늘
어제
  • 분류 전체보기 (181)
    • BlockChain (48)
      • [paper] Consensus (13)
      • [paper] Execution (19)
      • [paper] Storage (5)
      • [paper] ZKP (1)
      • [paper] Oracle (1)
      • Blockchains (9)
    • Java (19)
      • Java의 정석 (13)
      • Java 파헤치기 (5)
    • Python (20)
      • Python 뜯어보기 (6)
      • 데이터 분석 기초 (5)
      • Python 기초 강의 (6)
      • Python 기초 강의 부록 (3)
    • Golang (0)
    • MySQL (3)
      • programmers (2)
      • 기본 문법 (0)
    • 웹 프로젝트 (IBAS) (36)
      • Django 레거시 (14)
      • SpringBoot api 개편 (14)
      • Infra (3)
      • 서버 장애 기록 (4)
      • 신입팀원 교육 자료 (1)
    • CS (30)
      • Operating System (22)
      • Computer Security (3)
      • Network (4)
      • DBMS (1)
    • 책 (10)
      • 도메인 주도 설계 철저 입문 (9)
      • Real MySQL 8.0 (1)
    • BOJ 문제 풀이 (3)
    • 이러쿵저러쿵 (10)
    • 회고 (1)

인기 글

최근 댓글

최근 글

hELLO · Designed By 정상우.
동현 유

척척석사

[Spring boot] 5. 멀티모듈? MSA? 좋은 아키텍쳐가 뭐야?!
웹 프로젝트 (IBAS)/SpringBoot api 개편

[Spring boot] 5. 멀티모듈? MSA? 좋은 아키텍쳐가 뭐야?!

2022. 3. 9. 02:22

프로젝트 구조 변경을 고민하게 된 배경이 몇가지 있다.

 

(1) layer 는 구분이 가지만, 파일이 많아져서 해당 layer 안의 특정 도메인을 한눈에 찾기가 어려워지고 있다. 또 그렇다보니 어떤 도메인 모델이 어떤 service 와 controller 로 이어지는지 알기도 힘들어질 것  같았다. 특히 새로운 개발자가 들어왔을때는 확실히 눈에 안보일 거 같았다.

 

(2) 또 파일 업로드 및 다운로드를 동료 개발자가 맡아서 처리하고 있는데, 해당 기능은 완전히 독립적인 서비스로 빠져도 될 것 같다는 생각이 들었다. (원격 서버에 실제 파일을 업로드하고 다운로드 하게 해주는 파일 서버). 같은 모듈 내에 있는 것보다는, 적어도 다른 모듈로 독립적으로 구성할 필요가 있다.

 

(3) 빅데이터 및 ML 동아리이기 때문에, 추후에 다른 학우들이 만든 ML 서비스를 웹 서비스에 올려서 사용할 수도 있겠다는 생각이 있었다. 그래서 기존 서비스 바탕 위에 새로운 서비스를 쉽게 추가할 수 있는 좋은 구조를 고민하고 있었다.

 

그래서 도메인 별로 프로젝트를 구성해보는 건 어떨까? 라는 생각에 여러 아키텍쳐를 알아보기 시작했다... (이 때부터 혼돈 ㄷㄷ)

마구잡이로 찾아보니, 아래처럼 4가지의 구성으로 정리가 되었다.

 

  1. 모노리스 (가장 단순한 단일 프로젝트)
  2. 멀티 모듈을 layer 별로 구성(core, service, api, 등) => 모노리스 (하나의 JVM)
  3. 멀티 모듈을 도메인 별로 구성하지만 => 모노리스 (하나의 JVM)
  4. 멀티 모듈을 도메인 별로 구성 => MSA (여러 JVM)

 

 


 

1. 모노리스

장점

  - 가장 단순한 형태로 쉽고 빠르게 개발할 수 있다. (진짜 개발할 때는 단순하고 쉬운게 최고)

 

단점

  - scale up 이 어렵다. 특정 서비스만 정교하게 확장하고자 할 때, 프로젝트를 통째로 늘려야할 수 밖에 없을 듯 하다.

  - 오류가 전파되기 쉽다. 하나의 서비스에서 쉽게 다른 컴포넌트를 가져다 사용할 수 있는 만큼, 의존성 관리가 잘 안되는 경우가 많다. 그래서 하나의 컴포넌트에서 오류가 발생했을 때, 관련 서비스들이 모두 장애를 겪을 수 있다.

 


 

2. layer 별로 구성한 멀티 모듈 프로젝트

장점

  - 흔하게 보이는 프로젝트 구조이다.

 - 개발이나 설정이 쉬운편이다. 물론 단순 모노리스에 비해서는 패키지 의존성 관리를 더 신경쓰면서 해주어야한다.

 - 프로젝트 구조상 패키지 의존성이나 모듈간의 의존성을 주의하면서 설계할 수 밖에 없다. 그래서 모노리스에 비해 의존성이 더 잘 정리되는 느낌이 있다.

 

단점

  - 패키지 의존성 관리를 잘 못하면 모노리스보다 더한 참사가 일어난다. 빌드도 꼬이고, 괜히 더 무거운 프로그램이 될 수 있다.

  - 결국은 모노리스에 비해, 패키지 의존성과 모듈 의존성 관리를 해주어야 한다는 점에서 trade off 가 있는 것 같다. 의무적으로 관리를 하게 되면서 얻는 장점도 있지만, 계속 신경써야한다.

  - 다른 말로 하면, 의존성 관리를 잘 못하면 결국 모노리스와 같은 처지이지만 관리는 좀 더 힘든 상황에 처할 수 있다.

  - 도메인 간 분리가 어려울 수 있다. 해당 layer 의 도메인이 다른 layer 의 도메인과 어떻게 이어지는 지 모를 수 있다.

 


 

3. 멀티 모듈을 도메인 별로 구성하지만 => 모노리스 (하나의 JVM)

장점

  - 프로젝트가 서비스 단위로 나뉜다. => 해당 서비스 모듈에 대한 책임자가 명확히 보인다.

  - 프로젝트 내에서 파일 찾으려, 다른 폴더 안뒤지고 있어도 된다. 대부분 같은 도메인 내에서 해결될테니까?

  - 새로운 서비스를 추가할 때, 모듈을 새로 생성해서 작업한다. => 기존의 파일들과 엮이지 않고 분리된 환경에서 개발이 가능하다.

 

단점

  - 여러 개의 서비스 모듈을 하나의 JVM 에 띄우기 위한 추가 작업이 필요하다.

  • 다른 서비스 모듈 하위 spring bean 을 등록하기 위한 추가 작업 : componentScan 하는 시점 때문에, 다른 모듈에 있는 스프링 빈을 단순하게 componentScan 으로 같이 등록할 수 없다. 이것 때문에 작업을 더 해주어야한다.)
  • 서비스 모듈별 설정파일과 패키지 의존성 관리에도 신경을 좀 써야한다.

  - 이게 진짜 애매한게, 예를 들어 동아리 홈페이지 내부의 거의 모든 서비스는 로그인한 유저 정보가 필요하다. 근데 게시글 서비스에서 로그인유저가 필요하다고 할 때, UserService 빈을 들고와서 직접 조회를 할건지,  회원 api 에 restTemplate 등으로 질의해서 해당 멤버를 가져올건지를 결정해야한다.

  - 전자를 선택하게 되면 프로젝트 구성은 도메인 별로 구분되었지만 진정한 의미의 도메인 컨텍스트 분리는 아니다. 또 추후 서비스 규모가 커져 MSA 로 전환하게 될때 다른 서비스 코드를 다 들어내야하는 작업을 해야한다. 하지만 후자를 선택하자니 서비스간 통신으로 인한 데이터 동기화 문제가 있다.

  - 어쨌든 모노리스로 하려고 한다면 서비스 규모가 그리 크지는 않을테고 앞으로도 그리 크지 않을거라고 한다면, 의존성을 잘 제어한다는 전제로 다른 서비스 모듈 코드를 직접 가져오는게 어느 정도 적절한 선일 것 같다.

 


 

4. 멀티 모듈을 도메인 별로 구성 => MSA (여러 JVM)

장점

  - 서비스 간 의존도가 가장 낮은 구조이다.

  - 그렇다보니 서비스 별로 scale up 하기가 용이하다.

 

단점

  - 서비스 간 통신에 신경을 많이 써야한다.

  - 데이터 동기화 문제, 메세지 큐 관리, 서킷 브레이커, 로드밸런싱, 분산 db 등등 오버헤드가 어마무시하게 늘어난다.

 

 


 

 

 

일주일 동안 맨 땅에 헤딩하듯이 무턱대고 찾아봤는데,,, 머리가 너무 아프다...

 

이것 때문에 책 3권을 뚝딱 읽어버리고

("도메인 주도 설계 철저 입문", "도메인 주도 설계로 시작하는 마이크로 서비스 개발", "마스터링 스프링 클라우드")

 

여러 깃헙 레파지토리도 찾아보고 (인상 깊었던 레파지토리 : https://github.com/piomin/sample-spring-microservices-new, https://github.com/arawn/building-modular-monoliths-using-spring)

 

기타 블로그 글 및 레퍼런스들을 많이 읽어보면서

(서비스 별 멀티모듈 분리 : https://daddyprogrammer.org/post/13156/spring-boot-change-multi-module/)

(DDD 글 설명 잘 되어있는 글: https://medium.com/raa-labs/part-1-domain-driven-design-like-a-pro-f9e78d081f10)

 

여러가지 시도를 해봤는데,, (https://github.com/Dong-Hyeon-Yu/Inhabas.com-api/tree/study/multi-module, https://github.com/Dong-Hyeon-Yu/spring-cloud-monitoring-example )

 

잘 모르겠다... 허허허

 

지금 아키텍쳐를 바꾸는 비용이 얻는 거에 비해 훨씬 많이 들 거 같다. 

(내가 너무 지치고,, 1주일 째 고민중이어서 더이상 시간끌면 진행이 안될듯.)

 

굳이 이 문제 때문에 프로젝트가 진행이 아예 안되는 상황도 아니어서

 

일단 이런 고민들을 갖고 계속 진행해보기로 한다.

 


 

일단 당장 작업해야하는 파일 서버는 새로운 모듈로 만들고

 

추후에 OAuth2 인증 서버를 분리해내서 + cloud 게이트웨이랑 붙여야겠다.

 

그러면 (인증서버, 리소스서버, 파일서버) 이렇게 나중에 분리가 될 예정이다.


단일 모노리스 프로젝트라도,

 

bounded context 를 잘 정의하고

 

응집과 결합를 잘 다스린다면,

 

괜찮겠지 허허

 

도메인을 잘 나누고, 의존성을 어떻게 하면 낮추면서 좋은 아키텍쳐를 만들어 갈 수 있을지 계속 고민해봐야겠다.

 

힘들다. 이런 개발.

 

'웹 프로젝트 (IBAS) > SpringBoot api 개편' 카테고리의 다른 글

[Spring Boot] 4. 로컬 개발을 위한 CORS 설정 - (2) Spring MVC 와 Spring Security  (0) 2022.04.15
[SpringBoot] 6. ManyToMany 를 "일대다/다대일"로 풀어서 사용하기 (+ 영속성 전이 문제)  (0) 2022.03.20
[Spring Boot] 4. 로컬 개발을 위한 CORS 설정 - (1) w3c recommendation  (0) 2022.02.28
[Spring Boot] 3. OAuth2 인증 설계 및 구현 (feat. Security FilterChain 분석)  (0) 2022.02.28
[Spring Boot] 2. 서버 개발 환경 분리 (Spring Cloud Config 적용) 및 배포 자동화  (0) 2022.02.28
    동현 유
    동현 유
    Fault Tolerant System Researcher for more Trustful World and Better Lives. (LinkedIn: https://www.linkedin.com/in/donghyeon-ryu-526b8a276/)

    티스토리툴바