728x90
< Microservices 분리 전략 >
서비스 분리 전략
- 기존 Monolith를 Microservice로 전환하기 위한 시작점
- 서비스 분리 원칙 및 고려 사항
- 도메인 주도 설계
- 서비스 분리 패턴
- 데이터베이스 분리 패턴
- 서비스 분리 프로세스
- 서비스 분리를 위한 3 Key Point
- 단계적으로 마이그레이션 해야 한다
- 처음에는 크게 분리하고 추후에 작게 분리하라
- 서비스 분리의 공식은 없다
MSA 전환을 위한 고민 거리들
- Monolith 분리 방법에 대한 기준
- 서비스 분리의 First Step
- 분리 대상 서비스의 선택
- 적절한 서비스의 크기 결정
- 기존 코드 재사용 vs 서비스 재개발
작고 분리가 쉬운 서비스로 워밍업
- MSA 성공적 전환을 위해서는 다양한 사전 준비사항이 있다
- Cloud, Deployment Pipeline, Container, Monitoring 등
- 본격적인 MSA 분리 전 간단한 서비스를 분리하며 역량을 내재화한다
- 한 두개 정도의 간단한 서비스를 분리하며 필요한 인프라, 프로세스를 구축한다
- 작은 Pilot 서비스를 선택한다
- 기존 Monolith에서 분리 가능한 작은 기능
- 신규 개발되는 작은 기능
- Pilot 서비스 선정 기준
- 내부적인 의존성이 가장 적은 기능
- Code 의존성이 낮음
- 데이터 의존성이 낮음
- 장애가 발생해도 전체 시스템에 영향이 적은 기능
- Incoming 호출보다 Outgoing 호출이 많은 기능 (사실 이 특징은 나중에 Monolith를 수정하면 장애가 발생할 가능성이 높아 논란의 여지가 있다)
- Fallback 처리 가능한 기능 (추천 서비스)
- 데이터의 크기, 테이블의 개수가 적은 기능
- 신규 서비스 -> 기존 Monolith로의 의존성이 없거나 적은 서비스
- 분리된 신규 서비스는 독립적으로 개발/배포 될 수 있는 것이 좋다
- 신규 서비스 -> 기존 Monolith 의존성이 존재하면 Monolith의 변경에 영향을 받는다
- 내부적인 의존성이 가장 적은 기능
핵심 기능의 분리
- 앞 단계에서의 워밍업이 끝나면 개발팀, 운영팀 모두 MSA를 위한 기본 내공이 쌓여 있을 것이다
- 워밍업 후 운영, 배포, 프로세스, 조직 등에 대한 회고를 진행한 후에 핵심 기능 분리에 대응할 준비를 해야한다
- 핵심 기능은 다른 기능들과의 결합도가 높을 가능성이 크다
- 도메인 경계가 명확하지 않을 가능성이 높다
- 장기간의 유지보수
- 요구사항의 변화
- 개발자의 변경
- 우선 분리할 핵심 기능의 도메인을 명확하게 해야 한다
- 상품 전시, 결제, 회원, 추천 등 도메인을 발견하고 분리 대상을 선정한다 (ex. 커머스 서비스)
- 복잡한 Monolith에서 분리할 도메인을 식별하는 것은 어려운 작업이다
- 비즈니스 팀 구조를 기반으로 분리한다
- 기존 사업팀이 결제, 회원, 추천 등으로 분리되어 있는 조직의 경우
- 사업팀의 구조는 조직에서 깊은 고민을 한 결과로 만들어졌을 것이다
- 따라서 사업팀 별로 응집도 높은 비즈니스 기능을 갖고있을 가능성이 높다
- 사업팀의 구조는 하나의 서비스로 도출 가능한 훌륭한 후보이다
- 도메인 주도 설계 적용
- Event Storming을 수행하며 시스템의 Sub Domain 및 Bounded Context를 발견한다
- 고객이 발생시키는 이벤트를 시작점으로 하여 Path를 발견한다
- ex) 회원 가입 요청 -> 회원 데이터 저장 -> 이메일 발송 -> 포인트 적립
- 엔지니어 뿐만 아니라 도메인 전문가도 참여하여 비즈니스의 핵심 도메인을 발견하고 용어를 통일한다
- 핵심 기능은 다른 기능들과의 결합도가 높을 것이다
- 핵심 기능 분리를 위한 상세한 의존성 분석 과정이 필요하다
- 정적 분석 프로세스를 통해 상세 의존성을 분석한다 -> Method Call, Inheritance, Table Join etc.
- 다양한 정적 분석 도구 활용 필수 -> Structure101, Stan4J, Klocwork, coverity
데이터의 분리
- MSA 전환의 가장 큰 목적 중 하나는 서비스들의 독립적인 배포이다
- 서비스 간 결합도를 최소한으로 유지해야 달성 가능하다
- 데이터베이스의 분리 없이는 이 목적을 100% 달성하는 것은 불가능하다
- 데이터베이스 공유로 인한 강한 결합 때문에 데이터베이스 분리가 필요하다
- MSA 전환 초기에는 워밍업을 위해 DB 분리 없이 코드만 분리가 가능하다
- 그러나 Anti-Pattern 중 하나가 서비스 별 공유 DB를 갖는 것이다
- 따라서 서비스 분리 시, 독립된 저장소 및 데이터 Migration 전략 수립이 동반되어야 한다
- 데이터 분리 패턴은 이후 추가 설명할 예정!
분리 대상 선정
- First Step은 조직의 목표를 명확하게 수립하는 것이다
- 던져봐야 할 질문
- 현재 가장 문제가 되는 기능이 무엇인가?
- 앞으로 비즈니스 요구사항 변경이 빈번할 것 같은 기능이 무엇인가?
- 현재 잦은 코드 수정으로 인해 빌드/배포를 야기하는 기능이 무엇인가?
- 앞으로 유연한 수평 확장이 필요한 기능이 무엇인가?
- 변경의 관점에서 분리 대상을 선정한다
- 코드 커밋 히스토리를 파악하여 기능별 빈도를 분석한다
- 프로젝트 로드맵을 기반으로 향후에 크게 수정될 기능을 선정한다
- 분리 대상 선정을 위해 개발팀 뿐만 아니라 제품 책임자, 도메인 전문가와 끊임없는 의사 소통이 필수이다
- 분리 대상 선정의 예시
- 조직에서 최근 추천 시스템을 개발한 경우
- 자주 코드를 수정하기 떄문에 Production 환경에 배포 후 실험을 해야 한다
- 빈번한 빌드/배포가 힘들고, 그로 인해 빠른 기능 변화가 어렵다
- 따라서 이러한 기능부터 서비스를 분리하면 즉각적인 효율성 증대가 가능하다
< Microservices 분리 전략 2 >
코드의 재사용 vs 재개발
- 분리 대상 서비스 확정 후에는 재사용/재개발 고민이 필요하다
- 일반적으로 코드를 재사용하여 서비스로 구성하는 것이 효율적으로 보인다
- 그러나 기존 코드 재사용이 오히려 비효율을 초래할 가능성이 높다
- 기존 코드의 문제점
- 기존 코드는 기술 부채가 많이 쌓여 있고, 기술 자체도 오래되었을 가능성이 높다
- 수없이 변경된 요구사항을 반영한 코드들은 현재 비즈니스 도메인이 반영되어 있지 않을 가능성이 높다
- ex) Member, Account, Customer, User... 의 사용을 파악하기 어렵다
- 오래된 기술의 DB, Framework, Library와 관련된 Boilerplate Code가 많은 가능성이 높다
- 재개발의 장점
- 기능의 완전한 재작성의 장점
- 요구사항을 다시 파악하여 해당 기능에 대한 비즈니스 도메인을 명확화할 수 있다
- 비즈니스에 대한 더 높은 이해를 바탕으로 아키텍처 재설계가 가능하다
- 기존 쌓여 있던 기술 부채를 해결할 수 있다
- 새로운 기술 스택을 도입하여 Polygot Architecture 만족
진화적인 서비스 분리
- 서비스 분리 시에 가장 큰 고민거리 중 하나가 서비스의 크기이다
- 얼마나 작게 분리할 것인가에 대한 문제
- 사실 정답은 없다
- 원칙 - Go Macro, then Micro
- 우선 크게 분리하고 필요한 경우 재설계를 통해 더 작게 분리한다
- 서비스의 크기가 너무 작으면?
- 각 서비스는 응집도 높은 비즈니스 로직 없이 CRUD만 수행한다
- 서비스의 개수는 폭발적으로 늘어나게 될 것이다
- 너무 많은 수의 서비스는 운영에 대한 복잡도를 늘리게 된다
- 우선 크게 분리하고 그 이후에 설계에 대한 고민을 반복적으로 하며 추가적으로 분리하는 진화적인 사고가 필요하다
- 서비스 크기에 대한 휴리스틱
- Two Pizza Team - 2판의 피자를 알맞게 나눠먹을 수준의 팀
- 한 사람의 머리로 전체 관리가 가능한 수준
- 2주 안에 완전히 재작성 될 수 있는 수준
- 1 서비스에 12 사람
- 독립적으로 배포 가능한 수준
- 크기에 집착하기 보단 하나의 서비스가 하나의 비즈니스 기능을 응집도 높게 갖고 있는지가 중요하다
반복/점진적 분리
- 전체 Monolith를 MSA로 전환하는 건 길고 비용이 많이 드는 여정이다
- 크고 원대한 목표와 계획은 실패할 가능성이 높고 중간에 쉽게 지칠 수 있다
- 작고 명확한 계획의 여러 단계를 만드는 것이 유리하다
- MSA 전환을 위한 반복적이고 점진적인 방법론을 취해야 한다
- 한번에 하나씩 단계적으로 분리한다
- The only thing a Big Bang re-architecture guarantees is a Big Bang! - Maritn Fowler
- 서비스의 분리/통합의 복잡도
- 하나의 작은 기능을 신규 서비스로 분리한다
- 클라이언트로부터의 Request를 신규 서비스로 전환한다
- Proxy가 필요하다
- Monolith에서 Method를 호출하던 의존성을 모두 신규 서비스로 전환한다
- Monolith 내부의 기존 코드는 잠시 유지 후 반드시 제거한다
- 시간이 지나면 Monolith는 점점 작아져 결국 사라지는 전략이다
MSA와 함께 신기술을 도입한다
- MSA는 혁신과 실험을 가능하게 한다
- 그러나 MSA를 막 도입하는 시점에서의 실험/혁신은 복잡도를 크게 증가시킬 수 있다
- MSA로 전환하고 초기에 관리하는 부분만 해도 많은 어려움이 존재한다
- 기본적인 인프라나 방법론이 세팅이 되고 조직의 성숙도가 높아졌을때 시도하는 것이 좋다
서비스 분리와 조직
- 서비스를 분리하여 새로운 서비스를 만들 전담 팀이 필요하다
- 기존 서비스를 분리하면 업무량이 많아진다
- 기존 기능을 유지보수하면서 MSA 분리까지 하기는 어렵다
- 달리는 차의 타이어를 바꾸는 느낌
- 기존 모놀리틱의 기능도 계속 유지보수되어야 한다
- 상황에 따라 신규 인력 충원도 필요하다
- Cross Functional TFT 구성 - 기획, 디자인, 개발, 운영
- 첫 MSA 분리가 성공하기 까지는 TFT 인력들은 다른 업무가 없어야 한다
- 즉, MSA에만 집중할 수 있는 인력이 필요하다
< 응집도와 결합도 그리고 SRP >
Microservice를 위한 주요 개념
- 결합도 - Coupling
- 응집도 - Cohesion
- 단일 책임의 원칙 - SRP
결합도와 응집도
A structure is stable if cohesion is high, and coupling is low.
- Larry Constantine
- 결합도
- 특정 기능을 수정하는데 같이 수정되어야 하는 다른 기능이 얼마나 되는가
- 이외에도 결합도를 측정하는 기준은 여러가지가 있지만 주로 위의 내용을 본다
- 응집도
- 유사한 기능끼리 얼마나 잘 그룹화되어 있는가
- 즉, 결합도와 응집도 모두 변경의 관점에서 볼 수 있다
결합도
- 결합도 -> 얘를 변경하는데 왜 맨날 쟤도 같이 변경되어야 하는가?
- 기능들이 서로 협력하여 전체 시스템을 구성한다
- 완전히 독립적인 기능은 일반적이지 않다 -> 의존성이 항상 존재한다
- 최대한 의존성을 줄이도록 경계를 짓는 것이 주요 포인트이다
- 같이 변경되는 것들은 하나의 모듈로 만드는 것도 방법이다
- Bounded Context와 연관이 있다
- 의존성 분석을 통해 발견 및 완화가 가능하다
응집도
- The code that changes together, stays together
- 수정이 같이 자주되는 애들은 한 곳에 모아 놓자
- 같이 수정되는 애들끼리 수정하고 빌드하고 배포하고 운영하자! => Micorservices
단일 책임의 원칙 (SRP)
- 객체지향 프로그래밍의 원칙으로 사용된다
- 객체는 변경에 대한 이유가 단 한가지여야 한다
- 서비스는 변경에 대한 이유가 하나의 비즈니스 영역 때문이어야 한다
- ex) 결제 서비스는 결제 서비스로만 변경되어야지, 회원 서비스때문에 변경되면 안된다!
- Refactoring - Code bad smell
- Divergent Change : 한 클래스가 다른 이유로 인해 다른 방법으로 자주 변경되는 경우
- Shotgun Surgery - 변경을 할 때마다 많은 클래스를 수정하는 경우
- MSA에서도 Code bad smell은 동일하게 적용된다
Microservice Bad Smell
- 다양한, 서로 다른 비즈니스 영역의 요구사항 변경에 의해 특정 서비스가 자주 배포되어야 한다
- ex) 결제 서비스가 결제 이외의 다른 서비스에 의해 변경되면 결제 서비스는 잘못 설계된 것이다
- 단일 비즈니스 영역의 요구사항 변경에 대해 다수의 서비스가 배포되어야 한다
- ex) 회원 서비스를 변경했더니 5개의 서비스가 배포되어야 하면 경계 설정이 잘못된 것이다
- MSA에 완벽한 답안은 없지만 끊임없이 고민하며 반복적이고 점진적으로 MSA의 Bad Smell을 수시로 확인하는 것이 좋다!
- 자율적 변경/빌드/배포가 MSA의 주요 목적이다
728x90
'코드프레소 체험단 > MSA' 카테고리의 다른 글
[마이크로서비스 아키텍처 : 패턴과 핵심 기술] MSA 분리 전략 - Microservice 분리 프로세스 (0) | 2022.05.27 |
---|---|
[마이크로서비스 아키텍처 : 패턴과 핵심 기술] MSA 분리 전략 - 도메인 주도 설계 (0) | 2022.05.27 |
[마이크로서비스 : 패턴과 핵심 기술] MSA 도입을 위한 역량 및 필요조건 (0) | 2022.05.25 |
[마이크로서비스 아키텍처 : 패턴과 핵심 기술] MSA 개념과 주요 특징 (0) | 2022.05.18 |
[마이크로서비스 아키텍처 : 패턴과 핵심 기술] MSA 소개 (0) | 2022.05.16 |
댓글