5편은 분산 시스템과 MSA 아키텍처입니다. 면접관은 패턴 이름을 아는지보다 언제 도입하고 어떤 비용을 감수했는지를 봅니다.

시리즈 구성:

  • 1편: 인프라/스케일링
  • 2편: 운영/안정성
  • 3편: 설계/리더십
  • 4편: 동시성/런타임
  • 5편 (현재): 분산/MSA 아키텍처
  • 6편 (예정): 가용성/안정성 패턴

1. SAGA 패턴

Q1. MSA에서 트랜잭션을 어떻게 처리하시나요?

기대 답변: 2PC는 락이 길어져 부적합하기 때문에 SAGA(보상 트랜잭션 릴레이)를 씁니다.

  • Choreography: 각 서비스가 이벤트를 듣고 자기 단계 처리
  • Orchestration: 중앙 조정자가 단계별 호출

선택 기준은 서비스 수와 흐름 복잡도입니다. 단순 흐름은 Choreography, 가시성·복구가 중요하면 Orchestration.

🔄 꼬리질문 1: 보상 트랜잭션 자체가 실패하면 어떻게 하나요?

기대 답변:

  • 재시도 정책 (지수 백오프 + jitter, 최대 N회)
  • **DLQ(Dead Letter Queue)**로 격리, 운영 알람
  • 멱등키 기반 수동 재처리 콘솔

핵심은 eventual consistency 윈도우를 명시적으로 정의하는 것입니다.

🔄 꼬리질문 2: Choreography의 단점은?

기대 답변:

  • 흐름이 코드 여러 곳에 흩어져 추적 어려움
  • 새 단계 추가 시 의존 서비스 모두 인지해야
  • 분산 트레이싱 없으면 디버깅 비용 폭증

→ 흐름이 5단계 넘으면 Orchestration으로 전환 권장.

🔄 꼬리질문 3: SAGA vs Outbox 패턴 차이는?

기대 답변:

  • SAGA: 분산 트랜잭션 흐름 패턴 (보상)
  • Outbox: 로컬 트랜잭션과 이벤트 발행을 원자적으로 묶는 패턴

둘은 보완 관계입니다. SAGA 각 단계에서 이벤트 발행의 신뢰성을 Outbox로 보장.


2. CQRS

Q2. CQRS는 언제 도입하시나요?

기대 답변: 명령(Command)과 조회(Query)의 데이터 모델·저장소 요구가 달라질 때입니다.

  • 조회 쪽이 복잡 집계·검색이고 쓰기보다 빈도가 훨씬 높음
  • 쓰기 모델이 도메인 규칙으로 무거운데 조회 응답속도 SLO가 엄격

도입 비용은 프로젝션 갱신 지연(eventual consistency)과 운영 복잡도입니다.

🔄 꼬리질문 1: 일관성 윈도우는 어떻게 다루나요?

기대 답변:

  • 사용자 화면에서 자기 변경 사항은 즉시 보여야 함 → Read Your Writes: 쓰기 직후 잠시 마스터에서 조회
  • 외부 알림에는 프로젝션 완료 후 전송
  • 운영 메트릭으로 lag(p99) 지표화

🔄 꼬리질문 2: Event Sourcing과 같이 가야 하나요?

기대 답변: 아닙니다. CQRS는 모델 분리, Event Sourcing은 상태 표현입니다.

  • CQRS만 도입: 일반 RDB + 별도 read DB
  • ES까지 도입: 감사/재구성이 필요할 때만 (운영 부담 큼)

대부분은 CQRS만 도입해도 효과가 충분합니다.

🔄 꼬리질문 3: 프로젝션 갱신은 어떻게 안정화하나요?

기대 답변:

  • CDC(Debezium 등)로 카프카에 변경 흘리고 컨슈머가 read DB 갱신
  • 멱등 처리 + 순서 보장(파티션 키 = aggregate id)
  • 실패 시 재처리 가능하도록 오프셋·DLQ 관리

3. API Gateway 패턴

Q3. API Gateway에 어디까지 책임을 두시겠어요?

기대 답변: 횡단 관심사만 둡니다.

  • 인증·인가, 레이트 리밋, 라우팅, 응답 캐싱, 관측(trace ID 부여)

비즈니스 로직·집계는 두지 않습니다. BFF가 필요하면 별도 레이어로.

🔄 꼬리질문 1: 단일 장애점 위험은 어떻게 줄이나요?

기대 답변:

  • 다중 인스턴스 + 무상태 + L4/L7 LB
  • 게이트웨이 자체에 서킷 브레이커
  • 인증 캐시(JWT 검증 결과)로 ID provider 의존도 축소

🔄 꼬리질문 2: 게이트웨이가 병목이 될 때 어떤 신호를 보나요?

