샘 뉴먼 님의 "마이크로서비스 아키텍처 구축" 책을 정리한 포스팅 입니다.
1. 마이크로서비스 살펴보기
마이크로서비스란?
- 도메인과 관련된 모든 요소를 하나의 모듈로 캡슐화한 아키텍쳐 스타일
적용 범위 | 설명 | 주의사항 |
도메인 |
비즈니스 도메인별로 기능을 나누어 서비스 경계 설정
|
|
네트워크 |
REST API, gRPC, 메시지 큐 등을 통한 통신만 허용
|
내부 로직·DB 직접 접근 ❌
|
데이터베이스 |
각 서비스가 자체 데이터베이스를 소유
|
공유 데이터베이스 사용 ❌
|
효과
효과 | 설명 | 특징 |
정보 은닉 |
가능한 많은 내부 정보를 구성요소에 감춤
외부 인터페이스를 통해 최소한만 노출 |
- 결합도 낮아짐
- 응집도 높아짐 |
변경 격리 |
내부 변경이 외부에 전파되지 않도록 하여 영향 범위를 최소화
|
|
경계 명확화 |
변경이 쉬운 부분과 어려운 부분을 명확히 구분
|
- 변경이 쉬운 부분: 내부 구현
- 변경이 어려운 부분: 외부 API |
독립 배포 |
개별 서비스 단위로 빌드·배포 가능
|
다른 서비스에 영향 ❌ |
2. 마이크로서비스의 핵심 개념
독립적 배포성
- 독립적으로 마이크로서비스를 변경하고, 배포하고, 릴리스할 수 있다는 개념
- 다른 서비스를 변경하지 않고도 한 서비스를 변경할 수 있음
- ➡️ 마이크로서비스를 느슨하게 결합해야 함
- ➡️ 서비스 간 분명하고, 안정적이고, 잘 정의된 계약이 필요함
예시) 강결합 - 데이터베이스 공유
더보기
- 서비스 A에서 테이블 스키마 바꾸면 서비스 B의 데이터베이스 접근 계층 코드 변경해야함
- ❌ 다른 서비스의 내부 구현에 의존하게 됨
비즈니스 도메인 중심의 모델링
도메인 주도 설계
- 소프트웨어가 동작하는 실제 도메인을 더 잘 표현하도록 코드를 구성할 수 있음
- ➡️ 마이크로서비스에서 동일한 개념을 사용해 서비스 경계를 정의함
구현 방향
원칙 | 이유 |
외부 인터페이스 변경 최소화 |
- 변경 시 팀 간 조율 필요
- 배포 순서·호환성 고려 필요 |
계층 간 응집도 높이기 |
- 변화가 빈번하므로 응집도를 높여야 함
- 요구사항 변경 시 최대한 한 곳의 수정으로 처리 가능하게 함 |
자기 상태 소유
- 각 서비스는 각각의 자기 상태를 소유함
- 다른 서비스의 상태는 외부 계약을 통해 접근하도록 함
- ➡️ 서비스 독립성을 유지하기 위함
인터페이스 설계
- 인터페이스는 하위 호환성을 지켜야 함
- 내부 구현 상세와 외부 계약이 명확히하면, 변경에 대해 하위 호환성을 지키는데 도움됨
- ➡️ 어떤것을 공개할지 감출지를 명확히 분리하게 하는 효과
유연성
특징 | 설명 | 예 / 특징 |
서비스별 독립 배포 | 다른 서비스에 영향 없이 하나의 서비스만 빌드·배포 가능. | - 새로운 기능 실험 - 빠른 롤백 - 점진적 배포(Blue-Green, Canary) |
기술 스택 독립 | 서비스별로 기술 자유롭게 선택 가능 | - 프로그래밍 언어 - 프레임워크 - 데이터베이스 |
스케일링 단위 분리 | 필요한 서비스만 개별적으로 확장 가능 | |
변경 격리 | 서비스 간 결합도가 낮아 내부 구현 변경이 다른 서비스에 전파되지 않음. | API/이벤트 계약만 유지하면 내부 구조 자유롭게 리팩터링 가능 |
장애 격리 | 한 서비스 장애가 전체 시스템 다운으로 이어지지 않음. | - Circuit Breaker - Fallback |
아키텍처와 조직의 정렬
구분 | 기술 조직별 아키텍처 (옛날) |
도메인별 아키텍처 (현대)
|
구성 방식 | 기술 스택 중심 팀 구성 (백엔드·프론트·DB 등) |
비즈니스 도메인 중심 팀 구성 (결제·주문·배송 등)
|
기술 응집도 | 높음 (같은 기술 전문가들이 한 팀) |
낮음 (기술 인력이 각 도메인 팀에 분산)
|
비즈니스 기능 응집도 | 낮음 (여러 팀이 기능 구현에 관여) |
높음 (기능 구현이 한 팀 내부에서 완료)
|
변경 속도 | 느림 (여러 팀 협업·조율 필요) |
빠름 (팀 내부에서 독립적으로 변경 가능)
|
팀 간 소통량 | 많음 | 적음 |
장점 | 기술 전문성·표준화 용이 |
기능 변경·배포 속도 빠름, 변경 범위 제한
|
단점 | 기능 개발·변경에 시간 오래 걸림 |
기술 표준·품질 관리 어려움
|
현대 소프트웨어
- 빠르게 출시하고 많은 요구사항 및 변경사항을 수용할 줄 알아야 함
- 빠르게 배포하고 소통 비용을 줄이는 것이 핵심
- ➡️ 비즈니스 중심 팀으로 구성하고, 각 팀에 기술별 전문가들이 팀을 이뤄 개발함
3. 모놀리스
종류
유형 | 설명 | 특징 |
단일 프로세스형 모놀리스 | 모든 코드가 단일 프로세스로 배포되는 시스템 |
- 구조 단순, 배포 간단
- 😭 규모 커질수록 변경·배포 부담 증가 |
모듈식 모놀리스 | 단일 프로세스이지만 별도의 모듈로 구성된 형태 |
- 모듈별로 작업 가능
- 😭 배포는 전체 합쳐서 해야 함 - 😭 데이터베이스 결합 존재 |
분산형 모놀리스 | 여러 서비스로 구성되지만 전체 시스템을 함께 배포해야 하는 형태 |
- 😭 서비스 간 강한 결합
- 😭 독립 배포 불가 → 운영 복잡도는 높고 유연성은 낮음 |
장점
장점 | 설명 | 분산 환경 단점 |
단순함 | 아키텍처와 배포 구조가 단일 프로세스 |
설계·운영 복잡
|
분산 시스템 함정 회피 |
복잡성을 피할 수 있음
|
- 네트워크 통신 - 데이터 일관성 - 분산 트랜잭션 - 서비스 간 장애 전파 |
코드 재사용 용이 |
같은 코드베이스 내에서 모듈·함수 호출로 쉽게 재사용 가능
|
- 코드 복사 - 라이브러리 분리 - 공유 기능을 별도 서비스로 노출해야 함 |
단점
- 전달 경합
- 같은 코드를 여러 사람이 수정
- 각 팀들이 원하는 시간에 배포하기 원함
4. 활성화 기술
- 마이크로서비스 아키텍처는 점차 분산되는 시스템으로 인해 발생하는 문제를 지속적으로 찾고 도움이 될 만한 기술을 도입해야 함
로깅
개념 | 설명 | 효과 |
로그 집계 | 여러 서비스에서 생성된 로그를 수집·집계 |
- 한 곳에서 분석 가능하게 함
- 로그 검색 및 분석 용이 (서비스·시간·레벨별) |
분산 추적 | 요청의 흐름과 각 단계의 소요 시간을 시각적으로 보여줌 |
병목 구간·오류 지점을 빠르게 파악
|
상관관계 ID | 요청 단위로 로그와 추적 데이터를 연결하는 고유 식별자 |
동일 요청의 전체 호출 흐름을 쉽게 재구성 가능
|
컨테이너와 쿠버네티스
구분 | 설명 | 특징 |
컨테이너 | 각 마이크로서비스 인스턴스를 격리해 실행하는 환경 |
- 서비스 인스턴스를 위한 독립적 실행 환경 제공
- VM 대비 훨씬 가벼움 - 빠른 배포 및 확장 가능 |
컨테이너 오케스트레이션 | 다수의 컨테이너를 효율적으로 관리하는 도구 및 방식 |
- 하위 머신(노드) 자원 효율적 사용
- 자동 스케일링, 부하 분산, 장애 복구 제공 - 예: Kubernetes, Docker Swarm |
스트리밍
- 실시간 피드백을 구현하는 요구사항에 따라 도입됨
공용 클라우드 및 서버리스
- 다양한 관리형 서비스와 배포 옵션을 제공함
- 서버 리스: 서버를 직접 관리하지 않고, 이벤트나 요청이 있을 떄만 코드를 실행해주는 클라우드 서비스 모델
5. 마이크로서비스의 장점
구분 | 설명 | 특징 |
기술 이질성 | 각 서비스에 서로 다른 기술을 사용하기로 결정할 수 있음 |
- 기능별 기술을 더 쉽게 적용할 수 있음
- 다른 마이크로서비스에 영향을 미치지 않음 |
견고성 | 특정 서비스의 고장에 대한 문제는 격리됨 |
- 서비스 경계가 벌크헤드 역할을 함
- 나머지 시스템은 계속 동작함 |
확장성 |
확장이 필요한 서비스만 확장할 수 있음
|
|
배포 용이성 |
시스템의 다른 부분과는 독립적으로 배포할 수 있음
|
|
조직적 정렬 | 팀이 담당하는 서비스와 실제 코드 구조가 잘 매칭됨 | - 아키텍쳐와 조직 구조 간 정렬을 유지할 수 있음 - 조직 변경에 따라 서비스의 소유권도 쉽게 바꿀 수 있음 - 하나의 코드베이스에서 일하는 인원을 최소화할 수 있음 |
조합성 | 기능을 독립적으로 설계하여 다양한 채널에 재사용 가능하게 함 |
- 멀티 채널 시대에 이를 뒷받침할 유연한 아키텍쳐가 필수
- 채널별 애플리케이션을 쉽게 구축할 수 있음 |
6. 마이크로서비스의 고충
구분 | 설명 | 해결 방법 |
개발자 경험 | JVM 런타임은 하나의 호스트 머신에서 실행 가능한 마이크로서비스 수를 제한함 | 한 머신에서 전체 시스템을 실행할 수 없을 떄는 어떻게 해야할지 논의해야 함 |
기술 과다 | 마이크로서비스를 도입하는데 따르는 여러 문제를 이해하는데 많은 시간을 할애해야 함 | 엄청난 양의 새로운 기술을 수용하는 동시에 그 개념이 소프트웨어 개발에 대한 생각을 어떻게 바꾸는 지 이해해야 함 |
비용 | 더 많은 프로세스, 컴퓨터, 네트워크, 스토리지, 지원 소프트웨어를 실행해야 한단 점을 고려해야 함 |
|
리포팅 | 전체 데이터를 다루는 리포팅은 실행이 어려움 - 데이터가 논리적으로 분리된 여러 스키마에 분산되어 있음 |
메시지 큐로 전체 데이터를 대상으로 한 복제 데이터베이스운영 |
모니터링 | 여러 서비스를 통합해서 모니터링하는 시스템을 구축해야 함 | - 프로토콜: HTTP2(멀티플렉싱) |
보안 | 네트워크 간 통신이 많으므로 외부에 노출될 가능성이 높아짐 | - 마이크로서비스 엔드포인트 보호 (권한) |
테스팅 | 엔드투엔드 테스트 범위가 상당히 늘어남 - 테스트 시나리오에 맞게 배포해야 함 - 여러 프로세스에서 테스트를 실행해야 함 - 환경적 이슈로 인해 테스트가 실패하는 거짓 음성도 대비 필요 |
- 계약 주도 테스팅 - 운영 환경 내 테스팅 - 병렬 실행 - 카나리아 릴리스 |
지연 시간 | 네트워크 통신으로 인한 지연시간 발생 | - 아키텍처: 비동기화, 데이터 현지화 - 프로토콜: HTTP2(멀티플렉싱) - 직렬화/역직렬화: 파이너리 포맷 |
데이터 일관성 | 다양한 데이터베이스 상태 관리를 위해 분산 트랜잭션을 사용함 - 복잡성이 높아지고 안정성이 낮아짐 |
- 궁극적 일관성 - 사가 패턴 |
7. 마이크로서비스를 사용해야 하는가?
마이크로서비스가 적합하지 않은 곳
상황 | 특징 | 권장 접근 |
새로운 서비스 또는 스타트업 | - 서비스 경계가 자주 변경됨 - 도메인 모델이 아직 불안정함 |
도메인 모델이 충분히 안정화될 때까지 대기
|
고객이 배포하고 관리할 소프트웨어 | - 운영 및 배포 복잡성이 큼 - 고객이 직접 실행해야 함 |
복잡성을 줄이기 위해 추가적인 기술 적용 필요
|
마이크로서비스가 적합한 곳: SaaS
SaaS 특성 | 마이크로서비스와의 적합성 | 설명 |
24시간 연중무휴 운영 | 독립적 릴리즈 가능 |
서비스가 작은 단위로 나뉘어 있어 일부만 수정·배포 가능
→ 전체 중단 없이 항상 가동 |
확장성 필요 | 선택적 확장 가능 |
부하가 큰 기능만 개별적으로 확장 가능
→ 효율적 자원 사용 |
클라우드 플랫폼 기반 | 기술 중립성·관리형 서비스 활용 |
각 서비스마다 다른 기술 스택 사용 가능
클라우드의 인증·저장소·메시징 등 관리형 서비스와 쉽게 연동 |