마이크로서비스 기초 (Microservices Fundamentals)
마이크로서비스 기초 (Microservices Fundamentals)¶
난이도: ⭐⭐⭐
개요¶
마이크로서비스 아키텍처는 애플리케이션을 작고 독립적인 서비스들의 집합으로 구성하는 설계 방식입니다. 이 장에서는 모놀리스와 마이크로서비스의 차이, 서비스 경계 정의, 데이터 관리 원칙, 그리고 서비스 간 통신 방식을 학습합니다.
목차¶
1. 모놀리스 vs 마이크로서비스¶
모놀리스 아키텍처¶
┌─────────────────────────────────────────────────────────────────────────┐
│ 모놀리스 아키텍처 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ Monolithic Application │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ User │ │ Order │ │ Product │ │ │
│ │ │ Module │ │ Module │ │ Module │ │ │
│ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │
│ │ │ │ │ │ │
│ │ └────────────────┼────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────────────┐ │ │
│ │ │ Shared Library │ │ │
│ │ │ (Common Utils) │ │ │
│ │ └──────────┬──────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌─────────────────────┐ │ │
│ │ │ Single Database │ │ │
│ │ └─────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
│ 특징: │
│ - 단일 코드베이스, 단일 배포 단위 │
│ - 모듈 간 직접 함수 호출 │
│ - 하나의 공유 데이터베이스 │
│ - 동일한 기술 스택 │
│ │
└─────────────────────────────────────────────────────────────────────────┘
마이크로서비스 아키텍처¶
┌─────────────────────────────────────────────────────────────────────────┐
│ 마이크로서비스 아키텍처 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ User Service │ │ Order Service │ │Product Service│ │
│ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │
│ │ │ API │ │ │ │ API │ │ │ │ API │ │ │
│ │ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │ │
│ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │
│ │ │ Logic │ │ │ │ Logic │ │ │ │ Logic │ │ │
│ │ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │ │
│ │ │ │ │ │ │ │ │ │ │
│ │ ▼ │ │ ▼ │ │ ▼ │ │
│ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │
│ │ │ DB │ │ │ │ DB │ │ │ │ DB │ │ │
│ │ │(Postgres│ │ │ │ (MySQL) │ │ │ │ (Mongo) │ │ │
│ │ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │ │
│ └───────┬───────┘ └───────┬───────┘ └───────┬───────┘ │
│ │ │ │ │
│ └──────────────────┼──────────────────┘ │
│ │ │
│ 네트워크 통신 │
│ (REST/gRPC/MQ) │
│ │
│ 특징: │
│ - 독립적인 배포 단위 │
│ - 서비스 간 네트워크 통신 │
│ - 서비스별 독립 데이터베이스 │
│ - 다양한 기술 스택 사용 가능 │
│ │
└─────────────────────────────────────────────────────────────────────────┘
장단점 비교¶
┌─────────────────────────────────────────────────────────────────────────┐
│ 모놀리스 vs 마이크로서비스 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────┬───────────────────┬───────────────────┐ │
│ │ 측면 │ 모놀리스 │ 마이크로서비스 │ │
│ ├────────────────┼───────────────────┼───────────────────┤ │
│ │ 개발 초기 │ 빠름 │ 느림 │ │
│ │ 배포 │ 전체 재배포 │ 독립 배포 │ │
│ │ 확장 │ 전체 확장 │ 선택적 확장 │ │
│ │ 장애 영향 │ 전체 시스템 │ 해당 서비스만 │ │
│ │ 기술 스택 │ 단일 │ 다양 │ │
│ │ 팀 구조 │ 단일 팀 │ 서비스별 팀 │ │
│ │ 트랜잭션 │ ACID 가능 │ 분산 트랜잭션 │ │
│ │ 테스트 │ 단순 │ 복잡 │ │
│ │ 디버깅 │ 쉬움 │ 어려움 │ │
│ │ 운영 복잡도 │ 낮음 │ 높음 │ │
│ │ 네트워크 │ 없음 │ 필요 (지연, 실패) │ │
│ └────────────────┴───────────────────┴───────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
모놀리스의 문제점¶
┌─────────────────────────────────────────────────────────────────────────┐
│ 모놀리스의 일반적인 문제 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. Big Ball of Mud (진흙 공) │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │ │
│ │ │ A │◄───►│ B │◄───►│ C │◄───►│ D │ │ │
│ │ └─┬─┘ └─┬─┘ └─┬─┘ └─┬─┘ │ │
│ │ │ ╲ │ ╱ │ ╲ │ │ │
│ │ │ ╲ │ ╱ │ ╲ │ │ │
│ │ ▼ ╲ ▼ ╱ ▼ ╲ ▼ │ │
│ │ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │ │
│ │ │ E │◄───►│ F │◄───►│ G │◄───►│ H │ │ │
│ │ └───┘ └───┘ └───┘ └───┘ │ │
│ │ │ │
│ │ → 모듈 간 경계가 사라지고 얽히게 됨 │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
│ 2. 배포 공포 │
│ - 작은 변경에도 전체 재배포 │
│ - "금요일 배포 금지" 문화 │
│ - 릴리스 주기 길어짐 (월 → 분기) │
│ │
│ 3. 확장의 비효율성 │
│ - 주문 서비스만 트래픽 증가 → 전체 시스템 확장 필요 │
│ - 리소스 낭비 │
│ │
│ 4. 기술 부채 축적 │
│ - 프레임워크/라이브러리 업그레이드 어려움 │
│ - 새로운 기술 도입 불가 │
│ │
└─────────────────────────────────────────────────────────────────────────┘
2. 마이크로서비스의 특성¶
핵심 특성¶
┌─────────────────────────────────────────────────────────────────────────┐
│ 마이크로서비스 핵심 특성 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. 단일 책임 (Single Responsibility) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 각 서비스는 하나의 비즈니스 기능에 집중 │ │
│ │ - User Service: 사용자 관리만 │ │
│ │ - Order Service: 주문 처리만 │ │
│ │ - Payment Service: 결제 처리만 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 2. 독립적 배포 │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ v1.0 v1.1 v1.2 ← User Service 업데이트 │ │
│ │ ──────────────────────────────────────────────── │ │
│ │ v2.3 ← Order Service (영향 없음) │ │
│ │ ────────────────── │ │
│ │ v1.5 ← Product Service (영향 없음) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 3. 기술 다양성 (Polyglot) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │User Service │ │Order Service│ │ ML Service │ │ │
│ │ │ (Java) │ │ (Node.js) │ │ (Python) │ │ │
│ │ │ PostgreSQL │ │ MySQL │ │ MongoDB │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │
│ │ 각 서비스에 최적화된 기술 선택 가능 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 4. 장애 격리 │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Payment Service ✗ (장애) │ │
│ │ │ │
│ │ User Service ✓ Order Service ✓ Product Service ✓ │ │
│ │ (계속 동작) (제한된 기능) (계속 동작) │ │
│ │ │ │
│ │ → Graceful Degradation 가능 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
서비스 크기¶
┌─────────────────────────────────────────────────────────────────────────┐
│ "얼마나 작아야 Micro인가?" │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 정량적 기준보다 정성적 기준: │
│ │
│ ✓ 한 팀이 소유하고 관리 가능 │
│ - Amazon의 "Two-Pizza Team" (6-8명) │
│ │
│ ✓ 몇 주 내에 재작성 가능 │
│ - 너무 크면 리팩토링/교체 어려움 │
│ │
│ ✓ 단일 비즈니스 기능에 집중 │
│ - "주문 서비스"가 사용자 관리까지 하면 안됨 │
│ │
│ ✓ 독립적으로 배포 가능 │
│ - 다른 서비스 변경 없이 배포 │
│ │
│ ───────────────────────────────────────────────────────────────── │
│ │
│ 너무 작으면: (Nano-service) │
│ - 과도한 네트워크 호출 │
│ - 운영 복잡도 폭증 │
│ - 분산 시스템 오버헤드 │
│ │
│ 너무 크면: (Distributed Monolith) │
│ - 마이크로서비스의 장점 상실 │
│ - 높은 결합도 │
│ - 독립 배포 불가 │
│ │
└─────────────────────────────────────────────────────────────────────────┘
3. 서비스 경계 정의¶
Domain-Driven Design (DDD)¶
┌─────────────────────────────────────────────────────────────────────────┐
│ DDD와 마이크로서비스 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 핵심 개념: Bounded Context │
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ E-Commerce Domain │ │
│ │ │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ Sales Context │ │Inventory Context│ │Shipping Context │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ - Order │ │ - Product │ │ - Shipment │ │ │
│ │ │ - Customer │ │ - Stock │ │ - Delivery │ │ │
│ │ │ - Shopping Cart│ │ - Warehouse │ │ - Carrier │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │ │
│ │ │ │ │ │ │
│ │ ▼ ▼ ▼ │ │
│ │ Order Service Inventory Service Shipping Service │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
│ Bounded Context = 마이크로서비스 경계의 좋은 후보 │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Ubiquitous Language¶
┌─────────────────────────────────────────────────────────────────────────┐
│ Context별 언어 차이 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ "Customer"의 의미가 Context마다 다름: │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Sales Context │ │Support Context │ │ Billing Context │ │
│ ├─────────────────┤ ├─────────────────┤ ├─────────────────┤ │
│ │ │ │ │ │ │ │
│ │ Customer: │ │ Customer: │ │ Customer: │ │
│ │ - 구매 이력 │ │ - 티켓 이력 │ │ - 결제 수단 │ │
│ │ - 선호도 │ │ - 만족도 │ │ - 청구 주소 │ │
│ │ - 장바구니 │ │ - 문의 내용 │ │ - 결제 이력 │ │
│ │ │ │ │ │ │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
│ │
│ 같은 용어, 다른 의미 → 각 Context에서 자체 모델 유지 │
│ │
│ ───────────────────────────────────────────────────────────────── │
│ │
│ Anti-pattern: 모든 Context에서 공유하는 "God Customer" 모델 │
│ │
│ class Customer { │
│ // Sales attributes │
│ purchaseHistory, preferences, cart... │
│ // Support attributes │
│ tickets, satisfaction, inquiries... │
│ // Billing attributes │
│ paymentMethods, billingAddress, invoices... │
│ // ... 끝없이 커지는 모델 │
│ } │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Context Mapping¶
┌─────────────────────────────────────────────────────────────────────────┐
│ Context 간 관계 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌──────────────┐ Upstream ┌──────────────┐ │ │
│ │ │ Order │ ─────────────► │ Inventory │ │ │
│ │ │ Context │ (의존) │ Context │ │ │
│ │ └──────────────┘ └──────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 관계 패턴: │
│ │
│ 1. Customer-Supplier (고객-공급자) │
│ - Upstream이 Downstream의 요구사항 반영 │
│ - 협력적 관계 │
│ │
│ 2. Conformist (순응자) │
│ - Downstream이 Upstream 모델을 그대로 사용 │
│ - Upstream이 변경 요청 거부 │
│ │
│ 3. Anti-Corruption Layer (ACL) │
│ ┌─────────────┐ ┌─────┐ ┌─────────────┐ │
│ │ Legacy │───►│ ACL │───►│ New │ │
│ │ System │ └─────┘ │ Service │ │
│ └─────────────┘ (변환 계층) └─────────────┘ │
│ │
│ 4. Open Host Service (개방형 호스트) │
│ - 잘 문서화된 공개 API 제공 │
│ - 다수의 Consumer 지원 │
│ │
└─────────────────────────────────────────────────────────────────────────┘
서비스 분해 전략¶
┌─────────────────────────────────────────────────────────────────────────┐
│ 서비스 분해 전략 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. 비즈니스 기능 기반 │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 조직 구조 반영 (Conway's Law 활용) │ │
│ │ │ │
│ │ 마케팅 팀 ──► Marketing Service │ │
│ │ 주문 팀 ──► Order Service │ │
│ │ 배송 팀 ──► Shipping Service │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 2. 하위 도메인 기반 │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Core Domain: 핵심 비즈니스 경쟁력 │ │
│ │ → 직접 개발, 최고 품질 │ │
│ │ │ │
│ │ Supporting Domain: 핵심 지원 │ │
│ │ → 내부 개발 또는 커스터마이징 │ │
│ │ │ │
│ │ Generic Domain: 일반적인 기능 │ │
│ │ → 외부 솔루션 또는 표준 구현 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 3. 변경 빈도 기반 │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 자주 변경 ◄──────────────────────────────► 거의 안 변경 │ │
│ │ │ │
│ │ Promotion Order Inventory User Auth │ │
│ │ Service Service Service Service │ │
│ │ │ │
│ │ → 변경 빈도가 다른 것끼리 분리 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
4. Database per Service¶
원칙¶
┌─────────────────────────────────────────────────────────────────────────┐
│ Database per Service 원칙 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 규칙: 각 서비스는 자신만의 데이터베이스를 가진다 │
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │User Service │ │Order Service│ │Product Svc │ │ │
│ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │
│ │ │ │ │ │ │
│ │ ▼ ▼ ▼ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ User DB │ │ Order DB │ │ Product DB │ │ │
│ │ │ (PostgreSQL)│ │ (MySQL) │ │ (MongoDB) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │
│ │ ✗ 직접 DB 접근 금지! │ │
│ │ │ │
│ │ Order Service ──✗──► User DB (금지) │ │
│ │ Order Service ──✓──► User Service API (허용) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 이유: │
│ - 느슨한 결합 유지 │
│ - 스키마 독립적 변경 가능 │
│ - 서비스별 최적화된 DB 선택 │
│ - 독립적 확장 가능 │
│ │
└─────────────────────────────────────────────────────────────────────────┘
데이터 공유 패턴¶
┌─────────────────────────────────────────────────────────────────────────┐
│ 서비스 간 데이터 공유 패턴 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. API 호출 (동기) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Order Service User Service │ │
│ │ │ │ │ │
│ │ │──GET /users/123 ────────────────►│ │ │
│ │ │◄──{ name: "Kim", ... } ──────────│ │ │
│ │ │ │ │ │
│ │ - 실시간 데이터 필요 시 │ │
│ │ - 의존성 발생 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 2. 이벤트 기반 (비동기) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ User Service Event Bus Order Service │ │
│ │ │ │ │ │ │
│ │ 사용자 생성 │ │ │ │
│ │ │──UserCreated────►│ │ │ │
│ │ │ │──UserCreated─────►│ │ │
│ │ │ │ │ 로컬 복사본 저장 │ │
│ │ │ │ │ │ │
│ │ - 데이터 복제 │ │
│ │ - 결과적 일관성 │ │
│ │ - 느슨한 결합 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 3. CQRS (Command Query Responsibility Segregation) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌─────────────┐ 이벤트 ┌────────────────────────┐ │ │
│ │ │Command Side │──────────────►│ Read Model │ │ │
│ │ │(각 서비스) │ │(조인된 뷰, 검색 최적화)│ │ │
│ │ └─────────────┘ └────────────────────────┘ │ │
│ │ │ │
│ │ - 읽기/쓰기 분리 │ │
│ │ - 복잡한 조회 최적화 │ │
│ │ - 이벤트 소싱과 결합 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
분산 트랜잭션 처리¶
┌─────────────────────────────────────────────────────────────────────────┐
│ 분산 데이터 일관성 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 문제: 주문 생성 시 재고 차감이 필요 │
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Order Service Inventory Service │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ 주문 생성 │ │ 재고 차감 │ │ │
│ │ │ (성공) │ │ (실패!) │ │ │
│ │ └──────────────┘ └──────────────┘ │ │
│ │ │ │
│ │ → 데이터 불일치! (주문은 있는데 재고 안 빠짐) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 해결책: │
│ │
│ 1. Saga 패턴 (보상 트랜잭션) │
│ - Choreography: 이벤트 체인 │
│ - Orchestration: 중앙 제어 │
│ (자세한 내용은 10_데이터_일관성_패턴.md 참조) │
│ │
│ 2. 최종 일관성 수용 │
│ - 비즈니스 요구사항에 따라 일시적 불일치 허용 │
│ - 백그라운드 재조정 프로세스 │
│ │
│ 3. Outbox 패턴 │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Order Service │ │
│ │ ┌──────────────────────────────────────────────────────────┐ │ │
│ │ │ BEGIN TRANSACTION │ │ │
│ │ │ INSERT INTO orders (...) │ │ │
│ │ │ INSERT INTO outbox (event: OrderCreated) │ │ │
│ │ │ COMMIT │ │ │
│ │ └──────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ Background Worker: outbox → Message Queue │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
5. 서비스 간 통신¶
동기 통신 (Synchronous)¶
┌─────────────────────────────────────────────────────────────────────────┐
│ 동기 통신: REST vs gRPC │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ REST (HTTP/JSON) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Order Service Product Service │ │
│ │ │ │ │ │
│ │ │──GET /products/123 ─────────────►│ │ │
│ │ │ Content-Type: application/json │ │ │
│ │ │ │ │ │
│ │ │◄─{ "id": 123, "name": "...", │ │ │
│ │ │ "price": 1000 } ──────────────│ │ │
│ │ │ │ │ │
│ │ 장점: 간단, 디버깅 쉬움, 범용적 │ │
│ │ 단점: 텍스트 기반 (오버헤드), 타입 안전성 부족 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ gRPC (HTTP/2 + Protocol Buffers) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Order Service Product Service │ │
│ │ │ │ │ │
│ │ │──GetProduct(id: 123) ───────────►│ │ │
│ │ │ (Binary, HTTP/2 multiplexing) │ │ │
│ │ │ │ │ │
│ │ │◄─Product { id, name, price } ────│ │ │
│ │ │ (Strongly typed) │ │ │
│ │ │ │ │ │
│ │ 장점: 빠름, 타입 안전, 양방향 스트리밍 │ │
│ │ 단점: 바이너리 (디버깅 어려움), 브라우저 직접 호출 제한 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────┬─────────────────────┬─────────────────────┐ │
│ │ 특성 │ REST │ gRPC │ │
│ ├──────────────┼─────────────────────┼─────────────────────┤ │
│ │ 프로토콜 │ HTTP/1.1 or 2 │ HTTP/2 │ │
│ │ 포맷 │ JSON (텍스트) │ Protobuf (바이너리) │ │
│ │ 성능 │ 보통 │ 빠름 (~7x) │ │
│ │ 타입 안전 │ 런타임 │ 컴파일타임 │ │
│ │ 스트리밍 │ 제한적 │ 양방향 지원 │ │
│ │ 브라우저 │ 직접 가능 │ gRPC-Web 필요 │ │
│ │ 사용 사례 │ 외부 API │ 내부 서비스 간 │ │
│ └──────────────┴─────────────────────┴─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
비동기 통신 (Asynchronous)¶
┌─────────────────────────────────────────────────────────────────────────┐
│ 비동기 이벤트 기반 통신 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Order │ │ Message │ │ Inventory │ │
│ │ Service │ │ Broker │ │ Service │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ 주문 생성 │ │ │
│ │ │ │ │
│ │──OrderCreated────►│ │ │
│ │ │──OrderCreated────►│ │
│ (즉시 반환) │ │ 재고 차감 │
│ │ │ │ │
│ │ │◄─StockReserved────│ │
│ │◄─StockReserved────│ │ │
│ │ │ │ │
│ │
│ 장점: │
│ - 서비스 간 느슨한 결합 │
│ - 서비스 장애 시에도 메시지 보존 │
│ - 부하 분산, 스케일링 용이 │
│ │
│ 단점: │
│ - 복잡도 증가 │
│ - 디버깅 어려움 │
│ - 최종 일관성 │
│ │
└─────────────────────────────────────────────────────────────────────────┘
통신 패턴 선택 가이드¶
┌─────────────────────────────────────────────────────────────────────────┐
│ 통신 패턴 선택 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 동기 통신을 사용할 때: │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ - 즉각적인 응답이 필요할 때 (조회, 유효성 검사) │ │
│ │ - 요청-응답 패턴이 자연스러울 때 │ │
│ │ - 단순한 서비스 간 호출 │ │
│ │ │ │
│ │ 예: 로그인 인증, 상품 정보 조회, 잔액 확인 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 비동기 통신을 사용할 때: │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ - 작업 완료까지 시간이 걸릴 때 │ │
│ │ - 장애 격리가 중요할 때 │ │
│ │ - 이벤트 브로드캐스트가 필요할 때 │ │
│ │ - 부하 평준화가 필요할 때 │ │
│ │ │ │
│ │ 예: 이메일 발송, 알림, 로그 수집, 분석 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 하이브리드: │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Client ──REST──► API Gateway ──Event──► Internal Services │ │
│ │ │ │
│ │ - 외부: REST (간단, 범용) │ │
│ │ - 내부: 이벤트/gRPC (성능, 느슨한 결합) │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
6. 마이크로서비스 도입 전략¶
Strangler Fig Pattern¶
┌─────────────────────────────────────────────────────────────────────────┐
│ Strangler Fig Pattern │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 단계 1: 모놀리스 앞에 프록시 │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ ┌─────────┐ │ │
│ │ Client ────►│ Proxy │────► Monolith (100%) │ │
│ │ └─────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 단계 2: 일부 기능을 마이크로서비스로 추출 │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ ┌─────────┐ ┌─────────────────┐ │ │
│ │ Client ────►│ Proxy │───►│ User Service │ (10%) │ │
│ │ │ │ └─────────────────┘ │ │
│ │ │ │ ┌─────────────────┐ │ │
│ │ │ │───►│ Monolith (90%) │ │ │
│ │ └─────────┘ └─────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 단계 3: 점진적 마이그레이션 │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ ┌─────────┐ ┌─────────────────┐ │ │
│ │ Client ────►│ Proxy │───►│ User Service │ │ │
│ │ │ │───►│ Order Service │ │ │
│ │ │ │───►│ Product Service │ (70%) │ │
│ │ │ │ └─────────────────┘ │ │
│ │ │ │───►│ Monolith (30%) │ │ │
│ │ └─────────┘ └─────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ 단계 4: 모놀리스 제거 완료 │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ ┌─────────┐ ┌─────────────────┐ │ │
│ │ Client ────►│ Proxy │───►│ User Service │ │ │
│ │ │ │───►│ Order Service │ │ │
│ │ │ │───►│ Product Service │ (100%) │ │
│ │ │ │───►│ Payment Service │ │ │
│ │ └─────────┘ └─────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
마이크로서비스 준비 체크리스트¶
┌─────────────────────────────────────────────────────────────────────────┐
│ 마이크로서비스 준비도 체크 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 조직/문화 측면: │
│ ☐ DevOps 문화가 자리잡았는가? │
│ ☐ 팀이 서비스를 소유하고 운영할 준비가 되었는가? │
│ ☐ 자동화된 CI/CD 파이프라인이 있는가? │
│ ☐ 온콜/장애 대응 프로세스가 있는가? │
│ │
│ 인프라 측면: │
│ ☐ 컨테이너/오케스트레이션 경험이 있는가? (Docker, K8s) │
│ ☐ 모니터링/로깅 인프라가 준비되었는가? │
│ ☐ 서비스 메시 또는 API Gateway를 운영할 수 있는가? │
│ ☐ 분산 추적 도구가 있는가? │
│ │
│ 개발 측면: │
│ ☐ 도메인이 명확히 정의되었는가? │
│ ☐ API 설계/버저닝 표준이 있는가? │
│ ☐ 테스트 자동화 수준이 충분한가? │
│ ☐ 분산 시스템 패턴에 대한 이해가 있는가? │
│ │
│ ⚠️ 위 항목들이 준비되지 않았다면, 마이크로서비스는 │
│ 오히려 복잡도와 비용만 증가시킬 수 있습니다. │
│ │
└─────────────────────────────────────────────────────────────────────────┘
7. 연습 문제¶
연습 1: 서비스 분해¶
온라인 서점 시스템을 마이크로서비스로 분해하세요: - 핵심 Bounded Context 식별 - 각 서비스의 책임 정의 - 서비스 간 관계 (Context Mapping) 설계 - 데이터베이스 분리 전략
연습 2: 통신 방식 선택¶
다음 시나리오에서 동기/비동기 통신 중 적절한 방식을 선택하세요: 1. 상품 상세 페이지 로딩 시 재고 확인 2. 주문 완료 후 이메일 발송 3. 결제 처리 후 재고 차감 4. 사용자 프로필 조회 5. 로그인 이벤트 로깅
연습 3: 마이그레이션 계획¶
기존 모놀리스 이커머스 시스템을 마이크로서비스로 전환하는 계획을 수립하세요: - Strangler Fig 패턴 적용 - 첫 번째로 분리할 서비스 선택과 이유 - 단계별 마이그레이션 로드맵
다음 단계¶
14_Microservices_Patterns.md에서 서비스 디스커버리, 서킷 브레이커, 서비스 메시 등 마이크로서비스 운영 패턴을 배워봅시다!
참고 자료¶
- "Building Microservices" - Sam Newman
- "Domain-Driven Design" - Eric Evans
- "Microservices Patterns" - Chris Richardson
- Martin Fowler's Microservices Guide
- Netflix Tech Blog
- Uber Engineering Blog