한 줄 정의

아키텍처 패턴 은 특정 문제에 대한 맥락화된 해법(contextualized solution) 입니다. 이름이 붙은 토폴로지인 스타일과 달리, 패턴은 스타일을 가로지르며 재사용·통신·인프라 같은 공통 문제에 적용됩니다.

쉽게 말하면

스타일은 “건물의 골조 형태”를 말합니다. 모놀리스인지 마이크로서비스인지, 계층형인지 도메인형인지처럼 시스템 전체의 모양입니다.

패턴은 그 골조 안에서 반복적으로 나타나는 부품 단위의 해법 입니다. “도메인 로직과 운영 관심사를 어떻게 분리할 것인가”, “서비스 간 작업흐름을 어떻게 조율할 것인가” 같은 공통 문제에 대해 검증된 답을 모아둔 카탈로그입니다.

GoF의 디자인 패턴이 객체지향 코드 수준에서 했던 것을, 아키텍처 패턴은 시스템 수준에서 합니다.

왜 중요한가?

  • 해결하는 문제: 스타일을 정한 뒤에도 매일 마주치는 구체적인 결정—“운영 기능을 어디에 둘 것인가”, “이벤트 브로커를 몇 개 둘 것인가”—에 대해 검증된 사고틀과 트레이드오프 목록을 제공합니다.
  • 이게 없다면: 패턴 이름을 모른 채 사용하면 트레이드오프를 의식하지 못합니다. 사이드카가 무엇을 격리하는지, 단일 브로커가 어떤 위험을 안고 있는지 인식하지 못한 채 도구 기본값을 따라가게 됩니다.

핵심 내용

패턴과 스타일·모범관행·솔루션의 구분

스타일 vs 패턴

스타일은 토폴로지·물리적 아키텍처·배포·통신·데이터 토폴로지의 차이로 구별되는 이름 붙은 구조 입니다. 패턴은 스타일과 무관하게 적용 가능한 문제별 해법 입니다.

같은 패턴(예: 사이드카)이 마이크로서비스에서도, 모놀리스 일부에서도 등장할 수 있습니다.

패턴 vs 모범관행

“모범관행(best practice)“이라는 표현은 위험합니다. ‘모범’ 이라는 말이 붙는 순간 아키텍트들은 다른 가능성을 검토하지 않고 그대로 따라야 한다는 압박을 느낍니다.

“더 나은 관행”이라고 부르면 재고할 여지가 있지만, “모범관행”은 사고를 닫습니다. 패턴은 트레이드오프를 동반하는 선택지일 뿐이며, 무조건 따라야 할 본보기가 아닙니다.

패턴 vs 솔루션

도구·프레임워크·라이브러리는 하나 이상의 패턴을 캡슐화한 결과물 입니다. 예를 들어 Spring Cloud는 서비스 디스커버리·서킷 브레이커·게이트웨이 같은 여러 패턴을 묶어 제공합니다.

아키텍트는 먼저 가장 적절한 패턴을 식별 한 뒤, 그 패턴을 구현하는 가장 적절한 방법(어떤 라이브러리·어떤 인프라)을 선택해야 합니다. 순서가 뒤집혀 “이 도구를 쓰니까 이 패턴을 따른다”가 되면 트레이드오프 평가가 사라집니다.

재사용 패턴

도메인 결합 vs 운영 결합

마이크로서비스의 핵심 설계 목표는 결합 최소화 입니다. “결합보다 중복이 낫다”는 조언이 그 정신을 잘 표현합니다.

도메인 정보(예: 고객 프로필)는 서비스마다 자기 표현을 갖고, JSON처럼 느슨한 형식으로 통신해 결합을 끊습니다. 하지만 모든 결합이 나쁜 것은 아닙니다.

결합 종류예시처리 방식
도메인 결합주문이 결제 정보를 알아야 함가능한 끊고, 필요하면 메시지로 통신
운영 결합모니터링·로깅·인증·서킷 브레이커모든 서비스에 공통이므로 재사용이 이득

