콘텐츠로 바로가기

Design Patterns for Distributed Systems

네트워크 통신과 부분적 장애가 뒤섞인 분산 환경에서 시스템의 안정성과 성능을 보장하는 재사용 가능한 설계 패턴들을 다루는 학습 노드입니다.

Article
M

Me

hyunyoun's Blog

system-architecture-distributed-systemssystem-architecturedistributed-systemsfoundationsarchitectural-patternsdesign-patterns-for-distributed-systemsarchitectural-evolutionlearning9 min read

1. Overview

분산 시스템을 위한 디자인 패턴(Design Patterns for Distributed Systems)은 네트워크 너머에 찢어져 있는 마이크로서비스들이 장애, 통신 지연, 데이터 불일치의 혼돈 속에서도 마치 하나의 안정적인 기계처럼 동작하게 만드는 실무 아키텍처 패턴의 집대성입니다.

학습자는 무수한 마이크로서비스의 진입점을 하나로 모으고 인증/라우팅을 전담하는 API Gateway 패턴과 프론트엔드별 맞춤형 API를 깎아주는 **BFF(Backend for Frontend)**를 해부합니다. 나아가 서비스 간 통신이 지연될 때 시스템 전체가 마비되는 연쇄 장애(Cascading Failure)를 차단하기 위해 스스로 회로를 끊어버리는 **서킷 브레이커(Circuit Breaker)**의 방어 기제를 뜯어봅니다. 마지막으로 서비스 디스커버리(Service Discovery)부터 트래픽 통제까지 인프라 통신 계층을 어플리케이션 코드 밖으로 완전히 분리해 버리는 최강의 클라우드 네이티브 패턴, **서비스 메시(Service Mesh)와 사이드카(Sidecar)**를 장악하여 무결점 분산 시스템을 구축하는 역량을 확보합니다.

2. Scope & Boundaries

In-Scope

  • Edge Patterns: API Gateway, BFF (Backend for Frontend), Rate Limiting(처리율 제한).
  • Resiliency Patterns: Circuit Breaker(회로 차단기), Bulkhead(격벽), Retry & Timeout(재시도 및 타임아웃).
  • Infrastructure Patterns: Sidecar Pattern, Service Mesh (Istio, Envoy), Service Discovery (Consul, Eureka).
  • Communication Flow: Synchronous (동기) vs Asynchronous (비동기 이벤트) 패턴의 물리적 트레이드오프.

Out-of-Scope

  • 데이터 정합성 패턴: Saga Pattern, CQRS, Event Sourcing \rightarrow 06-02-06 Data Modeling for Connected Data 및 분산 트랜잭션 영역으로 위임.
  • 쿠버네티스 CNI/CRI 깊은 튜닝: 인프라 프로비저닝 차원의 오케스트레이션 \rightarrow 09-02 CI/CD & DevOps 영역.

Boundaries

  • 라이브러리(App 레벨) vs 사이드카(Infra 레벨): 서킷 브레이커 로직을 자바 코드 안(예: Netflix Hystrix)에 직접 짜 넣으면, Node.js나 Python 서버에는 적용할 수 없는 '언어 종속성'이 발생합니다. 최신 패턴인 서비스 메시(Service Mesh)는 이 통신 제어 로직을 앱 안에서 뜯어내어, 파드(Pod) 안에 동승한 사이드카(Envoy 프록시) 프로세스에게 전담시킵니다. 앱 개발자는 통신 장애를 신경 쓰지 않고 비즈니스 로직만 짜면 되는, '비즈니스와 인프라의 완벽한 물리적 분리'가 이 패턴의 철학적 종착지입니다.

3. Counterexample

  • 프론트엔드의 N+1 호출 지옥: 마이크로서비스가 20개로 쪼개졌습니다. 모바일 앱(클라이언트)이 '마이페이지' 화면을 그리기 위해 유저 서버, 주문 서버, 리뷰 서버, 포인트 서버에 직접 HTTP 요청을 4번 날립니다. 모바일 네트워크 환경이 안 좋아서 화면 렌더링에 5초가 걸리고 배터리가 광탈합니다. 중간에 여러 서버의 응답을 모아(Aggregation) 한 방에 내려주는 API Gateway나 BFF(Backend for Frontend) 패턴 부재가 낳은 클라이언트 학대입니다.
  • 연쇄 장애(Cascading Failure)의 악몽: 리뷰 서버의 DB가 느려져 응답에 30초가 걸립니다. 주문 서버가 리뷰 서버를 호출했다가 스레드가 30초간 블로킹됩니다. 결국 주문 서버의 모든 스레드가 고갈되어 주문 서버마저 죽어버리고, 메인 홈 서버까지 연쇄적으로 다운됩니다. 하나의 썩은 사과가 전체 바구니를 망치는 것을 물리적으로 격리하는 서킷 브레이커(Circuit Breaker)나 격벽(Bulkhead) 통제가 없을 때 벌어지는 참사입니다.