기대 답변:

  • 게이트웨이 p99 vs 백엔드 p99 격차
  • 커넥션 풀 사용률, keep-alive 재사용률
  • TLS 핸드셰이크 비율(0-RTT/session resumption 적용 효과)

🔄 꼬리질문 3: 게이트웨이 vs Service Mesh, 어떻게 나누나요?

기대 답변:

  • 게이트웨이: 외부 트래픽 입구 (north-south)
  • Service Mesh: 내부 서비스 간 (east-west) — mTLS, 재시도, 트래픽 분할

둘은 보완. 작은 조직은 게이트웨이만으로 시작, 서비스 50+ 넘으면 Mesh 검토.


4. DDD와 Bounded Context

Q4. Bounded Context를 코드·팀·DB에 어떻게 반영하시나요?

기대 답변:

  • 코드: 모듈/패키지 경계 = 컨텍스트 경계. 다른 컨텍스트 객체 직접 import 금지
  • : 한 컨텍스트는 한 팀의 결정권
  • DB: 스키마 분리 (가능하면 인스턴스도). 공유 DB는 컨텍스트 경계를 깨뜨림

🔄 꼬리질문 1: 컨텍스트 간 통신은 어떻게 하나요?

기대 답변:

  • 비동기 도메인 이벤트 우선
  • 동기 호출은 오픈 호스트 서비스 형태의 명시적 계약
  • 직접 DB 조회는 금지 (Anti-Corruption Layer로 격리)

🔄 꼬리질문 2: 도메인 모델과 ORM 엔티티가 같아야 하나요?

기대 답변: 규모에 따라 다릅니다.

  • 작은 도메인: 같아도 OK (@Entity = 도메인 객체)
  • 복잡 도메인: 분리 (도메인 객체 + 영속 엔티티 + 매핑). 운영 부담은 늘지만 도메인 규칙이 ORM에 오염되지 않음

🔄 꼬리질문 3: 마이크로서비스로 분리하는 기준은?

기대 답변: 컨텍스트 경계가 분명하고 다음 중 둘 이상이면 분리:

  • 배포 주기/팀이 다름
  • 스케일 요구가 다름 (예: 결제는 5배, 카탈로그는 1배)
  • 장애 격리 SLO가 다름

코드 모듈로 시작해 문제가 보일 때 분리하는 모듈러 모놀리스 → MSA 흐름이 안전합니다.


5. 모놀리스 내 도메인 이벤트와 아웃박스

Q5. 같은 모놀리스 안 두 모듈을 직접 호출 대신 도메인 이벤트로 묶을 때 트랜잭션 경계는 어떻게 설계하나요?

기대 답변: 3축으로 정리합니다.

  1. 이벤트 발행 시점 제어: 커밋 후 발행 (@TransactionalEventListener AFTER_COMMIT)
  2. 유실 방지: Outbox 패턴 — 같은 트랜잭션에 outbox 테이블 insert, 별도 릴레이가 발행
  3. 실패 처리: 재시도 + DLQ + 보상 트랜잭션

🔄 꼬리질문 1: 커밋 전 발행하면 어떤 일이 생기나요?

기대 답변:

  • 커밋 실패 시 컨슈머가 이미 처리한 상태 → 정합성 깨짐
  • 같은 트랜잭션 안 다른 작업의 lock과 경합

AFTER_COMMIT이 기본, 단 커밋 후 발행 실패는 별도로 잡아 outbox로 보완.

🔄 꼬리질문 2: Outbox 폴링의 DB 부하는 어떻게 제어하나요?

기대 답변:

  • 인덱스(status, created_at)와 적정 batch size
  • 발행 후 즉시 삭제 또는 status 업데이트
  • 규모가 커지면 CDC(Debezium)로 전환해 폴링 자체를 제거

🔄 꼬리질문 3: 컨슈머 측 멱등성은 어떻게 보장하나요?

기대 답변:

  • 이벤트 ID를 유니크 키로 두고 처리 이력 테이블에 insert
  • 처리 완료 후 ack
  • 멱등 키 보존 기간을 비즈니스 윈도우보다 길게

마무리: 5편 핵심 정리

  1. SAGA: 보상 트랜잭션과 DLQ까지 설계, Choreography vs Orchestration 판단
  2. CQRS: 일관성 윈도우 관리, Event Sourcing은 선택적
  3. API Gateway: 횡단 관심사만, 비즈니스 로직 금지
  4. DDD: 컨텍스트 경계가 코드·팀·DB까지 반영
  5. 도메인 이벤트 + 아웃박스: 커밋 후 발행 + 유실 방지 + 멱등성

다음 6편은 가용성/안정성 패턴 — Rate Limiting, Bulkhead, Circuit Breaker, Timeout Cascade, 멱등성과 재시도 jitter를 다룹니다.