MSA 모르면 백엔드 개발 하지 마세요 → MSA로 백엔드 개발을 한다는 것으로 글 제목을 수정했습니다. 자극적인 글 제목에 대해 반성하는 마음으로 글을 계속 수정하고 있습니다.
사실 모든 백엔드 개발자가 MSA
를 알 필요도 없고, 모든 스타트업에서 MSA
를 적용할 필요도 없다. 하지만 이것이 나온 배경과 장점, 어떤 상황에서 쓰이는지 등을 알고 있으면 문제 상황이 생겼을 때 좀 더 능숙하게 대응할 수 있는 개발자가 될 것이라고 생각한다.
모놀리식 아키텍쳐(Monolithic Architecture)
는 소프트웨어의 모든 구성요소가 한 프로젝트에 통합되어있는 형태이다.
예를 들어, Auth 모듈, Posting 모듈, Chatting 모듈 등을 개발하고 개발 완료된 Application을 하나의 결과물로 패키징하여 배포되는 형태를 말한다. (이러한 애플리케이션을 모놀리식 애플리케이션이라고 한다.)
하지만 모놀리식 아키텍쳐는 일정 규모 이상의 서비스에서 한계를 보인다.
이게 무슨 말인지 아래에서 차근차근 읽어보자.
Scale-out
이 어렵다. (Scale-out : 여러 서버로 나누어 일을 처리하는 방식) (Monolithic Architecture
에서는 사용되지 않는 다른 모든 서비스가 Scale-out되어야 하기 때문에 부분 Scale-out이 어렵다.)Framework
와 언어
에 종속적이다.MSA
는 Micro Service Architecture의 약어이다.
위에서 말한 것처럼 모놀리식 아키텍쳐는 일정 규모 이상의 서비스에서 한계를 보인다.
생각해보자. 기존에 만들어본 토이 프로젝트와 같이 규모가 작고 트래픽이 적게 들어오는 서비스에서는 굳이 MSA
를 도입할 필요성을 못 느낄 것이다.
하지만 네이버와 같은 서비스의 경우 뉴스, 메일, 지식인, 카페, 검색엔진, 쇼핑(결제) 등의 기능이 한 백엔드 애플리케이션에 합쳐져 있다면 막대한 코드 양
이 개발과 유지보수를 어렵게 할 것이고, 많은 개발자들이 한 애플리케이션에서 작업한다면 빈번한 Conflict
가 일어날 것이며, 결국 서비스가 한계에 다다를 것이다.
이와 같은 문제를 해결하기 위해 뉴스 API, 카페 API, 쇼핑 API 등으로 다른 서버를 사용할 수 있게 하는 MSA
라는 개념이 나왔다. MSA
는 Netflix가 이 개념을 실제 서비스에 도입하여 성공적인 결과를 이끌어냈기 때문에 유명해진 것이라고 생각한다. Netfilx는 이 MSA를 이렇게 정의했다.
Bounded Context간의 느슨한 결합으로 이루어진 SOA
여기서 Bounded Context
는 관심사에 따라 비즈니스 로직을 분리해놓은 것을 뜻하고, 느슨하게 결합된(Loosely Coupled)
은 서로 강력한 의존 관계 없이 API 등의 느슨한 규약으로만 이루어져 있는 것을 뜻한다. SOA(Service Oriented Architecture)
는 여러 서비스의 상호작용으로 이루어진 소프트웨어에 대한 아키텍쳐라고 한다. (MSA와 비슷한 개념, SOA는 아래에서 더 알아보자.)
MSA는 API
를 통해서만 상호작용할 수 있다. 즉, 마이크로 서비스는 서비스의 end-point를 API의 형태로 외부에 노출하고, 실질적인 세부사항들은 모두 추상화한다. 내부의 구현 로직, 아키텍쳐, 프로그래밍 언어, 데이터베이스, 품질 유지 체계와 같은 기술적인 사항들은 서비스 API에 의해 철저히 가려진다.
각각의 서비스는 모듈화되어 있으며, 이러한 모듈끼리 RPC
또는 message-driven API
등을 이용하여 통신한다. 이러한 MSA는 각각의 개별 서비스 개발을 빠르게 해주며, 유지보수도 쉽게 해준다. 마이크로서비스는 REST
등 가벼운 통신 아키텍쳐, Kafka
등을 이용한 message stream 등을 사용한다.
CD(Continuous Deployment)
도 가볍게 할 수 있음)Scale-out
이 가능하다.모놀리식 아키텍쳐
에 비해 상대적으로 복잡하다. 개발자는 내부 시스템의 통신을 어떻게 가져가야 할지 정해야 한다.트랜잭션
유지가 어렵다.통합 테스트
가 어렵다. 개발 환경과 실제 운영 환경을 동일하게 가져가는 것이 쉽지 않다.위에서 혜성처럼 등장한 MSA
라고 표현했지만, 사실은 MSA 이전에도 모놀리식 아키텍쳐의 문제를 해결하고자 나타난 개념이 있었다. 그게 위에서 잠깐 언급한 SOA(Service Oriented Architecture)
이다. 그럼 SOA
는 왜 MSA
와 같이 유명해지지 못했을까?
이 SOA
가 MSA
와 크게 다른 점은 폴리글랏 퍼시스턴스(Ployglot Persistence)
가 아니었다는 사실과 그 당시 클라우드 서비스(Cloud Service)
를 많이 이용하지 않았다는 사실이다.
먼저 폴리글랏 퍼시스턴스
는 하나의 서비스당 하나의 DB를 사용하는 것이다. SOA
는 기본적으로 하나의 DB를 여러 서비스가 동시에 사용하는 구조이다. 그래서 DB 서버가 죽으면 다른 모든 서비스에 영향이 가게 되고, DB 트랜잭션 관리를 잘못하면 일관성이 깨지기 마련이다. 이러한 문제점들을 MSA에서는 폴리글랏 퍼시스턴스로 해결했다. 즉, MSA에서는 하나의 서비스에 하나의 DB를 사용하여 안정성을 높였다.
또 SOA가 나왔을 시기에는 클라우드 서비스
가 지금처럼 유명하지 않았다. 거의 모든 회사들이 온프레미스(On-premise)
기반으로 서버를 가동했다. 실제 서버컴을 사들여 사내 전산실에서 서버를 가동했다는 말이다. 이런 상황에서 서비스에 따라 인스턴스를 쉽게 나눠 배포하는 건 불가능했기에 SOA는 크게 흥행하지 못했다. MSA는 클라우드 서비스의 발전과 비슷한 시기에 탄생했기에, 빛을 발할 수 있었다.
위의 단점에도 불구하고 장점이 훨씬 많은 아키텍쳐이기 때문에, 스프링 개발 팀은 Spring Framework
을 작고 분산되어 클라우드에 쉽게 배포 가능한 서비스를 구축하려는 고도의 분산 모델로 이동하고 있었다. 그로써 스프링 부트
와 스프링 클라우드
라는 2개의 프로젝트를 진행했다.
스프링 부트
는스프링 프레임워크
를 재구성한 프로젝트이다. 스프링 부트의 가벼운 구조는 이후 클라우드 환경에 적용하기 적절한 형태의 프레임워크로 성장한다.
스프링 클라우드
는 Public, Private 클라우드에 마이크로서비스를 쉽게 배포하고 운영할 수 있게 돕는다.
정리하자면 MSA는 작고
, 단순하고
, 분리된
서비스 → 확장 가능하고
, 회복적이고
, 유연한
애플리케이션! 장단점이 있기에 각각 개발하는 서비스의 백엔드 특성에 맞게 알잘딱깔센 하기!!
읽어주셔서 감사합니다 :)
피드백 주신xylopeofficial
님,siwony
님께 무한히 감사드려요 🙏
https://velog.io/@xylopeofficial/%EC%95%8C%EB%A9%B4-%EC%A2%8B%EC%9D%80-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-MSA
https://wooaoe.tistory.com/57
https://go-coding.tistory.com/79
https://github.com/DGSW-Backend-Study/whitebear05_TIL/blob/main/MSA.pdf
TIL수준의 정리된 글이지만 엄청난 제목의 어그로가 인상깊었습니다.
폴리글랏 DB관련해서 h2 "MSA의 단점" 중 2번째 리스트에 딱 한줄로만 설명해서 좀 아쉽네요
더 할말이 많지만, 마지막으로 궁금한점이 있는데
prod 환경에서 배포가 어렵다는건 service 간의 높은 결합도를 가지고있으며, Eventual Consistency 하지 않다는것인데 이는 전술한 MessageStream 을 통해 해결 가능한데 어떻게 생각하시나요?
😮 고등학교 2학년이심에도 MSA 에 관심을 가지시다니 대단하시네요..!
Neflix 에서는 MSA 를 Boundery Context간의 느슨한 결합도로 이루어진 "SOA" 라고 정의하고있어요.
Redhat 에서도 MSA 를 SOA 의 확장형으로 보고있고요.
그렇다면 MSA 와 SOA 의 차이는 무엇일까요??
그리고 SOA 는 실패했음에도, MSA 왜 성공한걸까요?
또한, gRPC, HTTPAPI, MessageQueue 등 아웃바운드 포트가 파편화되었을때 이들을 하나로 묶어주기 위해선 어떻게해야할까요?
모든 서비스에서 공통적으로 처리해야하는 인증/인가 로직은 어떻게 처리하는것이 효율적일까요?
말씀하셧듯, MSA 는 여러 서비스의 상호작용으로 비즈니스 로직을 수행하기떄문에, 하나의 서비스에서 에러가 발생하면 해당 에러가 다른 서비스들에게도 전파되어 크리티컬 에러가 발생할 위험이 있어요. 이를 해결하기위해선 어떻게 해야할까요?
MSA에서는 폴리글랏 퍼시스턴스를 통해 모든 DB가 분산되어있어요. 보통은 Two Phase Commit 방식으로 분산된 DB의 트랜젝션을 관리하겠지만, MSA 에서는 DB 분산 뿐 아니라NoSQL 등 Two Phase Commit 방식을 지원하지 않는 DB도 존재해요. 그렇다면 이러한 여러 트랜젝션을 어떻게 관리해야할까요?
MSA 하면 SpringCloud 뿐 아니라, SpringCloud의 몇몇 기술의 원본이된 Netflix OSS 생태계 또한 유명하더라구요
이러한 부분들에 대해서도 조금 더 추가가 된다면 더욱 좋은 글이 될 것 같아요!
좋은 글 작성해주셔서 감사합니다 ㅎㅎ
MSA 라는 단어를 오늘 처음 본 사람도 알아들을 수 있을 정도로 문체나 정리기법이 깔끔한 것 같습니다. 덕분에 기본적인 부분들 다시 짚고 갑니다. 감사합니다!
와우 제목보고 그래 얼마나 잘 써놧나 보러왔는데 이미 피드백을 받고 수정하셧군요
나이도 어리신것 같은데
지식의 깊이가 대단합니다!
멋진 개발자가 되시겟어요 ㅎㅎ
그... 혹시나 MSA 찬양글만 있을것 같아서 실무적으로 고려할 점을 적어보면
잠깐 언급하신것 같긴한데 메시지큐던 뭐던 간에 트랜잭션 처리가 상당히 골치가 아픕니다.
그리고 각각 API별로 서비스가 분리되기 때문에 유지비용도 장난 아니게 올라갑니다.
간단하게 예를 들자면 모놀리틱 서비스는 관리자 1명이 커버 가능 했다고 하면
MSA는 크기가 커질수록 관리하는 사람도 곱절이 되어야 하겠죠?
예전 SOA나 지금 MSA나 다를바 없는건 구성이 복잡하다는 겁니다.
단지 XML에서 JSON으로 데이터 전달 방식이 바뀌고 클라우드 서비스가 활성화 된것
그리고 넷플리스의 경험을 통한 기술적 진보???
뭐.. 썰이 길었습니다만..
중소규모에서 MSA는 비추이거나 이커머스일 경우 주문, 상품 정도만 분리해서 처리하기를 의견드리고
대형 규모 MSA는 회사에 일단 돈이 많아야 가능합니다.
좋은글 잘 읽었습니다.
저도 모노레포로 프로젝트 진행중인데 비슷한 개념인거 같네요!