4. Prerequisites

  • 분산 시스템의 8가지 오류 (Basic): 네트워크는 신뢰할 수 없고 지연이 있다는 사실의 인지. (08-01 Network Fundamentals)
  • 마이크로서비스 아키텍처 (Basic): 모놀리스에서 찢어진 독립 서비스의 형태. (07-01-01 Monolithic Evolution)

5. Learning Map

Sequence Core Cluster Objective & Description Evidence (BoK)
1 Edge & Gateway Patterns 흩어진 수십 개의 서비스 진입점을 하나로 모아 클라이언트의 API 호출 고통을 해결하는 BFF와 Gateway를 쥡니다. P1
2 Circuit Breaker & Resiliency 남의 서버 장애가 내 서버의 스레드를 말라붙게 하는 연쇄 작용을 끊어내는 차단기와 타임아웃 방어막을 해부합니다. P5
3 Sidecar Pattern 로깅, 모니터링, 통신 제어 코드를 비즈니스 로직에서 뜯어내 별도의 보조 프로세스로 띄우는 분리 마법을 뜯어봅니다. Industry
4 Service Mesh (Istio/Envoy) 마이크로서비스의 궁극적 진화 형태. 어플리케이션 코드를 1줄도 수정하지 않고 전체 네트워크 트래픽을 통제하는 인프라를 장악합니다. Industry

6. Learning Topics

Basic

Core Topic 01: 분산 시스템의 수문장, API Gateway & BFF (Edge Patterns)

  • Why to Learn: 쪼개진 수십 개의 서비스 IP를 클라이언트가 일일이 기억하고 호출하는 구조적 파탄을 막고, 인증/인가/라우팅을 중앙 방화벽에서 처리하기 위함입니다.
  • What to Learn:
    • Concepts: API Gateway, BFF (Backend for Frontend), API Composition/Aggregation, Reverse Proxy.
    • Skills: NGINX, Spring Cloud Gateway, Kong 등을 활용한 라우팅 규칙 설계.
  • How to Learn:
    • 1단계: API Aggregation: 클라이언트가 Gateway 하나만 찌르면, Gateway가 뒤편의 서비스 A, B, C를 병렬로 호출하여 하나의 JSON 덩어리로 조합해 클라이언트에게 돌려주는 네트워크 비용 절감을 해부합니다.
    • 2단계: 맞춤형 재단(BFF): 모바일 앱(화면 작음)과 웹 데스크톱(화면 큼)이 요구하는 데이터의 양이 다릅니다. 범용 Gateway 하나 대신, 모바일용 BFF와 웹용 BFF를 따로 띄워 프론트엔드 팀이 각자 필요한 API를 깎아 쓰는(Tailored) 아키텍처를 뜯어봅니다.
  • Implement: 파이썬 FastAPI를 이용한 초간단 Aggregator 데모. Gateway 서버가 /mypage 요청을 받으면 비동기(asyncio.gather)로 가상의 User_ServiceOrder_Service를 찔러 응답을 합친 뒤 리턴. 개별 호출(직렬) 대비 병렬 호출의 응답 속도 향상(Latency 축소) 콘솔 출력.

Core Topic 02: 타버린 퓨즈 끊어내기, 서킷 브레이커 (Circuit Breaker & Resiliency)

  • Why to Learn: 남의 장애가 내 서버의 스레드 자원을 갉아먹는 분산 시스템 최악의 전염병(Cascading Failure)을 물리적으로 격리(Fail-fast)하기 위함입니다.
  • What to Learn:
    • Concepts: Circuit Breaker 상태 (Closed, Open, Half-Open), Cascading Failure, Fallback (대체 응답), Bulkhead (스레드 격벽), Retry with Exponential Backoff.
    • Skills: 장애 감지 임계치 설정(예: 10초 내 50% 에러 발생 시 회로 차단).
  • How to Learn:
    • 1단계: 회로 차단(Open): 타겟 서비스가 5초간 먹통이면 타임아웃 스레드가 계속 쌓입니다. 이때 서킷 브레이커가 회로를 끊어버리고(Open 상태), 이후 들어오는 요청은 타겟을 찌르지도 않고 0.001초 만에 "안 돼 돌아가(Fail-fast)" 에러를 던져 내 서버의 스레드를 방어하는 기제를 해부합니다.
    • 2단계: 회복(Half-Open): 일정 시간이 지나면 서킷 브레이커가 요청 1~2개만 슬쩍 흘려보내 타겟 서버가 살아났는지 간을 봅니다(Half-Open). 성공하면 회로를 다시 닫고(Closed), 실패하면 닫아버리는 자동 치유(Auto-healing) 상태 머신을 뜯어봅니다.
  • Implement: 파이썬 커스텀 서킷 브레이커 클래스 구현. call() 메서드를 감싸고, 실패 횟수가 3번 누적되면 상태를 OPEN으로 바꿈. OPEN 상태일 때는 Exception을 즉각 반환하고 시간(sleep)을 낭비하지 않는 방어 기전 코드 렌더링.

