Top - Down Approach
설계의 목적과 분석부터 시작한다.
Discover 단계
MSA 설계와 프로토타이핑을 진행한다.
Delivery 단계
- API 설계
- 어플리케이션 분산 설계
- 마이크로 서비스 개발
- CI/CD 테스트
- 마이크로 서비스 테스트
CI/CD를 제외한 4가지를 반복적으로 진행한다.
Bottom-Up Approach
일반적인 회사에서는 이 방식을 사용한다.
현행 시스템에 대한 분석부터 시작한다.
Delivery 단계
- API 설계
- 어플리케이션 분산 설계
- 마이크로 서비스 개발 -> 기존 서비스 리팩토링 단계
- CI/CD 테스트
- 마이크로 서비스 테스트
DevOps 단계 추가
서비스 모델링
분석
후보 서비스 도출
- 비지니스 도메인 분석을 통한 후보 서비스 식별
후보 서비스 평가 항목
- 신속하고 독립적인 배포가 가능한가?
- 트랜잭션의 폭증에 스케일 아웃이 원활하게 이뤄질 수 있나?
- 장애의 격리가 가능한가?
후보 서비스 연관도
- API 설계
- 분산 트랜젝션 설계
- API Composition 설계
- 동기/비동기 설계
초기 서비스 정의
절차
MicroService Discovery
후보 서비스를 도출하는 것은 쉬운 일이 아니다. 따라서 DDD를 기반으로 서비스를 도출한다.
MicroService Design
1. API First Design
서비스간 상호 이벤트를 설계한다. ( 이벤트 스토밍 ) 서비스가 운영될 때 한 이벤트를 처리하기 위해 어떠한 서비스들이 관계를 맺는지를 우선 설계해야 한다.
- 서비스 식별 ( 어떤 서비스들이 있는지 다이어그램으로 나타낸다 )
- 컴포넌트 식별 ( 서비스 별로 어떤 컴포넌트들이 들어있을지 )
- 오퍼레이션 식별 ( 컴포넌트 별로 어떤 기능을 제공할 것인지 )
- API 식별 ( 어떤 컴포넌트를 외부에 공개해 통신할 것인지 )
- 서비스 간 상호 작용 ( 이벤트 스토밍이 어떤 식으로 연관 관계가 존재하는지 )
- API 정의서
2. 분산 트랜젝션 설계
마이크로 서비스간 분산 트랜젝션 및 보상 트랜젝션을 설계해야 한다.
분산 트랜젝션 디자인 패턴인 Saga를 활용한 Orchestration / Choreography 방식의 분산 트랜젝션 설계를 한다.
Orchestration : 중앙에서 비지니스와 트랜젝션을 제어하는 방법으로 command 기반으로 동작한다.
Choreography : 상호간 서비스 실행 결과에 따라 정상/비정상 처리 결과에 따른 로직을 수행한다. 이벤트 기반으로 동작하며, 서비스간 발행 / 구독된 이벤트에 따라 로직이 실행된다.
3. API Composition 설계
성능을 고려한 여러 서비스간의 호출 메커니즘 설계를 해야한다.
CQRS 패턴을 활용해서 Command와 Query의 책임을 분리해서 설계해야 한다.
CQRS 패턴이란 읽기와 쓰기에 대한 책임을 분리하는 것이다. 한 데이터베이스에 대한 트렌젝션은 반드시 단일 접근점으로 이루어져야 하며 이는 하나의 단일 서비스만이 한 데이터베이스에 트렌젝션을 보낼 수 있음을 의미한다.
단순히 읽기를 하는 서비스와 쓰기를 하는 서비스로 나누는 것이 아니라, 쓰기를 하는 서비스를 지정을 해서 단일 진입점의 명시적 선언을 해 책임을 분리하는 패턴이라고 생각하면 되겠다.
4. 동기 / 비동기 설계
서비스 독립성을 고려한 비동기 호출을 설계한다.
서비스 분리 기준
DDD ( Domain Driven Design )
사용자 관점에서 시스템을 만들어 보자.
메인 모델을 결정한 후, 서브 모델로 서비스를 나누어 나간다. 이때 서브 모델들이 공통되는 부분이 생기는데 이를 셰어드 커널이라고 하며 셰어드 커널을 최대한 포함하는 방향으로 서비스를 분리해 나간다.
업무 기능 관점
업무 기능을 바탕으로 서비스를 분해해 나간다. 조직에 속한 팀의 업무 별로 서비스를 나누어 가는 것이다.
Granularity
서비스의 크기는 코드 라인 수 등으로 정략적으로 책정될 수 있는 것이 아니다.
Business Context 에 맞게 독립적으로 개발/배포할 수 있는 단위로 결정해 나간다.
마이크로 서비스의 크기 ( 중요 )
업무 중심
기술이 아닌 업무 중심의 단위로 서비스의 크기를 결정하며, 업무/서비스간 영향도/결합도가 낮은 단위로 서비스를 결정한다.
확장성/장애대응/독립성/배포
- 서비스로 분리했을 때 큰 혜택을 볼 수 있는 단위로 나눈다.
- 장애 격리, 빠른 장애 대응으로 비지니스 피해를 최소화 할 수 있는 단위로 나눈다.
- 개별 실행 환경을 구축함으로써 독립적인 개발, 빌드, 테스트, 모니터링, 확장이 가능한 단위로 나눈다.
서비스 기능
서비스 별로 최소한의 API를 노출하고 통신이 원활한 단위로 서비스를 분리한다.
라이브러리를 공유하거나 유사한 기능들은 하나의 서비스로 통합시킨다.
변경 가능성/성능
상대적으로 작은 서비스일수록 새로 구현해 교체하기 쉽다.
서비스 간 프로세스 및 데이터 공유가 빈번한 경우 서비스를 통합하고, 서비스 분리로 인해 성능이 허용할 수 없는 수준으로 저하될 경우에도 통합한다.
트랜젝션과 일관성
서비스를 너무 세분화 하더라도 문제가 발생한다. 데이터간 분산 트랜젝션 처리나 일관성/정합성이 중요할 경우 서비스를 통합한다.
MSA 관련 핵심 기술 이슈
MSA 도입 목적 ( 개발자 관점, 서비스 관점 )
목적 없이 기술을 적용하는 케이스가 많았고, 기술의 도입이 목적인 경우 대부분 실패했다고 한다.
하지만 우리 팀의 경우 기술적인 호기심에 도입하고자 하였지만 기획을 진행하면서 알파 타입과 베타 타입으로 단계가 나누어졌고 추후 베타 타입에 추가될 기능인 다면 평가 서비스 도입을 위해서라도 MSA 구조를 선택했다.
우리 서비스에 맞지 않는다는 말은 경솔한 말이다. 그렇다면 어떤 서비스가 MSA에 적합한가? 이는 비지니스 환경과 고객 요구사항의 빠른 반영을 위한 것에 대한 질문이 아니라 서비스의 성격에 따른 MSA 도입을 고민하는 것이므로 옳지 않다.
마이크로 서비스 정의
서비스를 어떻게 분리하고 통합할 것인가에 대한 고민이 필요하다. 위에서 살펴본 내용을 잘 기억해서 판단해나가야 한다.
API First Design
서비스 간 이벤트 스토밍을 잘 구현해서 API를 최소화해서 최적화시켜야 한다고 한다. 다른 포스팅에서 더 자세히 알아보도록 하자
분산 트랜젝션
서비스 정의 단계에서 충분히 고려되어야 한다. 너무 무분별하게 서비스를 나누어도 트랜젝션 처리 과정에서 문제가 생길 수 있다.
위 4가지 사항 ( MSA 도입 목적, 마이크로 서비스 정의, API First Design, 분산 트렌젝션 ) 은 MSA 설계에 있어서 반드시 고려해보아야 할 토픽들로 잘 정리해서 가지고있자.
'원론 > MSA' 카테고리의 다른 글
분산 트렌젝션 (0) | 2025.01.26 |
---|---|
API First Design (0) | 2025.01.26 |
MSA 서비스 분리 (0) | 2025.01.26 |
MSA 개요 (0) | 2025.01.11 |