운영 기능을 팀마다 따로 구현하면 표준 모니터링 솔루션을 도입해도 팀별로 일관성이 무너지고, 통합 업그레이드도 어려워집니다. 운영 결합은 의도적으로 한 곳에 모아 재사용하는 편이 합리적입니다.

육각형 아키텍처 (포트와 어댑터)

핵심부에 도메인 로직을 두고, 가장자리의 여러 어댑터(UI·DB·SMS·이메일·로깅·테스트 스크립트 등)가 포트 를 통해 연결되는 패턴입니다.

graph TB
    subgraph App["애플리케이션"]
        UI[UI 어댑터]
        Test[테스트 스크립트 어댑터]
        Log[로깅 어댑터]
        CLI[관리자 CLI]
        Core[애플리케이션 핵심부<br/>도메인 로직]
        SMS[SMS 어댑터]
        Email[이메일 어댑터]
        DB[DB 어댑터]
        File[파일 어댑터]
    end
    UI --- Core
    Test --- Core
    Log --- Core
    CLI --- Core
    Core --- SMS
    Core --- Email
    Core --- DB
    Core --- File

창시자 알리스테어 코번은 처음에 이를 실제 육각형으로 그렸지만 곧 후회하고 포트와 어댑터(Ports and Adapters) 라는 이름을 더 선호했습니다. 너무 늦었고, “육각형”이라는 이름이 굳어졌습니다.

데이터 충실도 문제

육각형 아키텍처는 데이터베이스를 단순히 어댑터 로 취급합니다. 즉 DB 스키마는 핵심부 비즈니스 로직에 포함되지 않습니다.

이는 “DB는 외부 장치”라는 잘못된 인식에서 비롯되었습니다. 에릭 에반스는 『Domain-Driven Design』에서 이 오해를 바로잡으며, DB 스키마는 비즈니스 로직을 반영하도록 변경되어야 함 을 지적했습니다. 데이터 충실도(data fidelity)는 도메인의 일부이지 어댑터 너머의 외부 사물이 아닙니다.

마이크로서비스 시대의 위치

오늘날 아키텍트들은 육각형 패턴을 두 가지 의미로 혼용합니다.

  1. 운영 관심사와 도메인 관심사의 분리 를 설명하는 비유로 사용 — 괜찮음
  2. 데이터를 격리 함으로써 마이크로서비스 설계 원칙을 위반하는 문자 그대로의 패턴으로 사용 — 문제

이 구현은 더 이상 필수가 아닙니다. 운영 관심사 분리라는 원래 의도를 더 잘 구현하는 메커니즘이 등장했기 때문입니다. 바로 서비스 메시 입니다.

서비스 메시와 사이드카 패턴

마이크로서비스에서 운영 재사용을 위해 사이드카 패턴 과 서비스 메시를 사용합니다. 도메인 서비스 옆에 사이드카 컨테이너를 붙여 모니터링·로깅·인증·서킷 브레이커 같은 운영 기능을 격리합니다.

직교 재사용 패턴

사이드카는 단순히 운영을 분리하는 도구가 아니라, 직교 결합(orthogonal coupling) 을 다루는 직교 재사용 패턴입니다.

직교는 수학에서 두 직선이 직각으로 교차함을 뜻하며, 아키텍처에서는 목적은 완전히 다르지만 하나의 솔루션을 형성하려면 여전히 교차해야 하는 두 부분 을 가리킵니다.

도메인은 카탈로그·주문·결제처럼 비즈니스 축으로 분할됩니다. 모니터링은 그 축과 직교하는 운영 축이며, 모든 도메인을 가로지르지만 도메인 내용에는 무관심합니다. 사이드카는 이 직교 결합을 일관된 하나의 계층 으로 격리합니다.

