로드 밸런싱
로드 밸런싱¶
개요¶
이 문서에서는 로드 밸런싱(Load Balancing)의 핵심 개념을 다룹니다. L4/L7 로드 밸런서의 차이, 다양한 트래픽 분배 알고리즘, Sticky Session, 그리고 헬스 체크 메커니즘을 학습합니다.
난이도: ⭐⭐⭐ 예상 학습 시간: 2-3시간 선수 지식: 03_Network_Fundamentals_Review.md
목차¶
1. 로드 밸런싱이란?¶
1.1 정의¶
로드 밸런싱은 들어오는 네트워크 트래픽을 여러 서버에 분산시켜 시스템의 가용성과 성능을 향상시키는 기술입니다.
┌─────────────────────────────────────────────────────────────────┐
│ 로드 밸런싱 개념 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 로드 밸런서 없이: │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Client 1 ─────┐ │ │
│ │ Client 2 ─────┼─────────▶ Server 1 (과부하!) │ │
│ │ Client 3 ─────┤ │ │
│ │ ... │ │ │
│ │ Client N ─────┘ │ │
│ │ │ │
│ │ 문제: 단일 서버 과부하, 장애 시 서비스 중단 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 로드 밸런서 적용: │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Client 1 ─────┐ ┌────────▶ Server 1 │ │
│ │ Client 2 ─────┼─▶ [LB] ─┼────────▶ Server 2 │ │
│ │ Client 3 ─────┤ └────────▶ Server 3 │ │
│ │ ... │ │ │
│ │ Client N ─────┘ │ │
│ │ │ │
│ │ 해결: 부하 분산, 고가용성, 수평 확장 가능 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
1.2 로드 밸런서의 역할¶
┌─────────────────────────────────────────────────────────────────┐
│ 로드 밸런서 주요 기능 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. 트래픽 분산 │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ • 요청을 여러 서버에 균등하게 분배 │ │
│ │ • 서버별 처리 용량에 따라 가중치 적용 가능 │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 2. 고가용성 (High Availability) │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ • 서버 장애 감지 및 트래픽 자동 전환 │ │
│ │ • 사용자는 장애를 인지하지 못함 │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 3. 확장성 │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ • 서버 추가/제거가 용이 │ │
│ │ • 무중단 서버 교체 가능 │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 4. SSL 종료 (SSL Termination) │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ • LB에서 HTTPS 처리, 백엔드는 HTTP │ │
│ │ • 서버 부하 감소, 인증서 관리 집중화 │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 5. 세션 관리 │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ • Sticky Session으로 같은 서버 유지 │ │
│ │ • 세션 데이터 일관성 보장 │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
2. L4 vs L7 로드 밸런서¶
2.1 L4 로드 밸런서 (Transport Layer)¶
┌─────────────────────────────────────────────────────────────────┐
│ L4 로드 밸런서 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ OSI 4계층 (전송 계층) - TCP/UDP 레벨에서 동작 │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 패킷 헤더 정보만 확인: │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ Source IP │ Dest IP │ Source │ Dest │ │ │
│ │ │ 203.0.113.50 │ 10.0.0.100 │ Port │ Port │ │ │
│ │ │ │ │ 54321 │ 80 │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ │ ↑ │ │
│ │ 이 정보로 라우팅 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 동작 방식: │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Client ──▶ LB (10.0.0.100:80) │ │
│ │ │ │ │
│ │ ┌────────┴────────┐ │ │
│ │ │ IP/Port 기반 │ │ │
│ │ │ 라우팅 결정 │ │ │
│ │ └────────┬────────┘ │ │
│ │ │ │ │
│ │ ┌─────────┼─────────┐ │ │
│ │ ▼ ▼ ▼ │ │
│ │ Server 1 Server 2 Server 3 │ │
│ │ 10.0.1.1 10.0.1.2 10.0.1.3 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 장점: │
│ • 빠른 처리 (패킷 내용 검사 안 함) │
│ • 낮은 리소스 사용 │
│ • 프로토콜에 독립적 (TCP, UDP 모두 가능) │
│ │
│ 단점: │
│ • 애플리케이션 인식 불가 │
│ • URL 기반 라우팅 불가 │
│ • 콘텐츠 기반 결정 불가 │
│ │
│ 예시: AWS NLB, HAProxy (TCP mode), LVS │
│ │
└─────────────────────────────────────────────────────────────────┘
2.2 L7 로드 밸런서 (Application Layer)¶
┌─────────────────────────────────────────────────────────────────┐
│ L7 로드 밸런서 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ OSI 7계층 (애플리케이션 계층) - HTTP/HTTPS 레벨에서 동작 │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ HTTP 요청 내용 분석: │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ GET /api/users HTTP/1.1 │ │ │
│ │ │ Host: api.example.com │ │ │
│ │ │ Cookie: session=abc123 │ │ │
│ │ │ Authorization: Bearer xxx │ │ │
│ │ │ Content-Type: application/json │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ │ ↑ │ │
│ │ 전체 내용 분석하여 라우팅 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ URL 기반 라우팅: │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ /api/users/* ──────────▶ User Service │ │
│ │ /api/orders/* ──────────▶ Order Service │ │
│ │ /api/products/*──────────▶ Product Service │ │
│ │ /static/* ──────────▶ CDN/Static Server │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 호스트 기반 라우팅: │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ api.example.com ──────▶ API Servers │ │
│ │ www.example.com ──────▶ Web Servers │ │
│ │ admin.example.com ──────▶ Admin Servers │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 장점: │
│ • 콘텐츠 기반 스마트 라우팅 │
│ • SSL 종료 │
│ • 요청/응답 수정 가능 │
│ • A/B 테스트, 카나리 배포 │
│ │
│ 단점: │
│ • L4보다 느림 (패킷 분석 필요) │
│ • 더 많은 리소스 사용 │
│ • HTTP/HTTPS에 한정 │
│ │
│ 예시: AWS ALB, Nginx, HAProxy (HTTP mode), Envoy │
│ │
└─────────────────────────────────────────────────────────────────┘
2.3 비교 요약¶
| 항목 | L4 로드 밸런서 | L7 로드 밸런서 |
|---|---|---|
| OSI 계층 | 4 (Transport) | 7 (Application) |
| 분석 대상 | IP, Port | HTTP 헤더, URL, 쿠키 등 |
| 프로토콜 | TCP, UDP | HTTP, HTTPS, WebSocket |
| 속도 | 매우 빠름 | 빠름 |
| 리소스 | 적음 | 많음 |
| 기능 | 단순 분배 | 스마트 라우팅, SSL, 캐싱 |
| 사용 예 | 게임 서버, DNS, 내부 통신 | 웹 서비스, API |
3. 분배 알고리즘¶
3.1 Round Robin¶
┌─────────────────────────────────────────────────────────────────┐
│ Round Robin │
├─────────────────────────────────────────────────────────────────┤
│ │
│ "순서대로 돌아가며 분배" │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Request 1 ──▶ Server A │ │
│ │ Request 2 ──▶ Server B │ │
│ │ Request 3 ──▶ Server C │ │
│ │ Request 4 ──▶ Server A (순환) │ │
│ │ Request 5 ──▶ Server B │ │
│ │ Request 6 ──▶ Server C │ │
│ │ ... │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 장점: │
│ • 구현이 간단 │
│ • 상태 저장 불필요 │
│ • 균등 분배 (동일 성능 서버) │
│ │
│ 단점: │
│ • 서버 성능 차이 미고려 │
│ • 연결 지속 시간 미고려 │
│ │
│ 적합: 서버 성능이 동일하고, 요청 처리 시간이 비슷한 경우 │
│ │
└─────────────────────────────────────────────────────────────────┘
3.2 Weighted Round Robin¶
┌─────────────────────────────────────────────────────────────────┐
│ Weighted Round Robin │
├─────────────────────────────────────────────────────────────────┤
│ │
│ "서버 성능에 따라 가중치 부여" │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Server A: Weight 5 (고성능) │ │
│ │ Server B: Weight 3 (중성능) │ │
│ │ Server C: Weight 2 (저성능) │ │
│ │ │ │
│ │ 10개 요청 분배: │ │
│ │ A A A A A B B B C C │ │
│ │ ▲─────────▲─────▲─▲ │ │
│ │ 5개 3개 2개 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 적합: 서버 성능이 다를 때, 새 서버 점진적 투입 (canary) │
│ │
└─────────────────────────────────────────────────────────────────┘
3.3 Least Connections¶
┌─────────────────────────────────────────────────────────────────┐
│ Least Connections │
├─────────────────────────────────────────────────────────────────┤
│ │
│ "현재 연결이 가장 적은 서버에 분배" │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 현재 상태: │ │
│ │ Server A: 5 connections │ │
│ │ Server B: 3 connections ◀── 새 요청 할당 │ │
│ │ Server C: 7 connections │ │
│ │ │ │
│ │ 새 요청 후: │ │
│ │ Server A: 5 connections │ │
│ │ Server B: 4 connections │ │
│ │ Server C: 7 connections │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ Weighted Least Connections: │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ (연결 수 / 가중치)가 가장 작은 서버에 할당 │ │
│ │ │ │
│ │ Server A: 5 conn / weight 5 = 1.0 │ │
│ │ Server B: 3 conn / weight 2 = 1.5 │ │
│ │ Server C: 4 conn / weight 3 = 1.33 │ │
│ │ │ │
│ │ → Server A에 할당 (1.0이 가장 작음) │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 장점: │
│ • 동적 부하 분산 │
│ • 처리 시간이 다른 요청에 효과적 │
│ │
│ 적합: 요청 처리 시간이 다양할 때, 장기 연결 (WebSocket) │
│ │
└─────────────────────────────────────────────────────────────────┘
3.4 IP Hash¶
┌─────────────────────────────────────────────────────────────────┐
│ IP Hash │
├─────────────────────────────────────────────────────────────────┤
│ │
│ "클라이언트 IP를 해시하여 항상 같은 서버로" │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ hash(Client IP) % 서버 수 = 서버 인덱스 │ │
│ │ │ │
│ │ Client 203.0.113.50: │ │
│ │ hash(203.0.113.50) = 12345 │ │
│ │ 12345 % 3 = 0 ──▶ Server A │ │
│ │ │ │
│ │ Client 198.51.100.25: │ │
│ │ hash(198.51.100.25) = 67890 │ │
│ │ 67890 % 3 = 1 ──▶ Server B │ │
│ │ │ │
│ │ ※ 같은 IP는 항상 같은 서버! │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 장점: │
│ • Sticky Session 없이도 같은 서버 보장 │
│ • 캐시 효율성 (같은 사용자 = 같은 서버 캐시) │
│ │
│ 단점: │
│ • 서버 추가/제거 시 많은 사용자 재분배 │
│ • NAT 환경에서 불균형 (같은 공인 IP) │
│ │
│ 대안: Consistent Hashing (서버 변경 시 영향 최소화) │
│ │
└─────────────────────────────────────────────────────────────────┘
3.5 알고리즘 비교 요약¶
| 알고리즘 | 동작 | 장점 | 단점 | 사용 사례 |
|---|---|---|---|---|
| Round Robin | 순차 분배 | 단순, 균등 | 성능 차이 무시 | 동일 서버 |
| Weighted RR | 가중치 분배 | 성능 반영 | 정적 가중치 | 다양한 서버 |
| Least Conn | 최소 연결 | 동적 분산 | 상태 추적 필요 | 긴 연결 |
| IP Hash | IP 해시 | 일관성 | 불균형 가능 | 세션 유지 |
4. Sticky Session¶
4.1 Sticky Session이란?¶
┌─────────────────────────────────────────────────────────────────┐
│ Sticky Session │
├─────────────────────────────────────────────────────────────────┤
│ │
│ "같은 사용자의 요청을 항상 같은 서버로" │
│ │
│ 문제 상황 (Sticky Session 없이): │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ User ──Request 1──▶ Server A (로그인, 세션 생성) │ │
│ │ User ──Request 2──▶ Server B (세션 없음? 로그아웃!) │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 해결 (Sticky Session): │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ User ──Request 1──▶ Server A (세션 생성) │ │
│ │ User ──Request 2──▶ Server A (같은 서버!) │ │
│ │ User ──Request 3──▶ Server A (같은 서버!) │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────┐ │ │
│ │ │ Load Balancer │ │ │
│ │ │ User A → Server A (Cookie/IP 기반) │ │ │
│ │ │ User B → Server B │ │ │
│ │ │ User C → Server A │ │ │
│ │ └─────────────────────────────────────────┘ │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
4.2 Sticky Session 구현 방법¶
┌─────────────────────────────────────────────────────────────────┐
│ Sticky Session 구현 방법 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. Cookie 기반 │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 첫 요청: │ │
│ │ Client ──────────▶ LB ──────────▶ Server A │ │
│ │ ◀────────── ◀────────── │ │
│ │ Set-Cookie: SERVERID=server-a │ │
│ │ │ │
│ │ 이후 요청: │ │
│ │ Client ──────────▶ LB (Cookie 확인) ──▶ Server A │ │
│ │ Cookie: SERVERID=server-a │ │
│ │ │ │
│ │ 장점: 가장 일반적, 안정적 │ │
│ │ 단점: 쿠키 비활성화 시 동작 안 함 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 2. Source IP 기반 │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Client IP 203.0.113.50 → 항상 Server A │ │
│ │ Client IP 198.51.100.25 → 항상 Server B │ │
│ │ │ │
│ │ 장점: 쿠키 불필요 │ │
│ │ 단점: NAT, 프록시 환경에서 문제 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 3. Application Cookie (세션 ID) │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 앱에서 생성한 세션 ID (JSESSIONID 등) 활용 │ │
│ │ Cookie: JSESSIONID=abc123 → hash(abc123) → Server A │ │
│ │ │ │
│ │ 장점: 앱 세션과 일치 │ │
│ │ 단점: 첫 요청 시 쿠키 없음 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
4.3 Sticky Session의 문제점¶
┌─────────────────────────────────────────────────────────────────┐
│ Sticky Session 문제점과 대안 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 문제점: │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 1. 부하 불균형 │ │
│ │ 특정 서버에 "무거운" 사용자가 몰릴 수 있음 │ │
│ │ │ │
│ │ 2. 장애 시 세션 손실 │ │
│ │ 서버 다운 → 해당 서버의 모든 사용자 세션 손실 │ │
│ │ │ │
│ │ 3. Auto Scaling 어려움 │ │
│ │ 서버 추가/제거 시 사용자 재분배 필요 │ │
│ │ │ │
│ │ 4. 수평 확장 제한 │ │
│ │ Stateful 아키텍처의 한계 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 대안 (Stateless 아키텍처): │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 1. 외부 세션 저장소 (Redis, Memcached) │ │
│ │ 모든 서버가 같은 세션 데이터에 접근 │ │
│ │ │ │
│ │ 2. JWT (JSON Web Token) │ │
│ │ 세션 정보를 토큰에 포함, 서버 저장 불필요 │ │
│ │ │ │
│ │ 3. 데이터베이스 세션 │ │
│ │ 세션을 DB에 저장 (느리지만 확실) │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
5. 헬스 체크¶
5.1 헬스 체크란?¶
┌─────────────────────────────────────────────────────────────────┐
│ 헬스 체크 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ "서버 상태를 주기적으로 확인하여 장애 감지" │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Load Balancer │ │
│ │ │ │ │
│ │ ┌──────────┼──────────┐ │ │
│ │ │ │ │ │ │
│ │ ▼ ▼ ▼ │ │
│ │ Server A Server B Server C │ │
│ │ ✓ ✓ ✗ (장애) │ │
│ │ │ │
│ │ 트래픽 분배: A, B만 (C 제외) │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 주기적으로: │
│ 1. 헬스 체크 요청 전송 │
│ 2. 응답 확인 │
│ 3. 실패 횟수 누적 │
│ 4. 임계값 초과 시 서버 제외 │
│ 5. 복구 시 다시 포함 │
│ │
└─────────────────────────────────────────────────────────────────┘
5.2 Active vs Passive 헬스 체크¶
┌─────────────────────────────────────────────────────────────────┐
│ Active vs Passive 헬스 체크 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Active Health Check (능동적) │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ LB가 주기적으로 서버에 요청 전송 │ │
│ │ │ │
│ │ ┌──────┐ GET /health ┌──────┐ │ │
│ │ │ LB │ ───────────────▶│Server│ │ │
│ │ │ │ ◀───────────────│ │ │ │
│ │ └──────┘ 200 OK └──────┘ │ │
│ │ │ │
│ │ 설정 예: │ │
│ │ • 간격: 10초 │ │
│ │ • 타임아웃: 5초 │ │
│ │ • 실패 임계값: 3회 │ │
│ │ • 복구 임계값: 2회 │ │
│ │ │ │
│ │ 장점: 트래픽 없이도 장애 감지 │ │
│ │ 단점: 추가 부하, 네트워크 트래픽 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ Passive Health Check (수동적) │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 실제 요청의 응답을 모니터링 │ │
│ │ │ │
│ │ Client ──▶ LB ──▶ Server │ │
│ │ │ │ │
│ │ ┌───────┴───────┐ │ │
│ │ │ 5xx 에러? │ │ │
│ │ │ 타임아웃? │ │ │
│ │ │ 연결 실패? │ │ │
│ │ └───────────────┘ │ │
│ │ │ │ │
│ │ 실패 카운트 증가 │ │
│ │ │ │
│ │ 장점: 추가 트래픽 없음, 실제 상황 반영 │ │
│ │ 단점: 실제 사용자가 에러 경험 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 권장: Active + Passive 조합 │
│ │
└─────────────────────────────────────────────────────────────────┘
5.3 헬스 체크 엔드포인트 설계¶
┌─────────────────────────────────────────────────────────────────┐
│ 헬스 체크 엔드포인트 설계 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. 단순 헬스 체크 │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ GET /health │ │
│ │ │ │
│ │ Response: 200 OK │ │
│ │ { "status": "healthy" } │ │
│ │ │ │
│ │ 용도: 프로세스 생존 확인 │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 2. 상세 헬스 체크 │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ GET /health/details │ │
│ │ │ │
│ │ Response: │ │
│ │ { │ │
│ │ "status": "healthy", │ │
│ │ "version": "1.2.3", │ │
│ │ "uptime": "3d 5h 20m", │ │
│ │ "dependencies": { │ │
│ │ "database": "healthy", │ │
│ │ "redis": "healthy", │ │
│ │ "external_api": "degraded" │ │
│ │ } │ │
│ │ } │ │
│ │ │ │
│ │ 용도: 디버깅, 모니터링 대시보드 │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 3. Readiness vs Liveness (Kubernetes) │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Liveness: 프로세스가 살아있는가? │ │
│ │ GET /health/live │ │
│ │ 실패 시: 컨테이너 재시작 │ │
│ │ │ │
│ │ Readiness: 트래픽 받을 준비가 되었는가? │ │
│ │ GET /health/ready │ │
│ │ 실패 시: 트래픽 제외 (재시작 안 함) │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
6. 고가용성 구성¶
6.1 Active-Passive (Hot Standby)¶
┌─────────────────────────────────────────────────────────────────┐
│ Active-Passive 구성 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ "하나가 죽으면 대기 중인 다른 하나가 인수" │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 정상 상태: │ │
│ │ │ │
│ │ Clients ──▶ VIP (10.0.0.100) ──▶ LB Primary (Active) │ │
│ │ │ │ │
│ │ │ Heartbeat │ │
│ │ ▼ │ │
│ │ LB Secondary (Standby) │ │
│ │ │ │
│ │ 장애 발생 시: │ │
│ │ │ │
│ │ Clients ──▶ VIP (10.0.0.100) ──▶ LB Primary (Down!) │ │
│ │ │ │ │
│ │ │ VIP 인수 (Failover) │ │
│ │ ▼ │ │
│ │ LB Secondary (Active) │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 구현: VRRP, Keepalived, Pacemaker │
│ 장점: 간단, 리소스 효율 (Standby는 대기만) │
│ 단점: Standby 리소스 낭비, 전환 시 짧은 다운타임 │
│ │
└─────────────────────────────────────────────────────────────────┘
6.2 Active-Active¶
┌─────────────────────────────────────────────────────────────────┐
│ Active-Active 구성 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ "두 로드밸런서가 동시에 트래픽 처리" │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ DNS │ │
│ │ │ │ │
│ │ ┌──────────┴──────────┐ │ │
│ │ │ │ │ │
│ │ ▼ ▼ │ │
│ │ LB 1 (Active) LB 2 (Active) │ │
│ │ VIP: 10.0.0.100 VIP: 10.0.0.101 │ │
│ │ │ │ │ │
│ │ └──────────┬──────────┘ │ │
│ │ │ │ │
│ │ ┌──────────┼──────────┐ │ │
│ │ ▼ ▼ ▼ │ │
│ │ Server 1 Server 2 Server 3 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 장애 시: │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ LB 1 (Down!) ──▶ DNS에서 제거 또는 │ │
│ │ LB 2가 VIP 인수 │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 장점: 리소스 100% 활용, 더 높은 처리량 │
│ 단점: 구성 복잡, 상태 동기화 필요 │
│ │
└─────────────────────────────────────────────────────────────────┘
6.3 클라우드 로드밸런서¶
┌─────────────────────────────────────────────────────────────────┐
│ 클라우드 로드밸런서 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ AWS: │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ • ALB (Application Load Balancer) - L7 │ │
│ │ URL/호스트 기반 라우팅, WebSocket, HTTP/2 │ │
│ │ │ │
│ │ • NLB (Network Load Balancer) - L4 │ │
│ │ 초저지연, 고정 IP, TCP/UDP │ │
│ │ │ │
│ │ • CLB (Classic Load Balancer) - L4/L7 (레거시) │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ GCP: │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ • HTTP(S) Load Balancer - L7, 글로벌 │ │
│ │ • TCP/UDP Load Balancer - L4, 리전별 │ │
│ │ • Internal Load Balancer - 내부 트래픽 │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 장점: │
│ • 관리형 서비스 (운영 부담 감소) │
│ • 자동 확장, 고가용성 내장 │
│ • Auto Scaling과 통합 │
│ • 보안 기능 (WAF, DDoS 방어) │
│ │
└─────────────────────────────────────────────────────────────────┘
7. 연습 문제¶
문제 1: 로드밸런서 선택¶
다음 시나리오에 적합한 로드밸런서 유형(L4/L7)을 선택하고 이유를 설명하세요.
a) 마이크로서비스 간 gRPC 통신 b) 다국어 웹사이트 (URL: /ko/, /en/, /jp/) c) 실시간 게임 서버 d) API 게이트웨이
문제 2: 분배 알고리즘 선택¶
다음 상황에 가장 적합한 분배 알고리즘을 선택하세요.
a) 모든 서버가 동일한 스펙, 요청 처리 시간 비슷 b) WebSocket 기반 채팅 서비스 c) 새 서버를 점진적으로 투입 (canary) d) 서버 측 캐싱을 활용하는 서비스
문제 3: 헬스 체크 설계¶
전자상거래 서비스의 헬스 체크 엔드포인트를 설계하세요.
조건: - 데이터베이스, Redis, 결제 API 의존 - Kubernetes 환경 - 빠른 장애 감지 필요
문제 4: 아키텍처 설계¶
일일 1억 요청을 처리하는 서비스의 로드밸런서 아키텍처를 설계하세요.
조건: - 글로벌 사용자 (아시아, 북미, 유럽) - 99.99% 가용성 요구 - 비용 최적화
정답¶
문제 1 정답¶
a) gRPC 통신: L4 (NLB)
- gRPC는 HTTP/2 기반이지만 L4에서 충분
- 낮은 지연, 높은 처리량
b) 다국어 웹사이트: L7 (ALB)
- URL 기반 라우팅 필요 (/ko → 한국어 서버)
- 호스트 헤더 분석
c) 게임 서버: L4 (NLB)
- UDP 지원 필요
- 최소 지연 중요
- TCP/UDP 게임 프로토콜
d) API 게이트웨이: L7 (ALB)
- URL/헤더 기반 라우팅
- 인증, Rate Limiting
- SSL 종료
문제 2 정답¶
a) Round Robin
- 서버 동일, 요청 비슷 → 단순 순환이 효율적
b) Least Connections
- WebSocket은 장기 연결
- 연결 수 기반 분배가 부하 분산에 효과적
c) Weighted Round Robin
- 새 서버에 낮은 가중치 (예: 10%)
- 점진적으로 가중치 증가
d) IP Hash 또는 Consistent Hashing
- 같은 사용자 → 같은 서버 → 캐시 히트율 증가
문제 3 정답¶
// GET /health/ready (Readiness)
{
"status": "healthy",
"checks": {
"database": {
"status": "healthy",
"latency_ms": 5
},
"redis": {
"status": "healthy",
"latency_ms": 1
},
"payment_api": {
"status": "healthy",
"latency_ms": 50
}
}
}
// GET /health/live (Liveness)
{ "status": "healthy" }
설정:
- Readiness: 간격 5초, 실패 임계값 2, 복구 임계값 1
- Liveness: 간격 10초, 실패 임계값 3
Readiness 실패 시: 트래픽 제외 (결제 등 의존성 문제)
Liveness 실패 시: 컨테이너 재시작
문제 4 정답¶
아키텍처:
1. 글로벌 로드밸런싱 (DNS)
- AWS Route 53 / Cloudflare (Latency-based)
- 아시아 → 서울 리전
- 북미 → 버지니아 리전
- 유럽 → 프랑크푸르트 리전
2. 리전별 구성:
┌─────────────────────────────────┐
│ CDN (CloudFront/Cloudflare) │ ← 정적 컨텐츠
└─────────────────────────────────┘
│
┌─────────────────────────────────┐
│ L7 Load Balancer (ALB) │ ← URL 라우팅
│ - Auto Scaling │
│ - WAF 연동 │
└─────────────────────────────────┘
│
┌─────────────────────────────────┐
│ Application Servers │
│ (Auto Scaling Group) │
└─────────────────────────────────┘
3. 가용성 확보:
- 다중 가용영역 (AZ) 배포
- 헬스 체크: Active + Passive
- Cross-Zone Load Balancing 활성화
4. 비용 최적화:
- Reserved Instances (예약 인스턴스)
- CDN으로 Origin 부하 감소
- 리전별 트래픽 패턴에 따라 Auto Scaling
8. 다음 단계¶
로드 밸런싱을 이해했다면, 리버스 프록시와 API 게이트웨이를 학습하세요.
다음 레슨¶
관련 레슨¶
- 02_Scalability_Basics.md - Stateless 아키텍처
- 07_Distributed_Cache_Systems.md - 세션 저장소
추천 실습¶
- Nginx로 로드밸런서 구성해보기
- HAProxy 설정 실습
- AWS ALB/NLB 비교 테스트
9. 참고 자료¶
도구¶
문서¶
온라인 자료¶
문서 정보 - 최종 수정: 2024년 - 난이도: ⭐⭐⭐ - 예상 학습 시간: 2-3시간