MSA 의 개념과 등장 배경
1. MSA 의 핵심 개념
- 애플리케이션 구축시, 독립적으로 배포 가능한 작은 서비스들의 모음으로 구조화하는 아키텍처 패턴
- 두 가지 핵심은 각 서비스가 독립적으로 배포, 개발될 수 있다는 것과
- 서비스간에 의존성이 낮다 = 결합도가 느슨하다라는 점이다.
- MSA 에 대한 정확한 정의를 내리긴 어려우며, 위 두 가지가 가장 큰 핵심이라고 보인다.
- 각 서비스마다 별도의 데이터베이스를 가질 것이 권장된다. (데이터 독립성)
- 외부 클라이언트와 통신할 때엔 중간에 API 게이트웨이를 두는 게 권장된다.
- 서비스간 통신은 보통 API 를 통한 통신을 한다.
2. 모놀리식 아키텍처의 한계 및 MSA 등장 배경
모놀리식 아키텍처
- 모든 구성요소가 하나의 프로젝트에 통합되어 있는 형태
- 소규모 프로젝트에서는 간단하고 유지보수가 용이
- 하지만 일정 규모 이상으로 커지면 여러 한계에 봉착
- 이를 해결하기 위해 MSA가 등장
모놀리식 아키텍처의 한계
모놀리식 아키텍처의 단점 | 설명 |
---|---|
장애 격리 불가 | 한 서비스의 부분 장애가 전체 시스템 장애로 확산될 수 있음 |
구조의 복잡성 | 코드베이스가 방대해지면 전체 구조 파악이 어려움 |
빌드, 테스트, 배포 시간 급증 | 작은 변경에도 전체 애플리케이션을 재빌드 및 재배포해야 함 |
확장성 문제 | 특정 기능만 개별적으로 확장하기 어려워 리소스 낭비 초래 |
기술 스택 제한 | 시스템 전체 또는 일부의 기술 스택을 유연하게 변경하기 어려움 |
팀 운영의 어려움 | 팀 규모가 커질수록 역할 분담, 협업, 의사결정이 복잡해짐 |
MSA 의 장점과 단점
1. MSA의 장점
MSA의 장점 | 설명 |
---|---|
확장성 | 특정 서비스만 개별적으로 확장 가능 (예: mail 서비스 스케일아웃) → 자원 효율 및 비용 절감 |
독립적인 개발 및 배포 | 서비스 단위로 개발/배포 가능 → 개발 속도 증가, 빠른 시장 대응, 기존 시스템 영향 최소화 |
장애 격리 | 한 서비스의 장애가 전체 시스템에 영향을 주지 않음 → 장애 격리, 전체적인 시스템 가용성 확보 |
다양한 기술 스택 적용 가능 | 서비스별로 언어, 프레임워크 등 기술 선택 가능 → 개발 속도 가속, 새로운 기술 도입 유연 |
구조 파악 용이 | 서비스가 도메인 중심으로 구성 → 각 서비스의 구조와 역할 파악이 쉬움 (모놀리식보다) |
2. MSA의 단점 및 해결 방안
MSA는 만병통치약이 아니다.
단점 | 설명 |
---|---|
운영/관리 복잡성 | 문제점 - 서비스 수 증가 > 네트워크, 로깅, 모니터링, 배포 복잡도 증가 해결 방안 - 오케스트레이션 : 서비스 배포, 확장, 쟁애 복구 자동화(Kubernetes 등) - Service Mesh 도입 : 서비스 간 통신을 제어, 관리하는 레이어 (lstio 등) - DevOps 문화 정착 : 개발과 운영을 동시에 할 수 있 |
서비스 간 통신 비용 증가 (IPC) |
문제점 - 서비스 간 호출이 네트워크를 통해 이루어짐 (REST API 등) - 따라서 레이턴시가 증가, 장애 전파 가능성이 높아짐(통신 오버헤드) 해결 방안 - 비동기 통신 : 메시지 브로커 등 도입으로 서비스간 직접적인 통신을 줄임 - gRPC 최적화: gRPC 프로토콜을 사용해 통신 효율성 증대 - 서비스 디스커버리: 서비스의 엔드포인트(IP, Port)를 자동 파악 |
데이터 일관성 문제 (분산 트랜잭션) |
문제점 - MSA는 서비스별로 데이터 저장소를 분리함 - 이에 따라 데이터 동기화 및 정합성을 맞추는 것이 어려워짐 해결 방안 - 분산된 트랜잭션을 통합하여 관리하는 패턴 도입 (SAGA 패턴, 2PC 등) - SAGA 패턴 : 각 서비스의 로컬 트랜잭션 하나의 논리적 트랜잭션으로 다룸 - 2PC : 2단계 커밋. 하나의 큰 트랜잭션을 분산하여 처리하는 프로토콜 |
데이터 조회의 어려움 | 문제점 - 데이터가 여러 서비스에 분산되어 있어 여러 데이터를 조인하기 어려움 해결 방안 - 인메모리 조인 : 일단 데이터를 여기저기서 가져온 뒤 인메모리 조인. - CQRS 패턴 : Command(데이터 변경)-Query(조회) 데이터모델 분리 - CQRS 에서 C - Q 간 동기화에 메시지 큐, CDC 등 사용될 수 있음 |
설계의 어려움 (서비스 경계 설정) |
문제점 - MSA의 핵심은 서비스 분할 - 경계를 잘못 설정하면 서비스 간 결합도가 높아져 MSA의 장점 발휘 불가. - 도메인 이해가 충분하지 않을 경우 비효율적 서비스 분할로 이어질 수 있음. |
테스트 복잡성 증가 보안 문제 |
문제점 - 서비스 간 통신에 네트워크가 개입되어 통합 테스트가 복잡해지고 - 서비스 간 통신이 네트워크를 통하므로 암호화에 더 신경 써야 함 해결 방안 - Mock 서버, Spring Cloud Contract 등 - 서비스 메쉬의 mTLS 기능을 활용하여 코드 변경 없이 암호화를 적용 |
초기 비용 증가 | 문제점 - 오케스트레이션, 서비스 메쉬, API 게이트웨이 등 구축 필요 - 다양한 인프라가 필요하여 초기 비용과 학습 곡선이 높아질 수 있음 |
MSA 도입 및 전환 전략
1. 도입 전 체크
“모놀리식으로 관리하기에 특별히 복잡한 시스템을 운영할 상황이 아니면 마이크로서비스는 고려할 필요조차 없다” - 마틴 파울러
-
나눌 수 있을 만큼 충분히 복잡한 시스템인가? : 단순한 CRUD 애플리케이션이나 트래픽이 많지 않은 소규모 서비스에는 모놀리식이 훨씬 효율적일 수 있음. MSA 도입은 오히려 불필요한 오버헤드와 복잡성을 증가시킴.
-
실시간 일관성이 중요한 서비스 : 금융 거래, 재고 관리 등 강력한 트랜잭션 일관성이 필요한 경우, 분산 트랜잭션 문제를 해결하기 어려워 MSA가 부적합할 수 있음.
-
고도로 최적화된 성능이 중요한 시스템 : 서비스 간 네트워크 호출이 빈번하여 성능 저하가 발생할 수 있음. 일부 서비스는 모놀리식 구조로 유지하는 것이 더 나을 수도 있음.
-
성능 병목 지점이 명확한 경우 : 특정 모듈의 성능 최적화만으로 시스템 성능을 향상시킬 수 있다면 MSA보다 해당 모듈에 집중하는 것이 효과적일 수 있음.
-
데이터 모델이 강하게 결합된 경우 : 여러 마이크로서비스가 하나의 데이터베이스를 공유하거나 데이터 모델이 강하게 결합되어 있다면 MSA의 장점을 활용하기 어려움. 데이터베이스 분리 및 재설계가 필요.
-
개발팀의 역량 부족 : MSA는 분산 시스템에 대한 이해, 서비스 간 통신, 데이터 일관성, 자동화된 배포 파이프라인 구축 등 높은 수준의 개발 및 운영 역량이 요구됨. 역량이 부족하면 생산성 저하와 시스템 불안정으로 이어질 수 있음.
2. MSA 전환 전략
-
점진적 전환: 기존 모놀리식에서 MSA로 한 번에 마이그레이션하는 것은 비현실적. 점진적 분리 전략을 사용하여 새로운 기능을 개발하거나 기존 기능을 수정하면서 서비스들을 분리해나가는 것이 좋음. MSA를 한다, 안한다가 아니라 원래는 모놀리식이었던 시스템을 점차 서비스 중심, API 중심으로 나타내는 것이 권장됨.
-
DDD(도메인 주도 설계) 및 모듈 분리: 초기 모놀리식 개발 단계부터 향후 MSA 전환을 고려하여 도메인 주도 설계를 적용하고 모듈을 잘 분리해두면 추후 서비스 추출이 용이함. 특히 애그리거트 루트 간 참조는 PK를 통해 간접 참조하도록 설계하는 것이 중요.
용어집 (Glossary)
용어 (한글/영문) | 설명 |
---|---|
MSA (마이크로서비스 아키텍처) Microservices Architecture |
애플리케이션을 작고 독립적으로 배포 가능한 서비스들의 모임으로 구조화하는 개발 기법 |
모놀리식 아키텍처 Monolithic Architecture |
애플리케이션의 모든 구성요소가 하나의 프로젝트에 통합된 방식 |
SOA (서비스 지향 아키텍처) Service Oriented Architecture |
구성 요소들이 통신 프로토콜을 통해 서로 서비스 제공하는 방식. MSA는 그 일종 |
CRUD Create, Read, Update, Delete |
데이터베이스의 기본적인 네 가지 작업 |
확장성 Scalability |
시스템이 증가하는 작업량을 처리할 수 있는 능력 |
장애 격리 Fault Isolation |
한 서비스의 장애가 전체 시스템으로 확산되지 않도록 방지 |
회복력 Resilience |
장애 발생 후에도 정상 작동하거나 빠르게 복구되는 능력 |
기술 스택 Tech Stack |
개발과 운영에 사용되는 기술의 조합 |
IPC (프로세스 간 통신) Inter-Process Communication |
서비스 간의 데이터 교환 방식 |
레이턴시 Latency |
요청부터 응답까지 걸리는 시간 지연 |
메시지 큐 Message Queue |
비동기 통신을 위한 메시지 저장/전달 시스템 |
gRPC | HTTP/2 기반 고성능 RPC 프레임워크 |
분산 트랜잭션 Distributed Transaction |
여러 시스템에 걸친 하나의 논리적 트랜잭션 |
SAGA 패턴 SAGA Pattern |
로컬 트랜잭션을 순차 실행하고 실패 시 보상 트랜잭션으로 일관성 유지 |
2PC (2단계 커밋) Two-Phase Commit |
준비 → 커밋 두 단계로 분산 트랜잭션을 처리하는 방식 |
트랜잭셔널 메시징 Transactional Messaging |
데이터 변경과 메시지 발행을 하나의 트랜잭션으로 처리 |
트랜잭셔널 아웃박스 패턴 Transactional Outbox Pattern |
DB에 이벤트를 함께 저장하고 별도 프로세스가 발행 |
CDC (변경 데이터 캡처) Change Data Capture |
DB 변경 사항을 실시간으로 포착해 전달 |
이벤트 소싱 Event Sourcing |
상태 변경을 이벤트의 연속으로 저장 |
API 조합 패턴 API Composition Pattern |
여러 서비스 데이터를 모아 하나의 응답으로 반환 |
CQRS Command Query Responsibility Segregation |
쓰기와 읽기의 책임을 분리하는 설계 패턴 |
구체화된 뷰 Materialized View |
미리 계산되어 저장된 조회용 데이터 뷰 |
소비자 주도 계약 테스트 Consumer-Driven Contract Testing |
API 소비자와 제공자 간 계약을 자동으로 검증 |
API 게이트웨이 API Gateway |
모든 요청을 받아 적절한 서비스로 라우팅하는 진입점 |
쿠버네티스 Kubernetes |
컨테이너 기반 앱의 배포, 확장, 운영을 자동화하는 플랫폼 |
서비스 메시 Service Mesh |
마이크로서비스 간 통신을 제어/관리하는 인프라 계층 |
ELK 스택 ELK Stack |
로그 수집, 분석, 시각화 도구 조합 (Elasticsearch, Logstash, Kibana) |
프로메테우스 & 그라파나 Prometheus & Grafana |
모니터링 및 시각화를 위한 도구 조합 |
데브옵스 DevOps |
개발과 운영의 협업 및 자동화를 강조하는 문화 |
스트랭글러 패턴 Strangler Pattern |
모놀리스를 점진적으로 마이크로서비스로 전환하는 전략 |
도메인 주도 설계 Domain-Driven Design (DDD) |
비즈니스 도메인을 중심으로 시스템을 설계하는 방법론 |
애그리거트 루트 Aggregate Root |
도메인 일관성 단위로, 서비스 경계 설정에 활용됨 |
Reference
MSAP ai ebooks 이제 나도 MSA 전문가: 개념부터 실무까지
Metanet - MSA란? ① 특징과 구성요소
Metanet - MSA란? ② 장점과 단점
2PC(Two-Phase-Commit)과 SAGA 패턴
IMKUNYOUNG - MSA 실패의 주요 원인
Sungho’s blog - MSA가 좋지만은 않은 이유
Comments