사이드카·서비스 메시의 장점단점
격리된 결합을 생성하는 일관된 방법플랫폼마다 사이드카를 구현해야 함
일관된 인프라 조정 허용사이드카 컴포넌트가 크고 복잡해질 수 있음
팀별 소유권·중앙집중·둘의 조합 가능독립적인 팀들 간 구현 ‘이탈’ 가능
두 패턴의 위치

육각형 아키텍처와 서비스 메시는 모두 도메인을 운영 관심사로부터 분리하는 재사용 패턴 입니다. 차이는 적용 범위입니다.

  • 육각형은 범용 — 모놀리스에도 적용 가능
  • 서비스 메시는 마이크로서비스 같은 분산 아키텍처에 적합

아키텍트는 먼저 “분리가 필요하다”는 패턴을 식별하고, 그 다음에 자신의 아키텍처에서 이를 어떻게 구현할지 결정해야 합니다.

통신 패턴

오케스트레이션 vs 코레오그래피

이벤트 기반·메시지 기반 아키텍처에서 작업흐름을 조율하는 두 가지 방식입니다.

graph TB
    subgraph 오케스트레이션
        O[오케스트레이터]
        O --> SA[서비스 A]
        O --> SB[서비스 B]
        O --> SC[서비스 C]
        O --> SD[서비스 D]
    end
graph LR
    subgraph 코레오그래피
        CA[서비스 A] -.-> CB[서비스 B]
        CB -.-> CC[서비스 C]
        CC -.-> CD[서비스 D]
    end
오케스트레이션의 장점
  • 중앙집중된 작업흐름: 복잡성이 증가할 때 상태·행동방식·경계 조건을 통합 컴포넌트로 관리할 수 있습니다.
  • 오류 처리: 작업흐름 상태 소유자가 있으면 보상 트랜잭션·재시도 로직을 한 곳에서 다룰 수 있습니다.
  • 복구성: 오케스트레이터가 상태를 모니터링하므로 도메인 서비스가 잠시 중지돼도 재시도 로직으로 회복 가능합니다.
  • 상태 관리: 작업흐름 상태와 일시적 상태를 한 곳에서 조회할 수 있습니다.
오케스트레이션의 단점
  • 반응성: 모든 통신이 오케스트레이터를 거치므로 처리량이 많으면 병목이 됩니다.
  • 내결함성: 단일 장애점이 됩니다. 중복으로 해결할 수 있지만 복잡성이 늘어납니다.
  • 확장성: 조정점이 늘어나 잠재 병렬성이 감소합니다.
  • 서비스 결합: 오케스트레이터가 도메인 컴포넌트들과 단단히 결합됩니다. 마이크로서비스에선 바람직하지 않습니다.
코레오그래피의 장점
  • 반응성: 단일 병목 지점이 적어 병렬성을 활용할 기회가 많습니다.
  • 확장성: 조정점이 없어 독립적인 확장이 가능합니다.
  • 내결함성: 여러 인스턴스로 내결함성을 향상시킬 수 있습니다.
  • 서비스 분리: 오케스트레이터가 없어 결합이 약합니다.
코레오그래피의 단점
  • 분산 작업흐름: 작업흐름의 소유자가 없어 오류·경계 조건 관리가 어렵습니다.
  • 상태 관리: 중앙집중된 상태 소유자가 없습니다.
  • 오류 처리: 각 도메인 서비스가 작업흐름을 더 많이 알아야 하므로 어려워집니다.
  • 복구성: 재시도·상황 해결 작업을 수행할 주체가 없습니다.
트레이드오프 분석은 한 번으로 끝나지 않는다

이 두 패턴은 공통 패턴(common pattern) 의 좋은 예입니다. 분산 아키텍처라면 어디서든 등장하며, 매번 트레이드오프를 다시 평가해야 합니다.

“트레이드오프 분석을 단 한 번만 하고 끝낼 수는 없다.”

