김동욱님의 "마이크로서비스 아키텍처 구축 가이드"를 기반으로 공부한 내용입니다.
📕 목차
1. Definition
2. Overview
3. 대표적인 사례와 특징
4. 점진적 변환 vs 빅뱅 변환
1. Definition
📌 기존 방식의 Monolithic Architecture
Pros
- 구조가 단순하고, 테스트가 용이하다.
- 개발 환경과 방법이 통일
- 배포가 간편하다.
Cons
- 프로젝트 규모가 커질 수록 복잡도가 심각하게 증가한다.
- 코드 전체를 이해하기 힘들고, 빌드 시간이 증가한다.
- 새로운 기술을 적용하려면 프로젝트를 다 갈아 엎어야 한다.
📌 MSA(Microservice Architecture)
MSA는 시스템을 독립적으로 배포할 수 있는 서비스들로 구성하고 각 서비스는 잘 정의된 API로 통신한다.
서비스는 기능 단위로 나뉘어 작고 독립적인 팀들이 담당한다.
이러한 MSA는 애플리케이션의 확장이 쉽고 개발 속도가 향상되어 새로운 기능 출시까지의 시간을 단축시켜 준다.
pros
- 서비스 단위로 변경하고 독립적 배포 가능
- API로 기능을 재사용하고 조합하여 신규 기능 생성 가능
- 조직 구조에 따라 환경에 따라 정렬할 수 있다.
- 서비스 단위로 스케일 아웃할 수 있다.
- 서비스 장애가 다른 서비스로 번지는 것을 차단할 수 있다.
- 서비스 별로 다른 기술을 사용할 수 있어, 신규 기술 적용에 부담이 적다.
cons
- 서비스간 통신 규칙이 필요하며, 복잡하다.
- 서비스간 테스트가 어렵다.
- 복잡하고 독립된 구조로 통합적인 유지보수가 어려울 수 있다.
✒️ Scale Up & In & Out
• Scale Up : 서버 자원 부족으로 스펙을 상승시키는 것. AWS에선 더 좋은 인스턴스 타입 교체를 의미
• Scale In : 작업이 완료되어 더 이상 필요없는 Scale Out으로 늘렸던 컴퓨팅 수를 줄이는 것
• Scale Out : 서버 자원 스펙 상승으로 한계가 있고 효율이 떨어지는 시점에 컴퓨팅 수를 늘리는 것
2. Overview
📌 유래
Microservice Architecture는 명확한 정의가 없다.
REST(RepREsentational State Transfer)의 경우엔 아키텍처를 제시한 주체가 있고, 명확한 정의가 내려져 있다.
반면, MSA는 REST와는 다르다.
- 마이크로서비스 아키텍처는 자생적으로 생겨났기 때문에 이런 명확한 정의가 없다.
- 마이크로서비스 아키텍처를 적용하는 목표가 명확하지 않다.
- 아키텍처의 기준이 없다.
새로운 스타일을 소개한 주체가 문답을 통해 더 명확학 정의와 사례를 제공해야 하나, Microservice Architecture는 그런 주체가 없어서 여러 관련 전문가들의 공통된 의견에 따라 정의한다.
📌 협의의 정의
마이크로서비스 아키텍처의 어떤 특징이 어떠한 장점을 발현시키는지 이해해야 한다.
그래야 서비스에 맞는 부분은 살리고, 잘 맞지 않은 부분은 버리거나 보완하여 적용할 수 있다.
MSA는 그대로 사용하는 것이 아니라, 시스템 상황에 맞게 최적화하여 적용해야 한다.
아키텍처 스타일을 얼마나 동일한 형태로 구상했는지가 아닌, 시스템에 필요한 아키텍처 장점을 얼마나 잘 살렸는가로 판단한다.
Microservice Architecture 장점
- 시스템을 빠르게 변경할 수 있다.
- 각 서비스를 독립적으로 기획, 개발, 배포할 수 있다.
- 지속적인 통합과 전달이 가능하도록 단위 코드 크기를 작게 유지한다.
- 독립적 배포가 가능하다.
- 업무 단위로 장애를 차단하고 확장할 수 있다.
- 장애에 민감한 업무는 다른 업무로부터 분리하여 보호
- 다른 업무는 장애에 대한 부담을 덜어 쉽게 변경할 수 있다.
- 일부 업무에만 대용량 처리 기술 스택을 적용하여 단위 처리량 증가
Microservice Architecture 장점을 살리는 특징
- 각 서비스는 비즈니스 기능 단위로 나누어야 한다.
- 각 서비스 간에 임의적인 접근이 불가능하도록 격리해야 한다.
- 소스 코드를 분리하고 정해진 인터페이스로만 접근하게 한다.
- 다른 시스템이 내 데이터베이스를 액세스하지 못하게 차단해야 한다.
- 서비스는 독립적으로 실행하고 API로 통신한다.
- 서비스 간 데이터 조회나 트랜잭션 발생을 시켜야 하는 경우, REST API나 이벤트로 통신
- 각 서비스는 독립적으로 개발하고 배포해야 한다.
- 서비스 별 독립된 팀 별로 모든 프로세스가 독립되어야 한다.
- 빌드 배포 파이프라인 반영 전에 합쳐진다면 독립적인 것이 아니다.
📌 대규모 시스템 딜리버리 퍼포먼스 복원
Monolithic architecture는 구조가 간결하고, 충분히 검증된 아키텍처 스타일이다.
따라서 작은 시스템을 개발할 때는 모놀리식 아키텍처를 선택하는 것이 효율적이다.
하지만 규모가 커지게 되면 문제가 발생한다.
- 사용자가 증가하면서 기능이 고도화되고 추가된다. (개발 참여 인원 수가 증가한다.)
- 기능 변경을 위한 협업 인원 수가 많아지고, 커뮤니케이션이 힘들어진다.
- 배포 시, 받는 스트레스가 크다.
여기서 시스템에 장애가 발생하면 어떻게 될까?
장애가 발생할 때마다 배포 프로세스는 복잡해지고 엔지니어의 부담이 커진다.
(아마도 안전성을 위해 검증 시간을 확보하긴 해야 하는데, 기간 내에 릴리즈를 하긴 해야 하니 리스크가 증가한다는 내용같다.)
이로 인해, 운영 환경에 변경 사항 반영이 부담될 수록, 요구 사항을 소극적으로 접수하게 된다.
시스템 장애를 해결하기 위해 Microservice Architecture을 적용하면 시스템을 독립적인 서비스로 분리하고 각 팀에 배정할 수 있다.
- 각 팀은 서로의 서비스 기능을 사용하기만 하고 서비스를 제공하지는 않는다.
- 다른 서비스와 보조를 맞출 필요 없고, 장애가 생겨도 다른 서비스로 전파되지 않는다.
다만, 외부에도 영향을 주는 서비스가 분명히 있을 것이다.
- 오히려 모놀리식 아키텍처일 때보다 어렵다.
- 다른 팀에서 사용하는 API 변경 시, 팀이 다르므로 커뮤니케이션 비용이 증가한다.
- 기존 API가 하위 호환성을 가질 수 있도록 추가적인 고민을 해야 한다.
- 장애가 전파될 수 있으므로 보다 신중하고 점진적 배포 방식을 고려해야 한다.
📌 대규모 시스템 딜리버리 퍼포먼스 향상
배포 주기를 단축하면 개발 리드 타임 또한 단축된다.
- As-is. 주 1회 배포하는 시스템
- 사용자가 기능 변경을 요청하고 설계, 개발, 코드 통합, 테스트, 배포 과정을 거친다.
- 특정 서비스 개발이 먼저 끝나도, 기능 검증 단계까지 '테스트 대기' 상태
- To-be. 1일 1회 배포하는 시스템
- 배포 주기가 짧아지므로 변경 완료 코드가 대기하는 시간 단축
- 매일 반영하는 변경 건이 1~2개에 불과하므로 테스트에 필요한 시간 단축
- 필연적으로 리드 타임 단축
하지만 배포 주기를 단축하는 것은 마냥 쉬운 일이 아니다.
대규모 시스템은 지속적인 전달을 도입하여 딜리버리 퍼포먼스를 향상하는 것이 상대적으로 어렵다.
이를 위해서는 조직을 여러 개의 작은 조직으로 만들어 협업 인원을 줄여야 한다.
그리고 시스템을 작은 서비스로 분리하여 한 번에 배포하는 변경 건수를 줄여야 한다.
즉, N개의 변경 건을 한 번에 배포하는 모놀리식 시스템보다는 N개의 변경 건을 M개의 팀이 나누어서 매일 테스트&배포 하는 것이 대규모 시스템에 적합하다.
- 전체 변경 건은 동일하지만, 함께 일하는 개발자 수가 M분의 1로 줄어 코드 통합이 쉽다.
- 한 번에 1~2개 기능만 반영하므로 검증이 쉽다
- 변경 기능에 문제가 생겨도 다른 서비스에 직접적으로 영향을 주지 않는다.
- 다른 변경 건과 상관없이 이전 버전 복구가 가능하다.
📌 이해하기 어려운 이유
- MSA로 해결하려는 목표는 기술적인 것이 아니다.
- 거대한 조직 개발 생산성 유지, 작은 조직들의 독립적이고 빠르게 나아가는 것이 목표
- 비기술적인 측면에 공감을 못하면 장점을 인식하기 힘들다.
- 지속적인 전달(CD)과 같은 최신 소프트웨어 배포 방식을 이해하지 못하기 때문이다.
- 마이크로서비스 아키텍처가 개발 속도 혹은 개발 생산성을 높인다는 것은 운영 중인 시스템이 빠르게 변경되고 진화해간다는 뜻이다.
- 여긴 추측이지만, 아마 서비스 별로 팀을 나눈다는 것이 단순히 개발팀을 말하는 것이 아닐 것이다.
- MSA는 프로세스 독립적으로 움직여야 한다. 따라서 운영팀 또한 독립적일 것이다.
- 즉, 개발속도가 빨라진다는 것은 단순히 Develop 측면이 아니라 전체 Product 설계 관점에서 보는 것이 맞다. (아닐 수도..)
📌 마이크로서비스 아키텍처와 직접적인 관련이 없는 것들
- REST API는 MSA와 직접적인 관련이 없다.
- 기능 재사용에 좋은 수단이므로 API가 구체적인 목표가 될 수는 있다.
- 하지만 UI단은 SPA 개발하는 것이 사실상 표준이 되었다.
- 따라서 API는 MSA를 차별화하는 특징은 아니다.
- 때로는 재사용 관점에서 MSA를 바라보기도 한다.
- 중복 기능이 많거나 다른 시스템과 시너지를 발휘할 수 있는 업무가 있다면 추구할 만한 가치가 있다.
- 하지만 MSA 본질과는 거리가 있다.
- 구체적 재사용 니즈가 확보되면 기존 시스템 구조를 유지한 채 기능 공유하는 것도 가능하다.
- '클라우드 네이티브' 혹은 '클라우드 네이티브 애플리케이션'은 MSA와 함께 거론되는 경우가 많다.
- 클라우드 인프라에 마이크로서비스 아키텍처를 사용하는 경우가 흔하다.
- 하지만 모놀리식 시스템도 클라우드 인프라를 사용한다면, 잘 활용할 수 있는 구조를 갖춰야 한다.
- 클라우드 네이티브 애플리케이션은 두 아키텍처를 포함하는 개념이라 보는 게 더 맞다.
3. 대표적인 사례와 특징
📌 사례
- 넷플릭스
- 사운드 클라우드
- 길트
- 우버
- 쿠팡
📌 특징 (공통점)
- 인터넷 기반의 B2C 비지니스 시스템
- 경쟁이 심한 시장에서 경쟁력 있는 핵심 서비스를 제공하는 시스템
- 시스템을 개발하고 운영하는 엔지이너 수가 많음
- MSA를 도입하던 당시의 상황은 경험해보지 못한 새로운 상황이었다.
어쩌면 여기가 조금 핵심이 아닐까.
무조건 "요즘 트렌드가 마이크로서비스 아키텍처니까 그렇게 설계하자!"가 답이 아니다.
실제로 초기 스타트 단계에선 오히려 마이크로서비스가 생산성을 감소시킬 수도 있다.
MSA가 왜 나왔는지를 생각해보라. 그리고 프로젝트에 적용하기 전에 아래 질문에 반문해봐라.
- 애플리케이션이 크고 복잡해질 가능성이 있나?
- 가용성과 확장성을 갖춰야 하는가?
- 마이크로서비스에 대한 경험이 있는가?
4. 점진적 변환 vs 빅뱅 변환
💡 중요한 것은 MSA를 반영하는 것이 아니라, 시스템의 목표를 어떻게 달성하느냐다.
📌 점진적인 변환
- 스트랭글러(Strangler) 패턴을 적용하여 점진적으로 변환
- 모놀리식 아키텍처에서 일부 기능을 서비스를 분리하고 기존 코드를 대체하는 작업을 반복하여 궁극적으로 마이크로서비스 아키텍처로 전환
- 시간이 오래 걸리지만 리스크가 낮다.
- 마이크로서비스 아키텍처의 모습을 갖추는 것이 중요한 것이 아니다.
- 단순히 거대해진 시스템을 분할하여 개선속도를 향상시키는 것이 목표라면 작은 덩어리로 나누는 것이 중요하다.
- 전체 시스템의 모양이나 어떤 기술이 사용되는지 중요하지 않다.
- 점진적인 전환 과정에서 조직 매핑을 함께 진행한다.
- 스케일 아웃을 위해 마이크로서비스 아키텍처를 도입하는 경우 더 명확하다.
📌 빅뱅 변환
- 100여 명 이상 인원이 담당하는 대규모 시스템 전면 재개발과 익숙하지 않은 아키텍처와 기술을 더하면 감당하기 어려운 수준의 리스크를 감당해야할 수도 있다.
- 점진적 전환이 불가능하거나 처음 만드는 시스템 혹은 전면 재개발 계획이 수립된 경우에 적합하다.