[Pattern] Microservices vs Monolith: 언제 분리, 언제 통합
Microservices, Monolith, Modular monolith, Service boundary, Conway's Law, Distributed monolith
정의
| Monolith | Modular Monolith | Microservices | |
|---|---|---|---|
| 배포 단위 | 1개 | 1개 (모듈 명확) | N개 |
| 데이터 | 단일 DB | 단일 DB (스키마 분리) | DB per service |
| 통신 | 함수 호출 | 함수 호출 | 네트워크 (HTTP/gRPC) |
| 운영 복잡도 | 낮음 | 낮음 | 높음 |
| 스케일링 | 전체 함께 | 전체 함께 | service 별 독립 |
| 장애 격리 | 약함 | 약함 | 강함 (이상적) |
| 적합 팀 | < 30 | < 100 | 100+ |
결정 트리
flowchart TD
Q1{팀 크기}
Q1 -->|< 10| Mono[Monolith]
Q1 -->|10-50| Q2{성장 속도?}
Q2 -->|느림| Mono
Q2 -->|빠름| MM[Modular Monolith]
Q1 -->|50-200| MM
Q1 -->|200+| MS[Microservices]
MM -->|"진짜 필요해지면"| MS
시작은 Monolith (Fowler 의 “Monolith First”)
flowchart LR
Start[새 프로젝트] --> Mono[Monolith로 시작]
Mono --> Grow[성장 + 도메인 명확]
Grow --> MM[Modular Monolith]
MM --> Carve[필요시 service 분리]
Carve --> MS[Microservices 일부]
IMPORTANT
대부분의 새 프로젝트는 monolith 로 시작 이 정답. 마이크로서비스로 시작 한 팀이 2년 후 distributed monolith 가 되는 사례가 압도적.
Microservices 가 진짜 도움될 때
flowchart TD
Q1{독립 배포 절실?}
Q1 -->|예| C1[조건 1 ✓]
Q2{팀 별 자율성 절실?}
Q2 -->|예| C2[조건 2 ✓]
Q3{스케일 차이 큼?}
Q3 -->|예| C3[조건 3 ✓]
C1 & C2 & C3 -->|모두 ✓| Go[Microservices 도입]
Distributed Monolith (안티 패턴)
flowchart LR
A[Service A] -->|동기 호출| B[Service B]
B -->|동기 호출| C[Service C]
C -->|동기 호출| D[Service D]
Note1[하나 다운 = 전체 다운]
증상:
- 여러 service 가 함께 배포 되어야 함 (calling contract 변경 시)
- 한 service 다운 = 전체 다운
- 분산의 비용 + monolith 의 결합 동시
- 코드 변경 영향이 service 경계 넘김
CAUTION
마이크로서비스의 최악의 결과. monolith 보다 모든 면에서 나쁨.
Service Boundary 가르는 기준
flowchart TD
Best[좋은 boundary]
Best --> B1["Domain (DDD bounded context)"]
Best --> B2["Team ownership (Conway's Law)"]
Best --> B3[데이터 모델 자연 분리]
Bad[나쁜 boundary]
Bad --> X1["기술 계층 (API / DB / UI)"]
Bad --> X2["유사 데이터 기준 (DB 테이블 1:1)"]
Bad --> X3["CRUD 단위 (UserService, OrderService 의 진짜 분리는 어디서?)"]
Conway’s Law
“시스템 구조는 그것을 만든 조직의 의사소통 구조를 닮는다”
flowchart TB
Team1["Team A<br/>(독립 의사소통)"] --> Service1[Service A]
Team2["Team B<br/>(독립 의사소통)"] --> Service2[Service B]
Team3["Team C<br/>(독립 의사소통)"] --> Service3[Service C]
Team1 -.협업.-> Team2
Service1 -.API.-> Service2
팀 경계와 service 경계의 일치 가 Conway’s Law 의 실용적 활용. 한 service 가 두 팀에 걸치면 운영 사고.
Inverse Conway Maneuver
반대로 service 구조부터 정해 → 팀 구조 맞추기. 큰 조직 재편 에서 사용.
분리 비용 카탈로그
flowchart TB
Cost[Microservices 의 추가 비용]
Cost --> Net[네트워크 호출]
Cost --> Obs["관측성 (Tracing 필수)"]
Cost --> Auth[mTLS / Service Mesh]
Cost --> Data["데이터 일관성 (Saga)"]
Cost --> Deploy[K8s, CI/CD 복잡도]
Cost --> Test[Contract / E2E 테스트]
Cost --> Skill[엔지니어 학습 비용]
모듈 모놀리스 (Modular Monolith)
flowchart TB
subgraph App[Single deployable]
U[User module]
O[Order module]
P[Payment module]
end
U -.interface only.-> O
O -.interface only.-> P
App --> DB[(단일 DB<br/>스키마 분리)]
- 모듈 간 직접 호출 금지. interface만.
- 같은 DB, 다른 스키마.
- 나중에 service 분리 쉬움.
- 대부분의 회사가 결국 여기서 멈춤 (충분).
흔한 함정
WARNING
- 너무 일찍 분리 = 도메인 잘못 잡고 분리 후 재경계. 가장 큰 후회.
- DB 공유 = “Service 단위 분리” 가 DB 결합 으로 무의미. 각 service 자기 DB.
- 분산 트랜잭션 (2PC) = 마이크로서비스의 영혼. Saga 패턴으로 대체.
- shared library 의 영원한 결합 = service A 가 라이브러리 v2 로 못 올라가면 모든 service 정체.
관련 위키
이 글의 용어 (6개)
- [Auth] mTLS (Mutual TLS): 양방향 인증서 인증auth-security
- 정의 mTLS (Mutual TLS) 는 서버뿐 아니라 클라이언트도 TLS 인증서로 자기 신분 증명. 일반 TLS = 서버 인증만, mTLS = 양방향. 활용: 서비스 메시 (I…
- [Distributed Systems] 분산 트랜잭션: 2PC, Saga, Outboxdistributed-systems
- 정의 분산 트랜잭션 은 여러 service / DB / 메시지 큐에 걸친 작업을 ACID 처럼 묶는 문제. 마이크로서비스 / 이벤트 기반 아키텍처의 핵심 도전. 3가지 접근: 1…
- [Pattern] API Gateway: BFF, 라우팅, auth, rate limitdistributed-systems
- 정의 API Gateway = 클라이언트와 마이크로서비스 사이의 단일 진입점. 라우팅, auth, rate limit, transformation, monitoring 의 cro…
- [Pattern] CQRS: Command / Query 분리, read modeldistributed-systems
- 정의 CQRS (Command Query Responsibility Segregation) = 쓰기 모델 과 읽기 모델 을 분리. 같은 데이터를 다른 형태 로 저장 / 조회. […
- [Pattern] Event Sourcing: 상태 대신 이벤트 누적distributed-systems
- 정의 Event Sourcing = 현재 상태 대신 과거 이벤트 시퀀스 를 저장. 현재 상태 = event 모두 replay 한 결과. 핵심 약속 - 과거 모든 변화 기록. 감사…
- [Pattern] Saga: 분산 트랜잭션의 보상 흐름distributed-systems
- 정의 Saga = 여러 service 의 로컬 트랜잭션 을 연결한 긴 흐름. 한 단계 실패 시 이전 단계의 보상 (compensating) 트랜잭션 으로 논리적 롤백. [!IMP…
💬 댓글