같은 시스템이라도 작업흐름마다 답이 다를 수 있습니다. 결제 같은 일관성·복구성이 중요한 흐름은 오케스트레이션, 알림 발송 같은 독립성이 중요한 흐름은 코레오그래피로 가는 식의 혼합 채택이 흔합니다.

CQRS (명령·질의 책임 분리)

graph TB
    subgraph 일반["클라이언트/서버"]
        App1[애플리케이션]
        DB1[(읽기/쓰기 DB)]
        App1 <--> DB1
    end
    subgraph CQRS_["CQRS"]
        App2[애플리케이션]
        WriteDB[(쓰기 DB)]
        ReadDB[(읽기 DB)]
        App2 --> WriteDB
        WriteDB --> ReadDB
        App2 --> ReadDB
    end

기존 클라이언트/서버는 하나의 DB가 읽기와 쓰기를 모두 담당합니다. CQRS는 이를 둘로 나눕니다.

  • 쓰기 는 하나의 데이터 저장소(DB 또는 지속적 메시지 대기열)로 격리
  • 읽기 는 또 다른 데이터베이스로 비동기 동기화하여 처리
왜 분리하는가
  • 읽기와 쓰기의 양 차이가 크게 날 때 — 읽기 전용 DB를 마음껏 확장
  • 보안·격리 관심사 — 쓰기 권한과 읽기 권한을 물리적으로 분리
  • 데이터 모델 분리 — 쓰기는 정규화된 트랜잭션 모델, 읽기는 검색·집계에 최적화된 모델

CQRS는 데이터 기능 유형이나 보안·물리 분리에 따라 서로 다른 아키텍처 특성을 지원하는 데이터 통신 패턴 의 좋은 예입니다.

대신 비동기 동기화로 인한 결과적 일관성(eventual consistency) 을 받아들여야 합니다.

인프라 패턴

브로커-도메인 vs 도메인-브로커

이벤트 주도 아키텍처에서 토픽·대기열은 일반적으로 발신자(sender)가 소유 합니다. 예를 들어 Payment가 주문 이벤트를 구독하려면 Order Placement가 소유한 토픽 주소를 알아야 합니다.

단일 브로커 (브로커-도메인 패턴)

전체 시스템이 하나의 브로커를 공유하는 방식입니다.

graph TB
    Buy[책 구매] --> OP[Order Placement]
    OP -.-> Broker((단일 브로커))
    Broker -.-> Pay[Payment]
    Broker -.-> Inv[Inventory]
    Broker -.-> WH[Warehouse]
    Broker -.-> Notif[Notification]
    Broker -.-> Ship[Shipping]
장점단점
중앙집중식 발견성 — 모든 이벤트 처리기가 어디로 가야 할지 안다내결함성 — 단일 브로커가 다운되면 전체 작업흐름이 멈춘다
가능한 최소한의 인프라 — 로깅·모니터링·거버넌스를 한 곳에서 처리처리량 제한 — 메시지가 늘어날수록 과부하 위험
도메인-브로커 패턴

도메인 분할을 반영해 서비스를 그룹으로 묶고, 각 그룹이 자신의 브로커를 공유 하는 대안입니다.

graph TB
    Buy[책 구매] --> OP[Order Placement]
    OP -.-> B1((브로커 A))
    Pay[Payment] -.-> B1
    B1 -.-> OF[Order Fulfillment]
    OF -.-> B2((브로커 B))
    B2 -.-> Notif[Notification]
    B2 -.-> Ship[Shipping]
    OP -.-> B3((브로커 C))
    B3 -.-> WH[Warehouse]
    B3 -.-> Inv[Inventory]
장점단점
더 나은 격리 수준 — 한 브로커 장애가 전체로 번지지 않음대기열·토픽 발견이 더 어려움
도메인 경계와 일치 — 인프라가 도메인 분할을 따라감인프라 비용 증가
확장성 좋음’움직이는 부품’ 증가로 유지보수 부담 가중
무엇을 우선할 것인가

