이 글은 마이크로 서비스 아키텍처에 대해 굉장히 주관적인 생각을 담고 있습니다
혹시나 불편하실 수 있다는 점 말씀드립니다...
MSA를 하는 회사에 처음 들어가게 되었다...
회사에서 프로젝트를 보기 전엔 회사 아키텍처가 MSA란 것을 알지 못했다
공고엔 Spring Cloud라고 적혀있었지만,
특정 기술로 구성된 서버만 별도로 분리하고 그 외의 백엔드 서버는 모놀리식으로 구성되어 있다고 생각했다
큰 규모의 회사도 아니었고 그런 비용이 높은 설계를 굳이 채택할 필요가 없었다는 생각이 있었던 것 같다
그 덕분에 MSA에 대해 직접적인 경험을 할 수 있었다
사실 난 MSA에 관해 아주 많은 관심이 있던 사람 중 한 명이다
패션을 좋아하면 올해에 무슨 색이 시그니처인지 관심이 가는 것 처럼,
나 또한 22~23년의 개발계 핫 키워드인 MSA에 꽃혔다
하지만 이 생각은 직접 경험을 하면서 깨지게 되었다
경험에 기반한 단점들에 대해 소개한다
편의상 마이크로 서비스의 약어로 MS 혹은 ms라고 표기한다
여러개의 인텔리제이 창
(이 부분은 회사마다 다르다) 우선 다른 도메인 코드를 보기 위해서는 새로운 프로젝트를 열어야 했다
즉 인텔리제이 창을 여러개 띄우고 왔다갔다를 해야한다는 뜻인데, 이게 생각보다 집중의 흐름이 끊기는 포인트 중 하나다
공통 코드 관리
또 다른 고민은 공통 모듈에 대한 관리다
예를들어 어떤 공통 기능을 수정했다고 하자
그러면 이에 따른 서비스 영향도가 어디까지 미치게 되는지를 예상하기 힘들다
(회사들마다 다르지만, 이곳은 Mavan Nexus에서 Gradle 의존성을 가져오는 방식으로 되어있다)
위에서 얘기한 것과 연관된 건데, 마이크로서비스의 특정 기능이나 DTO 스펙이 바뀔 경우 영향도를 유추하기 쉽지 않다는 것이다 (단, 모든 서비스가 한 프로젝트 내에 있을 경우는 무관하다
임시 해결책으로 마이크로 서비스마다의 공통모듈을 추출해서
해당 모듈을 변경해서, 다른 서비스들이 재 배포가 필요할 경우
해당 모듈을 가진 repo를 모두 찾아서 해당 서비스를 재 배포한다는 아이디어가 있었지만 일정상 하지는 못했다
설계 비용 증가
또 다른 문제는 설계 비용이 들어간다는 것이다
내가 마지막으로 했던 개발은 (자세히 적을수 없으며 예시이다) 카페와 기존의 구독형 결제를 연결하는 개발이었다
구독 기간에 따른 회원별로 다른 요금을 부과해야 했다
그러다 보니 'cafe_subscription`, `cafe_member_subscription` 등의 엔티티가 필요하게 되었다
문제는 데이터 정합성과 안정성 때문에 저 두 엔티티(테이블)이 서로 다른 마이크로 서비스에 들어가게 되었다
실제로 위 두 엔티티는 카페 서비스와 결제 서비스 모두와 연관있다 (테이블명이 그렇듯이)
어디에 두느냐에 따라 API스펙, 로직이 달라진다...
고민에 따른 비용이 들어간다
테스트 품질은 하락, 비용은 증가
본래 하나의 트랜잭션으로 묶였던 것을 n개의 서비스로 나뉘다 보니 내부 API요청 / 이벤트 발행을 하게되고 테스트 코드상에선 이 부분을 mocking해야했다
그리고 본디 mocking을 하면 실제 현상과는 다르다는 것을 전제하기 때문에 테스트 신뢰도도 떨어진다
마이크로 서비스의 경계에 대한 고민
도대체 어디까지가 마이크로 서비스인가?
예를 들어 회원 서비스, 상품 서비스로 각 ms로 보는 건 자명해 보이지만
게시판 서비스, 리뷰 서비스로 ms를 나누는 건 그렇지 않다
마틴 팔로우가 MSA에 비판한 내용 중 하나는 "특별한 별 기능 없는 도메인이 서비스 하나를 담당"하는 경우가 있다는 것이다
저런 부분에 대해 다루려면 DDD의 Bounded Context, 콘웨이 법칙, 회사 내부 사정 등 다양하게 고민할 필요가 있어 보인다...
개인 개발 환경 구축 문제
모놀리스와 달리 개인 환경에서 하나의 ms를 개발할 때 이런 불편함이 생긴다
예를 들어 보통은 유저 서비스가 Upstream의 역할을 담당하기 때문에 어떤 ms를 개발하던 유저 서비스의 정보가 필요하다
따라서 내 로컬 환경에서도 유저 서비스가 필요한데, 전 회사의 경우는 로컬 환경이 개발 환경을 바라보게끔하는 방식으로 해결했다
그러나 가끔 개발을 하다 보면 테스트 데이터 등의 이유로 순수한 로컬 환경이 절실할 때가 있다
이럴 때는 개인 로컬에서 Eureka + Gateway + User Service 까지 모두 실행해야 한다
그 외
그외 아래와 같은 문제들이 있다...
트랜잭션 문제
널리 알려진 문제지만 트랜잭션이 보장되지 않는다
이걸 해결 하기 위해 다양한 기법들이 있다
- 사가 패턴
- 동기식 처리
예를 들어 사가패턴의 경우, 실패한 경우에 대한 보상 트랜잭션 처리 로직까지 구현해야 하는데...
100개의 API가 있다면 모든 부분에 대한 사가 패턴 처리를 하면 작업 공수가 산으로 갈 것이다...
따라서 자주 사용하거나 절대로 정합성에 문제가 있으면 안돼는 곳에만 부분적인 처리를 해야된다고 생각한다
배포 난이도 문제
나의 경우 배포(실행) 순서를
유레카 -> 게이트웨이 -> 각 마이크로서비스
-로 한다
그리고 각 서비스가 정상 동작하려면 5~30초 정도의 시간이 필요하다
따라서 이런 부분에 대한 배포 난이도 문제가 자연스레 증가한다
AWS 비용 - 서비스 배포 자체의 비용
당연한 얘기지만 각 마이크로 서비스를 모두 별도의 물리 서버로 배포하면 비용이 많이 든다
당시 AWS Light버전은 한 대당 5천원 정도의 비용이 소모되었다
마이크로 서비스가 10대면 5만원 정도의 비용이 드는 것이다
물론 마이크로 서비스 n개를 하나의 물리 서버에 배포하는 방법도 존재한다
AWS 비용 - 네트워크 통신의 비용
모놀리스 안에서는 자기 스스로 트랜잭션 처리(Command)와 Join (Query)를 하기 때문에 Network I/O가 일어나지 않는다하지만 MSA를 하는 경우 옆동네를 거치는 것만으로도 네트워크 비용이 소모 된다. 아키텍처에 따라선 실제 과금이 될 수도 있지 않을까... (서로 다른 네트워크 대역을 거쳐야만 하는 경우가 생기면)
참고
마틴 파울러와 MSA 책저자가 토론하는 내용이다..
마틴 파울러는 엔터프라이즈 아키텍처 "분산 컴포넌트" 챕터에서
자기가 어떤 클라이언트에게 "이 좋은 MSA를 몰라요?" 하면서 질타를 받았던 과거에 대해 썰을 풀었다
마틴은 이유 없이 모놀리스를 분산 형태의 아키텍처로 가는 것에 대해 회의적으로 생각하고
그래야 한다면 최후의 상황에서 해야 한다고 생각하는 것 같다
이글을 작성하는 시점인 현재의 나 또한 그렇게 생각한다...
'Back-end > Spring Cloud, MSA' 카테고리의 다른 글
Spring Cloud Gateway 테스트 코드와 리펙터링 (Kotlin-DSL) (0) | 2024.01.14 |
---|---|
Eureka 시나리오별 등록 과정 + 빠른 배포하기 (0) | 2023.12.18 |
실전에서 마주한 MSA에 대한 생각 - 희망편 (0) | 2023.11.26 |
Spring Cloud Config 을 이용한 빠른 YAML 리펙터링 (0) | 2023.05.29 |
hi hello... World >< 가장 아름다운 하나의 해답이 존재한다
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!