아키텍처 패턴이 실패하는 방식
21 views
설계 결정이란 어떤 고통을 언제 치르겠는가를 결정하는 것이다. 지금 선불로 낼 것인지, 나중으로 미룰 것인지.
1968년 Melvin Conway가 "조직의 통신 구조가 시스템 구조를 결정한다"고 관찰했다. Ward Cunningham이 기술 부채를 명명한 것은 1992년이었다. 1999년 Martin Fowler는 빈혈 도메인 모델을 경고했고, Alistair Cockburn이 헥사고날을 제안한 것은 2005년의 일이다. 이름은 나중에 붙는다. 고통은 이름이 붙기 전부터 거기 있었다. 패턴은 그 고통을 체계화한 것에 불과하다.
이 글은 다섯 패턴이 어떤 고통에서 태어났는지, 그리고 그 고통의 맥락을 무시할 때 어떻게 실패하는지를 추적한다.
## 1. 모놀리식: 초기 단순함과 성숙의 대가
모놀리식은 하나의 배포 단위다. 모든 기능이 단일 프로세스에 포함되고, 함수 호출은 메모리 내에서 일어나며, 트랜잭션은 데이터베이스 하나로 보장된다.
초기에 단순함은 미덕이다. 팀이 작고 도메인이 자기 경계를 아직 모르는 단계에서 모듈을 쪼개면 잘못된 경계를 코드에 굳힌다. Eric Evans가 『도메인 주도 설계』(2003)에서 정의한 Bounded Context — 하나의 언어와 모델이 일관되게 적용되는 경계 — 가 뚜렷해지기 전에 분리는 분열일 뿐이다.
약점은 시간이 데려온다. 응집도를 지키는 규율이 무너지면 모듈 간 결합도는 조용히 쌓인다. Ward Cunningham이 명명한 기술 부채가 이자를 낸다. 어느 날 사소한 수정 하나가 전체 재배포를 요구하고, 부분만 확장할 방법이 없어진다.
작을 때는 최선이다. 규율 없이 크면 최악이 된다.
## 2. 레이어드: 질서의 구조적 비용
레이어드 아키텍처는 의존성 방향을 단방향으로 고정한다. 표현 층은 비즈니스 로직 층에 의존하고, 비즈니스 로직 층은 영속성 층에 의존한다. 이 단 하나의 규칙이 예측 가능성을 만든다.
새로운 개발자가 합류해도 어디에 무엇이 있어야 하는지를 구조가 먼저 알려준다. 계층 단위로 독립적 테스트가 가능하다. 안정된 요구사항과 교체 가능한 인력을 가진 중간 규모 팀에서 레이어드는 여전히 가장 정직한 선택이다.
대가는 수직 관통이다. 데이터베이스 컬럼 하나를 추가하면 변경이 세 층을 통과한다. Fowler가 경고한 빈혈 도메인 모델 — 비즈니스 로직이 서비스 층에 집중되면서 도메인 객체가 데이터 컨테이너로 전락하는 상태 — 이 발생하기 쉬운 구조다.
패턴을 강제하는 것이 때로는 그 패턴의 본질을 희석한다.
## 3. 마이크로서비스: 전제 조건이 비용이다
마이크로서비스는 비즈니스 능력 단위로 서비스를 분리한다. 각 팀이 자기 서비스를 독립적으로 배포하고 확장하며, 다른 언어와 스택을 선택할 수 있다.
Conway의 법칙을 역으로 활용하겠다는 것이 핵심 전제다. 서비스 경계를 팀 경계와 일치시켜 팀 간 의존성을 API 계약으로 명시화한다. 조직 구조가 아키텍처가 된다. 조직이 준비되지 않으면 아키텍처도 준비되지 않는다.
비용은 분산 시스템 고유의 복잡도다. 네트워크는 신뢰할 수 없고, 분산 트랜잭션은 로컬 트랜잭션보다 훨씬 복잡하며, 서비스 간 의존 그래프가 불투명해질수록 디버깅은 어려워진다. 서비스 경계를 잘못 그으면 동기 호출로 묶인 분산 모놀리식이 탄생한다. 모놀리식의 결합도와 마이크로서비스의 운영 복잡도를 동시에 갖는 키메라다.
큰 조직, 높은 배포 빈도, 명확한 도메인 경계. 세 조건이 모두 맞을 때만 보상이 따른다.
## 4. 이벤트 드리븐: 결합도를 잃는 대신 흐름을 잃는다
이벤트 드리븐에서 컴포넌트는 서로를 부르지 않는다. 이벤트를 발행하고, 누가 구독하는지 관여하지 않는다. 생산자와 소비자는 시간적으로도 분리된다.
결합도가 거의 0에 수렴한다. 새로운 소비자를 추가해도 기존 코드를 건드리지 않는다. 처리량을 독립적으로 확장할 수 있다. 이질적인 시스템을 메시지로 통합할 때 최선이다.
인과가 사라진다. "주문 → 결제 → 배송"이라는 흐름이 세 서비스의 이벤트 핸들러에 분산된다. 시스템의 전체 행동을 단일 지점에서 파악할 수 없다. 멱등성, 이벤트 순서, 중복 처리를 애플리케이션 레벨에서 명시적으로 설계해야 한다.
디버깅은 로그를 시간순으로 재조합하는 고고학이 된다.
## 5. 헥사고날: 배포 위상이 아닌 설계 태도
헥사고날, 곧 포트앤어댑터는 앞의 네 패턴과 다른 층위에 있다. 배포 방식이 아니라 내부 구조의 원리다.
Alistair Cockburn이 2005년 제안한 이 패턴은 도메인 핵심을 중앙에 두고, 데이터베이스와 웹 프레임워크와 메시지 큐를 교체 가능한 어댑터로 외부에 배치한다. 도메인 코어는 자신을 둘러싼 기술의 이름을 모른다.
보상은 테스트 가능성이다. 인프라를 모의 객체로 교체하고 비즈니스 규칙만 검증할 수 있다. 단순한 CRUD에 이 구조를 강요하면 보일러플레이트만 쌓인다. 복잡한 도메인, 장기 생존이 예상되는 시스템에서만 그 격식은 품위가 된다.
모놀리식 안에서도, 마이크로서비스 안에서도 적용 가능하다. 위상이 아니라 태도이기 때문이다.
## 선택 기준
| | 모놀리식 | 레이어드 | 마이크로서비스 | 이벤트 드리븐 |
|-|-|-|-|-|
| 팀 규모 | 소 | 소~중 | 대·다팀 | 중~대 |
| 배포 빈도 | 낮음 | 낮~중 | 높음 | 높음 |
| 도메인 복잡도 | 낮음 | 중 | 높음(경계 명확) | 높음(흐름 중심) |
| 운영 복잡도 | 낮음 | 낮음 | 높음 | 높음 |
표는 한 절단면이다. 같은 패턴이 조건이 맞으면 우아하고, 조건이 어긋나면 재앙이 된다.
패턴을 선택한다는 것은 고통의 종류에 이름을 붙이는 것이다. 모놀리식은 결합도의 고통을 나중으로 미루고, 마이크로서비스는 운영 복잡도의 고통을 지금 선불로 낸다. 이벤트 드리븐은 인과 불투명을 치른다. 레이어드는 수직 관통 비용을 반복한다. 헥사고날은 의식의 초기 비용을 요구한다.
어떤 고통도 없는 아키텍처는 없다. 선택할 수 있는 것은 고통의 종류와 시점뿐이다.