발견 용이성과 도메인 격리 사이의 균형 문제입니다.

  • 시스템이 작고 단순하다 → 브로커-도메인(단일 브로커)으로 시작
  • 도메인 경계가 명확하고 한 도메인의 장애가 다른 도메인을 멈추면 안 된다 → 도메인-브로커
  • 카프카처럼 토픽 단위 격리가 강한 브로커를 쓰면 단일 브로커 단점이 일부 완화됨 — 그래도 클러스터 자체가 단일 장애 영역임을 잊으면 안 됩니다

이 두 패턴 역시 “모범관행”이 아닙니다. 시스템 규모·도메인 분리 요구·운영 비용 한도에 따라 다르게 선택해야 합니다.

비교 / 트레이드오프

패턴 영역핵심 질문후보
재사용운영 관심사를 도메인과 어떻게 분리할 것인가육각형 아키텍처 / 사이드카·서비스 메시
통신작업흐름을 어떻게 조율할 것인가오케스트레이션 / 코레오그래피
데이터 통신읽기와 쓰기 특성이 다를 때CQRS
인프라이벤트 브로커를 어떻게 배치할 것인가브로커-도메인 / 도메인-브로커

이 분류 자체가 핵심입니다. 패턴은 “한 시스템에서 하나만 고른다”가 아니라 영역별로 독립적으로 적용 됩니다. 마이크로서비스 시스템이 사이드카 + 코레오그래피 + CQRS + 도메인-브로커를 동시에 채택하는 것은 자연스러운 조합입니다.

내 생각

”모범관행”이라는 단어의 함정

실무에서 가장 자주 들리는 표현이 “그게 best practice라서요”입니다. 이 한 마디로 트레이드오프 분석이 종료됩니다. 책의 지적은 단순한 의미론 비판이 아니라 사고의 닫힘 을 경고합니다.

매번 “왜 이게 best인가? 우리 맥락에서도 best인가?”를 물어야 패턴이 살아있는 도구가 됩니다. 그렇지 않으면 패턴은 컬트가 됩니다.

육각형 아키텍처에 대한 재평가

DDD를 만난 뒤로 “DB는 어댑터”라는 단순화가 점점 어색하게 느껴졌습니다. 책의 지적이 정확합니다 — 도메인 모델과 ER 모델은 함께 진화해야 하며, DB를 단순히 외부 장치로 격리하면 데이터 충실도가 무너집니다.

실무에선 ORM을 써도 “테이블 스키마가 도메인을 반영하는가”를 늘 점검해야 합니다. 어댑터 너머에 두면 누구도 책임지지 않습니다.

단일 브로커의 유혹

작은 팀에서 카프카 클러스터 하나로 모든 이벤트를 흘려보내는 패턴을 자주 봅니다. 운영이 단순해서 매력적이지만, 도메인 경계가 무뎌질 때 토픽 네임스페이스가 난장판이 되는 경험을 했습니다.

도메인-브로커는 인프라 비용 증가가 큰 부담이지만, 토픽 카탈로그를 자동 생성하는 도구(예: Confluent Schema Registry + 네임스페이스 컨벤션)와 함께 쓰면 발견성 단점은 완화됩니다.

더 알아볼 것

  • Service Mesh 구현체 비교 — Istio·Linkerd·Consul Connect 트레이드오프
  • CQRS와 Event Sourcing의 결합 패턴
  • Saga 패턴 — 오케스트레이션·코레오그래피 두 변형의 비교
  • 카프카에서 도메인-브로커를 흉내내는 방법 (네임스페이스·ACL·클러스터 분리 기준)
  • 직교 결합의 다른 사례들 — 인증·관측·암호화

관련 개념

출처

  • 마크 리처즈, 닐 포드, 라주 간디, 프라모드 사달게. 『소프트웨어 아키텍처 The Basics』. 한빛미디어, 2024. Chapter 20.