웹 인프라 - CDN, 로드밸런서, Gateway API, 웹서버의 역할과 헤더 기반 트래픽 분기
한 문장 요약
CDN → 로드밸런서 → Gateway API → 웹서버 순으로 요청이 흐르며, 각 계층은 “어디서”, “어떻게”, “누구에게” 전달할지를 나눠서 담당한다.
🗺️ 전체 구조도
사용자 브라우저
│
│ HTTPS 요청 (example.com/page)
▼
┌─────────────────────────────────────────────┐
│ CDN (엣지 서버) │
│ - 지리적으로 가장 가까운 노드 │
│ - 정적 자원(이미지, JS, CSS) 캐시 응답 │
│ - 캐시 미스 시 → Origin으로 전달 │
└───────────────────┬─────────────────────────┘
│ Origin 요청
▼
┌─────────────────────────────────────────────┐
│ 로드밸런서 (L4/L7) │
│ - 여러 서버에 요청을 분산 │
│ - 서버 헬스 체크 │
│ - IP/포트(L4) 또는 URL/헤더(L7) 기반 분배 │
└───────────────────┬─────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ Gateway API (API 게이트웨이) │
│ - 인증/인가 처리 │
│ - 라우팅 규칙 (헤더, 경로, 메서드 기반) │
│ - 트래픽 분기 (A/B 테스트, 카나리 배포) │
│ - 속도 제한(Rate Limiting), 로깅 │
└────────┬──────────────────────┬─────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────────┐
│ 웹서버 A (안정) │ │ 웹서버 B (실험/신버전) │
│ Nginx / Apache │ │ Nginx / Node.js │
│ 정적/동적 응답 │ │ 정적/동적 응답 │
└─────────────────┘ └─────────────────────┘
1. 각 구성 요소의 역할
CDN (Content Delivery Network) - 콘텐츠 배달망
“사용자와 가장 가까운 곳에서 대신 응답한다”
서울 사용자 ──→ 서울 CDN 엣지 (즉시 응답)
뉴욕 사용자 ──→ 뉴욕 CDN 엣지 (즉시 응답)
↕ 캐시 만료 시에만 Origin 서버에 요청
Origin 서버 (한국)
| 항목 | 설명 |
|---|---|
| 주 역할 | 정적 콘텐츠 캐싱 및 지리적 분산 배포 |
| 처리 대상 | 이미지, CSS, JS, HTML (캐시 가능한 자원) |
| 핵심 이점 | 지연 시간 단축, Origin 서버 부하 감소 |
| 대표 서비스 | Cloudflare, AWS CloudFront, Akamai |
CDN은 요청을 가로채는 첫 번째 관문이다. 정적 자원은 여기서 끝나고, 동적 요청만 뒤로 전달된다.
로드밸런서 (Load Balancer) - 부하 분산기
“같은 일을 하는 여러 서버에 요청을 나눠준다”
┌──→ 웹서버 1 (처리 중: 30%)
요청 ──→ 로드밸런서 ├──→ 웹서버 2 (처리 중: 25%)
└──→ 웹서버 3 (처리 중: 45%)
L4 vs L7 로드밸런서
| 구분 | L4 (Transport Layer) | L7 (Application Layer) |
|---|---|---|
| 기준 | IP 주소, TCP/UDP 포트 | HTTP 헤더, URL 경로, 쿠키 |
| 속도 | 빠름 (패킷 수준) | 상대적으로 느림 (내용 해석) |
| 지능 | 낮음 | 높음 |
| 용도 | 단순 부하 분산 | 경로별 분기, 헤더 기반 라우팅 |
분산 알고리즘 종류:
Round Robin : 서버 1 → 서버 2 → 서버 3 → 서버 1 ...
Least Connection: 현재 연결 수가 가장 적은 서버로
IP Hash : 같은 사용자는 항상 같은 서버로 (세션 유지)
Weighted : 성능 좋은 서버에 더 많은 요청 배분
Gateway API - API 게이트웨이
“요청의 내용을 보고 어디로 보낼지 결정하는 관문”
┌──→ /api/user → 사용자 서비스
├──→ /api/order → 주문 서비스
요청 ──→ Gateway API ────┤
├──→ 헤더: X-Beta: true → 베타 서버
└──→ 그 외 → 일반 서버
Gateway API가 하는 일:
| 기능 | 설명 |
|---|---|
| 라우팅 | URL 경로, HTTP 메서드, 헤더 값에 따라 백엔드 선택 |
| 인증/인가 | JWT 토큰 검증, API 키 확인 |
| Rate Limiting | 초당 요청 수 제한 |
| 변환 | 요청/응답 헤더 추가·수정·삭제 |
| 트래픽 분기 | A/B 테스트, 카나리 배포, 블루-그린 배포 |
| 로깅 | 모든 API 요청 기록 |
로드밸런서 vs Gateway API의 차이
- 로드밸런서: “같은 서비스의 여러 인스턴스에 분산”
- Gateway API: “요청의 의미를 보고 적합한 서비스 자체를 선택”
웹서버 (Web Server) - 최종 응답자
“실제 HTML, JSON 등을 생성해서 돌려보낸다”
요청 도착
│
├── 정적 파일 요청 (/images/logo.png)
│ └── 파일 시스템에서 직접 읽어 응답
│
└── 동적 요청 (/api/products)
└── 애플리케이션 서버(Node.js, Django 등)에 전달
└── DB 조회 → 응답 생성 → 반환
| 소프트웨어 | 특징 |
|---|---|
| Nginx | 정적 파일, 리버스 프록시에 강점. 이벤트 기반으로 고성능 |
| Apache | 모듈 기반, 설정 유연성 높음 |
| Node.js (자체) | JavaScript 런타임이 직접 서버 역할 |
2. 계층 관계 요약
┌────────────────────────────────────────────────────────┐
│ 계층 역할 핵심 질문 │
├────────────────────────────────────────────────────────┤
│ CDN 캐싱/배포 "캐시가 있나? 가까운 노드?" │
│ 로드밸런서 부하 분산 "어느 인스턴스로 보낼까?" │
│ Gateway 라우팅/정책 "어느 서비스로 보낼까?" │
│ 웹서버 응답 생성 "실제 데이터를 돌려준다" │
└────────────────────────────────────────────────────────┘
이 네 계층은 항상 순서대로 존재하지 않는다. 소규모 서비스는 웹서버 하나로 모든 것을 처리하고, 대규모 서비스일수록 계층이 추가된다.
3. 헤더 기반 트래픽 분기 - 같은 URL, 다른 페이지
현대 인프라에서 A/B 테스트와 실험 플랫폼이 동작하는 원리
동작 원리
사용자 A (일반) 사용자 B (실험군)
│ │
│ GET /home │ GET /home
│ Cookie: session=abc123 │ Cookie: session=xyz789
│ (실험군 아님) │ (실험군으로 분류됨)
▼ ▼
┌─────────────────── Gateway API / L7 로드밸런서 ───────────────────┐
│ │
│ 헤더/쿠키 분석: │
│ if (X-Experiment-Group == "B" || Cookie.experiment == "new_ui") │
│ → 실험 서버로 라우팅 │
│ else │
│ → 기존 서버로 라우팅 │
└──────────────┬─────────────────────────────┬─────────────────────┘
│ │
▼ ▼
기존 서버 (A) 실험 서버 (B)
/home → 기존 UI /home → 새 UI
URL은 같지만 다른 응답을 받는 이유: 라우팅이 URL이 아니라 HTTP 헤더 값을 기준으로 결정되기 때문이다. 헤더 기반 트래픽 분기
- Gateway API 또는 L7 로드밸런서가 요청 헤더(X-Experiment-Group, Cookie 등)를 읽어 라우팅 결정
- 사용자는 동일한 URL 사용, 인프라 계층이 자동으로 구분자 삽입
- A/B 테스트, 카나리 배포, 블루-그린 배포 모두 이 원리 활용
- Kubernetes Gateway API YAML 예시 포함
헤더 구분자의 종류
헤더에 넣는 구분자는 시스템마다 다르게 정한다. 대표적인 방식:
# 방법 1: 커스텀 HTTP 헤더
X-User-Group: beta
X-Experiment-ID: exp_2026_new_home
X-Feature-Flag: new_checkout_flow
# 방법 2: 쿠키 활용
Cookie: ab_test=variant_b; experiment=new_ui
# 방법 3: 사용자 에이전트
User-Agent: Mozilla/5.0 ... (모바일 사용자 분기)
# 방법 4: 지역 정보 (CDN이 추가)
CF-IPCountry: KR
X-Forwarded-For: 203.0.113.1헤더 구분자가 붙는 시점
사용자 요청 (헤더 없음)
│
▼
CDN 엣지 서버
│── 국가 코드, IP 정보 헤더 추가 (CF-IPCountry 등)
│
▼
로드밸런서 / Gateway
│── 사용자 ID 해시 계산 → 실험군 분류
│── X-Experiment-Group: A 또는 B 헤더 추가
│── 헤더 값에 따라 백엔드 결정
│
▼
실험 서버 또는 기존 서버
사용자가 직접 헤더를 붙이지 않아도 된다. 인프라 계층(CDN, Gateway)이 중간에서 자동으로 구분자를 삽입하고 라우팅한다.
실제 사용 사례
A/B 테스트 (UI 실험)
전체 트래픽의 50%: 새 홈페이지 디자인 (B 버전)
나머지 50%: 기존 홈페이지 (A 버전)
→ 클릭률, 전환율 비교
카나리 배포 (Canary Deployment)
전체 트래픽의 5%만 새 버전 서버로
→ 문제 발생 시 즉시 5% → 0%로 롤백
→ 안전하면 점진적으로 10% → 50% → 100%
블루-그린 배포 (Blue-Green Deployment)
Blue (현재 운영): 100% 트래픽 수신
Green (새 버전): 배포 완료 후 대기
→ 순간 전환: 트래픽을 Green으로 100% 이동
→ 문제 시 Blue로 즉시 복구
Kubernetes Gateway API 예시 (실제 설정)
# 헤더 값에 따라 트래픽을 분기하는 HTTPRoute 설정
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: experiment-routing
spec:
rules:
# 실험군 (X-Experiment: beta 헤더가 있는 경우)
- matches:
- headers:
- name: X-Experiment
value: beta
backendRefs:
- name: web-server-beta
port: 80
# 대조군 (기본 라우팅)
- backendRefs:
- name: web-server-stable
port: 80같은 URL(/)로 들어와도 X-Experiment: beta 헤더가 있는 요청은 베타 서버로, 없는 요청은 안정 서버로 분기된다.
4. 전체 흐름 시나리오
시나리오: 실험 플랫폼에서 새 홈페이지를 50% 사용자에게 노출
① 사용자가 브라우저에서 example.com 접속
② CDN 엣지 서버 도달
- 정적 자원(이미지, CSS)은 캐시에서 즉시 반환
- HTML 요청은 Origin으로 전달
- CF-IPCountry: KR 헤더 추가
③ L7 로드밸런서 도달
- 여러 Gateway 인스턴스 중 하나에 분배
④ Gateway API 도달
- 사용자 ID(쿠키에서 추출) 해시 → 짝수: 그룹 A, 홀수: 그룹 B
- X-AB-Group: B 헤더를 요청에 추가
- 헤더 기반으로 라우팅 결정:
- 그룹 A → 웹서버 클러스터 A (기존 UI)
- 그룹 B → 웹서버 클러스터 B (새 UI)
⑤ 웹서버 도달
- 동일한 URL /home 요청 처리
- 그러나 클러스터 A와 B는 서로 다른 HTML 응답 생성
⑥ 사용자에게 반환
- 그룹 A: 기존 홈페이지 렌더링
- 그룹 B: 새 홈페이지 렌더링
- URL은 동일하게 example.com
5. 정리: 한 눈에 보기
| 구성 요소 | 위치 | 핵심 역할 | 판단 기준 |
|---|---|---|---|
| CDN | 사용자와 가장 가까운 엣지 | 캐싱, 지연 시간 단축 | 캐시 유무, 지리적 거리 |
| 로드밸런서 | Origin 진입점 | 트래픽 분산, 고가용성 | IP, 포트, 서버 부하 |
| Gateway API | 서비스 진입점 | 라우팅, 인증, 실험 분기 | URL, 헤더, 쿠키, 메서드 |
| 웹서버 | 최종 서비스 | 실제 응답 생성 | 비즈니스 로직, DB 조회 |
헤더 기반 트래픽 분기는 Gateway API 또는 L7 로드밸런서가 담당하며, 같은 URL로 접속해도 헤더 값에 따라 완전히 다른 서버의 응답을 받을 수 있다. 이것이 현대 실험 플랫폼, A/B 테스트, 카나리 배포의 핵심 원리다.