Practical

Core Topic 03: 비즈니스와 인프라의 찢어짐, 사이드카 패턴 (Sidecar Pattern)

  • Why to Learn: 앱을 컨테이너로 배포할 때, 로깅 에이전트나 통신 암호화 같은 인프라 로직을 비즈니스 코드 안에 넣지 않고 별도의 '보조 프로세스'로 밀어내기 위함입니다.
  • What to Learn:
    • Concepts: Sidecar Pattern, Pod(쿠버네티스의 논리적 호스트), Separation of Concerns (관심사의 분리), Co-location.
    • Skills: 메인 컨테이너와 사이드카 컨테이너 간의 로컬 호스트(Localhost) 통신 맵핑.
  • How to Learn:
    • 1단계: 오토바이와 사이드카: 메인 프로세스(오토바이)는 운전(비즈니스 로직)만 합니다. 옆에 붙은 보조 프로세스(사이드카)가 지도 보기, 무전기 통신(로깅, 메트릭 수집, TLS 암호화)을 대신합니다. 동일한 파드(Pod) 내에 띄워 파일 시스템이나 로컬 네트워크를 공유하는 구조를 해부합니다.
    • 2단계: 언어 독립성: 메인 서버가 Java로 짜여 있든 Node.js로 짜여 있든 상관없습니다. 인프라 팀이 Go 언어로 짠 사이드카 컨테이너를 모든 앱 옆에 붙이기만 하면 전사 로깅 규격을 통일할 수 있는 궁극의 확장성을 뜯어봅니다.
  • Implement: 개념적 사이드카 구조 로깅 파이프라인. 메인 파이썬 스크립트는 단순히 로컬 폴더의 app.log 파일에 텍스트만 씀(비즈니스 로직 집중). 백그라운드로 도는 별도의 파이썬 스크립트(사이드카 흉내)가 app.log 파일 변경을 감지하여 원격 서버로 HTTP Post 전송. 로직과 로깅 송출의 완벽한 분리 데모.

Advanced

Core Topic 04: 그물망의 지배자, 서비스 메시 (Service Mesh: Istio/Envoy)

  • Why to Learn: 수백 개의 마이크로서비스가 얽힌 환경에서, 각 개발팀이 통신 제어 코드를 짜는 헛수고를 없애고 인프라 레벨에서 전체 트래픽을 통제하는 클라우드 네이티브의 끝판왕을 장악하기 위함입니다.
  • What to Learn:
    • Concepts: Service Mesh, Data Plane (Envoy Proxies), Control Plane (Istio), Service Discovery, mTLS (상호 TLS), Canary Deployment (트래픽 분할).
    • Skills: 애플리케이션 코드 무수정 상태에서의 서킷 브레이커, 타임아웃, 트래픽 라우팅 인프라 주입.
  • How to Learn:
    • 1단계: 데이터 플레인(Data Plane): 모든 마이크로서비스 파드 안에 초경량 프록시(Envoy) 사이드카를 강제로 주입시킵니다. 서비스 A가 서비스 B를 부를 때, A의 코드는 localhost:Envoy를 부르고, 프록시가 B의 프록시로 트래픽을 넘기는 보이지 않는 L7 그물망(Mesh)을 해부합니다.
    • 2단계: 컨트롤 플레인(Control Plane): 중앙 관리실(Istio)에서 "A에서 B로 가는 트래픽의 10%만 B_v2(신버전)로 보내라(카나리 배포)", "응답이 2초 넘으면 서킷 브레이커 터트려라"라는 명령을 내리면, 전체 그물망의 프록시들이 즉각 룰을 업데이트하여 코딩 없이 네트워크를 지배하는 경이를 뜯어봅니다.
  • Implement: 서비스 메시 트래픽 가로채기(Intercept) 모사 로직. 서비스 A의 HTTP 요청(requests.get('http://service_b'))을 프록시 클래스가 가로챔(Interceptor). 통신 전 중앙 레지스트리(Control Plane Mock)에 접근해 "Service B의 신버전 IP가 뭐야?" 물어보고 트래픽을 동적으로 스위칭해버리는 데이터 플레인 마술 스크립트.

7. Terminology

Term (EN / ko, abbr) 1문장 정의 단계(기본/권장/실무/심화) 역할/맥락 관련 개념 유사/대비/함께 사용 오해 포인트 Evidence(Primary/Secondary/Industry) Flags(core)
API Gateway 모든 클라이언트의 요청을 받아내는 단일 진입점(Single Entry Point)으로, 뒤편의 수많은 마이크로서비스 IP를 감추고 인증/라우팅을 전담하는 방화벽입니다. 기본 에지 라우팅 Reverse Proxy BFF (Backend for Frontend) 모든 비즈니스 로직을 다 욱여넣으면 과거의 ESB 병목처럼 변질될 수 있음 P1:CS2023 core
Circuit Breaker 외부 서비스 호출 실패율이 임계치를 넘으면 회로를 끊어(Open) 즉시 에러를 반환(Fail-fast)함으로써, 타임아웃으로 내 서버 스레드까지 말라죽는 연쇄 장애를 방어하는 기법입니다. 권장 장애 격리(Resiliency) Fail-fast / Timeout Bulkhead 차단기가 내려갔다(Open)는 것은 고장 났다는 것이 아니라 '안전을 위해 스스로 끊었다'는 뜻임 P5:SFIA core
Sidecar Pattern 메인 애플리케이션 컨테이너 안에 비즈니스 로직만 남기고, 로깅이나 통신 제어 같은 인프라 로직을 별도의 보조 컨테이너(사이드카)로 분리해 띄우는 배포 패턴입니다. 실무 관심사 분리 Pod / Co-location Service Mesh 마이크로서비스 내부 코드(언어)의 종속성을 제거하기 위해 물리적인 프로세스를 분리한 것임 Industry core
Service Mesh 수많은 마이크로서비스 파드마다 사이드카 프록시(Envoy)를 주입하고, 이 프록시들끼리만 통신하게 만들어(Data Plane) 중앙에서 네트워크 트래픽을 통제하는 클라우드 인프라입니다. 심화 분산 네트워크 통제 Istio / Envoy API Gateway API Gateway가 '외부'에서 들어오는 트래픽 통제라면, Service Mesh는 '내부' 서비스 간 트래픽 통제임 Industry core

8. References

Primary

  • [P1] CS2023 - Software Engineering (SE) - Software Architecture (Design Patterns)
  • [P5] SFIA - Enterprise IT Architecture (ARCH) - Integration Architecture

Secondary

  • [Release It!] Michael Nygard - Circuit Breaker, Bulkhead, and System Resiliency
  • [Microservices Patterns] Chris Richardson - API Gateway, BFF, and Service Discovery

Industry

  • [Istio Documentation] - What is a Service Mesh? Control Plane vs Data Plane
  • [Netflix TechBlog] - Fault Tolerance in a High Volume, Distributed System (Hystrix)

9. Final Checklist

Primary

  • 수십 개의 마이크로서비스를 운영할 때, 클라이언트가 각 서비스의 IP와 포트를 직접 알고 호출하면 안 되는 물리적 이유(결합도 및 보안)를 API Gateway 관점에서 설명할 수 있는가?
  • 서킷 브레이커(Circuit Breaker)의 3가지 상태(Closed, Open, Half-Open)가 전이되는 과정을 자동 복구(Auto-healing) 메커니즘 관점으로 묘사할 수 있는가?

Secondary

  • 범용 API Gateway 하나만 두는 것과, 모바일 팀 / 웹 팀 / 외부 B2B 팀별로 BFF(Backend for Frontend)를 쪼개어 운영할 때의 조직적(콘웨이의 법칙) 장단점을 저울질할 수 있는가?
  • 타겟 서버가 지연될 때, 무한정 대기(Blocking)하는 현상이 내 서버의 커넥션 풀(Connection Pool)과 워커 스레드(Worker Thread)를 어떻게 고갈시키는지 증명할 수 있는가?

Industry

  • 쿠버네티스(Kubernetes) 환경에서 사이드카(Sidecar) 패턴이 메인 컨테이너와 동일한 라이프사이클(Pod)을 가지며 localhost 통신을 할 수 있는 물리적 구조를 아키텍처링 할 수 있는가?
  • 서비스 메시(Service Mesh)를 도입하면 어플리케이션(Java/Go) 코드를 수정하지 않고도 '카나리 배포(Canary Deployment, 10% 트래픽 분할)'나 '서킷 브레이커'를 인프라 단에서 켤 수 있는 이유(프록시 가로채기)를 설계할 수 있는가?

System Architecture · Architectural Evolution

5 / 5