Infra Architecture/Network Fundamentals

Network Fundamentals - 10. 로드 밸런싱

한 건물에 들어온 손님을 여러 창구로 안내하는 기술 — 로드 밸런싱

2017년 2월 28일 AWS S3 장애 당시 — 한 리전의 모든 요청이 몰리면서 AWS의 로드 밸런서(ELB)가 한계에 달했다. 정상 상태에서는 로드 밸런서가 수백 개의 백엔드 인스턴스에 트래픽을 골고루 분산하지만 — 백엔드가 줄어들면 한 인스턴스에 몰리는 트래픽이 증폭한다. "분산"의 이점이 사라지는 순간. 이 사건이 보여주는 것은 — 로드 밸런싱이 인프라의 중간 역할이라는 점이다. 클라이언트와 서버 사이에서 — 트래픽을 받고, 여러 서버에 나눠주고, 건강한 서버만 골라내는 역할. 이 역할이 제대로 안 되면 — foundations 03에서 본 연쇄 장애(cascading failure)가 시작된다.

이 글은 로드 밸런싱(load balancing) 을 다룬다. 여러 서버에 트래픽을 분산하는 기술. L4(포트 기반)와 L7(HTTP 경로 기반) 로드 밸런서의 차이, 분산 알고리즘(round-robin·least-connections·consistent hash), 헬스체크가 "트래픽을 어디로 보낼까?"를 어떻게 결정하는지. foundations 04에서 본 redundancy·active-active의 구체 실천이 — 로드 밸런서를 통해 이루어진다.

로드 밸런서란 — 트래픽을 나누는 중간자

로드 밸런서(load balancer) 는 — 클라이언트와 여러 서버 사이에 위치해, 들어오는 트래픽을 여러 서버에 분산(distribute) 시키는 장치 또는 소프트웨어다. 비유하자면 — 병원 접수 창구. 환자(클라이언트)가 오면 — 접수 담당자(로드 밸런서)가 "1번 창구 비었네, 거기로 가세요"라고 안내한다. 한 의사(서버)에게 환자가 몰리지 않게 골고루 분배하는 것.

로드 밸런서가 해결하는 세 가지 문제:

  1. 확장성(scalability) — 한 서버가 감당 못 하는 트래픽을 여러 서버로 분산. 서버를 추가하면 처리량이 늘어난다(수평 확장).
  2. 고가용성(availability) — 한 서버가 죽어도 로드 밸런서가 나머지 서버로 트래픽을 우회. foundations 04에서 본 active-active 패턴의 실천.
  3. 유연성(flexibility) — 서버 교체·업데이트 시 로드 밸런서가 그 서버를 순차적으로 빼고 넣는다(blue-green 배포·카나리 배포).
flowchart LR
    CLIENT[클라이언트들] --> LB[로드 밸런서]
    LB --> S1["서버 1<br/>(정상)"]
    LB --> S2["서버 2<br/>(정상)"]
    LB -.->|"헬스체크 실패"| S3["서버 3<br/>(장애 — 트래픽 안 보냄)"]
    LB --> S4["서버 4<br/>(정상)"]

L4 vs L7 — 어디까지 "열어보고" 분배하나

로드 밸런서는 처리하는 계층에 따라 두 종류로 나뉜다. foundations 01의 OSI 글에서 "L4 로드 밸런서는 포트까지, L7은 HTTP 내용까지 본다"고 맛보기로 소개했다. 여기서 깊이 본다.

L4 로드 밸런서 (전송 계층)

L4 로드 밸런서는 — TCP/UDP 계층(L4)에서 동작한다. 5-tuple(출발지 IP·목적지 IP·프로토콜·출발지 포트·목적지 포트)을 보고 트래픽을 분산한다. HTTP 요청의 내용(URL·헤더·쿠키)은 열어보지 않는다 — 포트 번호까지만 본다.

장점 — 빠르다. HTTP 내용을 파싱할 필요가 없으니, 패킷만 보고 빠르게 결정한다. L7보다 처리량이 높다. 단점 — 분배가 정밀하지 않다. "이 사용자는 항상 서버 A로" 같은 쿠키 기반 세션 고정이 어렵다. HTTP 내용을 안 보니까.

전형 사례 — AWS NLB(Network Load Balancer), HAProxy(L4 모드), LVS(Linux Virtual Server), F5 BIG-IP.

L7 로드 밸런서 (응용 계층)

L7 로드 밸런서는 — HTTP 계층(L7)에서 동작한다. HTTP 요청의 URL·헤더·쿠키·본문을 검사해서 분배한다. "/api/* 요청은 서버 A로, /static/* 요청은 CDN으로" 같은 정교한 분배가 가능하다.

장점 — 정밀한 분배. URL 경로별·호스트명별·쿠키 기반 분배. 단점 — 느리다. 모든 요청을 L7까지 파싱해야 하니까. 또한 — TLS 종단(TLS termination) 역할을 하려면 인증서를 로드 밸런서에 설치해야 한다.

전형 사례 — AWS ALB(Application Load Balancer), nginx(리버스 프록시), HAProxy(L7 모드), Envoy, Traefik.

특성 L4 로드 밸런서 L7 로드 밸런서
보는 계층 L4 (포트·IP) L7 (HTTP URL·헤더·쿠키)
분배 기준 5-tuple URL 경로, Host, 쿠키
속도 빠름 상대적으로 느림
정밀도 낮음 높음
TLS 종단 일부 지원 기본 지원
세션 고정 IP 기반(source affinity) 쿠키 기반(sticky session)
전형 사례 AWS NLB, LVS AWS ALB, nginx, Envoy

분산 알고리즘 — 트래픽을 어떻게 나눌까

로드 밸런서가 "이 요청을 어느 서버로?"를 결정하는 규칙이 분산 알고리즘(load balancing algorithm) 이다. 주요 알고리즘을 본다.

1. Round Robin (라운드 로빈) — 서버 1 → 2 → 3 → 1 → 2 → 3, 돌아가며 분배. 가장 단순. 모든 서버가 같은 사양이면 공정하다. 단점 — 서버마다 처리 속도가 다르면(서버 1이 느리면) — 서버 1에 요청이 몰려 지연. 또한 — 각 요청의 처리 비용이 다르면(무거운 요청이 서버 1에 연속해서 가면) — 불균형.

2. Least Connections (최소 연결) — 현재 활성 연결 수가 가장 적은 서버로 보낸다. 처리가 느린 서버는 연결이 쌓이니까 — 자동으로 덜 보내진다. 서버 사양이 다른 환경에서 round-robin보다 공정하다. HAProxy·nginx의 기본 알고리즘.

3. Source IP Hash (출발지 IP 해시) — 클라이언트의 출발지 IP를 해시해서 — 항상 같은 서버로 보낸다. 세션 어피니티(session affinity, sticky session) 를 만드는 알고리즘. "이 사용자는 항상 서버 A로" — 세션 상태가 서버에 저장돼 있을 때 필요하다. 단점 — 클라이언트 IP가 바뀌면(모바일 네트워크 전환 등) 다른 서버로 갈 수 있다.

4. Consistent Hash (일관적 해시) — source IP hash와 비슷하지만 — 서버가 추가·삭제될 때 매핑이 크게 안 바뀌는 해시 알고리즘. foundations 05에서 맛보기로 본 일관적 해시. 서버 4대에서 5대로 늘리면 — 일반 해시는 전체 매핑이 바뀌지만(5로 나눔), 일관적 해시는 추가된 서버만 담당이 바뀐다. 캐시 서버(Redis·Memcached) 분배에 자주 쓰인다.

5. Weighted Round Robin / Weighted Least Connections — 서버마다 가중치(weight) 를 준다. 서버 A(성능 좋음, weight=5)와 서버 B(성능 낮음, weight=1)가 있으면 — A에 5배 더 많이 보낸다. 서버 사양이 다른 환경에서 유용하다.

알고리즘 방식 장점 단점 전형 사례
Round Robin 돌아가며 단순 서버 사양 무시 같은 사양 서버
Least Connections 연결 수 최소 서버 자동 균형 계산 오버헤드 HAProxy, nginx 기본
Source IP Hash IP 해시 세션 유지 IP 변경 시 매핑 변경 sticky session
Consistent Hash 일관적 해시 서버 추가/삭제 영향 최소 약간 불균형 캐시 분배
Weighted 가중치 사양별 분배 가중치 수동 설정 혼합 사양

헬스체크 — 건강한 서버에게만 보낸다

로드 밸런서의 또 다른 핵심 기능이 헬스체크(health check) 다. 각 서버가 정상 동작하는지 주기적으로 검사하고 — 비정상 서버에는 트래픽을 보내지 않는다(우회, routing around). foundations 04에서 본 MTTR을 줄이는 핵심 메커니즘.

헬스체크의 두 축:

  • 주기(interval) — 얼마나 자주 검사하는가. 5초, 10초, 30초.
  • 임계값(threshold) — 몇 번 연속 실패해야 비정상으로 판정하는가. 보통 2 ~ 3회.

헬스체크의 종류:

유형 검사 방법 정확도 속도
TCP 체크 TCP 연결 성공 = 정상 낮음 (포트만 열려 있으면 OK) 빠름
HTTP 체크 HTTP 요청(GET /health) → 200 OK 높음 (앱까지 확인) 중간
커스텀 체크 앱 고유 엔드포인트(DB 연결 등 확인) 매우 높음 느림

헬스체크 엔드포인트의 설계가 중요하다. /health가 단순히 "200 OK"만 반환하면 — 앱이 떠 있지만 DB 연결이 끊긴 상태를 못 잡는다. 좋은 헬스체크는 — DB·캐시·외부 API 의존성까지 확인하고, 하나라도 문제가 있으면 503(Service Unavailable)을 반환한다. 단, 너무 엄격하면 — 일시적 외부 장애에도 서버가 빠져서 "cascade failover"(전체 서버가 헬스체크 실패로 빠지는 현상)가 일어날 수 있다. 적절한 균형이 필요하다.

세션 어피니티 — 같은 사용자를 같은 서버로

세션 어피니티(session affinity, sticky session) 는 — 같은 클라이언트의 요청을 항상 같은 서버로 보내는 기능이다. 세션 상태(session state)가 서버 로컬에 저장돼 있을 때 필요하다 — 서버 A에 로그인 세션이 있는데 서버 B로 가면, 서버 B는 그 세션을 모르니까 로그아웃된다.

세션 어피니티를 만드는 방법:

  • IP 기반(source IP affinity) — 클라이언트 IP를 해시해서 서버를 결정. L4에서 가능. 단점 — NAT 뒤의 여러 사용자가 같은 IP로 보일 수 있음(회사 네트워크).
  • 쿠키 기반(sticky cookie) — 로드 밸런서가 첫 요청에 쿠키(SERVERID=server1)를 식입하고, 이후 요청은 쿠키를 보고 같은 서버로. L7에서 가능. AWS ALB의 "sticky sessions"이 이 방식.
  • 세션 외부화 — 세션 상태를 서버 로컬이 아니라 외부 저장소(Redis·DynamoDB)에 두면 — 세션 어피니티 자체가 불필요. 어느 서버로 가든 외부 저장소에서 세션을 읽는다. 이게 현대 마이크로서비스의 정답이다 — 세션을 외부화하면 서버가 언제든 교체 가능해진다(immutable infrastructure와 정합).
방식 계층 장점 단점
IP affinity L4 단순 NAT 뒤 중복, IP 변경 시 매핑 깨짐
Cookie sticky L7 정확 L7 LB 필요, 쿠키 오버헤드
세션 외부화 서버 교체 자유, 가장 유연 외부 저장소(Redis 등) 필요

DSR — 서버가 직접 클라이언트에게 응답

DSR(Direct Server Return) 은 — 로드 밸런서가 요청만 서버로 전달하고, 서버의 응답은 로드 밸런서를 거치지 않고 클라이언트에게 직접 보내는 기술이다. 응답 트래픽(보통 요청보다 큼 — 웹 페이지·이미지·비디오)이 로드 밸런서를 안 거치니 — 로드 밸런서의 부하가 크게 줄어든다.

DSR의 원리 — 서버가 응답 패킷의 출발지 IP를 로드 밸런서의 IP(VIP)로 설정한다. 클라이언트는 응답이 로드 밸런서에게서 온 것으로 보이지만 — 실제로는 서버가 직접 보낸 것이다. 구현이 복잡하지만(서버의 네트워크 설정이 필요) — 대용량 응답(비디오 스트리밍·대용량 파일 다운로드)에서 로드 밸런서 병목을 없애는 데 효과적이다.

로드 밸런서 자체의 HA — 로드 밸런서가 죽으면?

로드 밸런서가 SPOF(단일 장애점)가 되는 걸 막으려면 — 로드 밸런서 자체를 이중화해야 한다. 두 로드 밸런서가 active-active 또는 active-passive로 묶이고, VRRP(Virtual Router Redundancy Protocol)keepalived로 하나가 죽으면 다른 하나가 VIP(Virtual IP)를 인계받는다. AWS ELB는 내부적으로 이중화돼 있어서 — 사용자는 신경 안 써도 된다. 자체 구축 로드 밸런서(HAProxy·nginx)는 이중화를 직접 설정해야 한다.

TLS 종단 — 로드 밸런서에서 암호화를 끝낼까, 서버까지 가져갈까

HTTPS 트래픽을 로드 밸런서가 처리할 때 — TLS 암호화 해독(TLS termination)을 어디서 할지 결정해야 한다. 두 가지 방식이 있다.

TLS 종단(TLS termination) — 로드 밸런서가 TLS를 해독하고, 백엔드 서버에게는 평문(HTTP)으로 전달. 로드 밸런서에 인증서를 설치해야 한다. 장점은 — 백엔드 서버가 암호화 연산 부담을 덜고, 로드 밸런서가 HTTP 헤더(URL·쿠키)를 검사해서 L7 분배를 할 수 있다. 단점은 — 로드 밸런서와 서버 사이가 평문이므로, 내부 네트워크를 신뢰할 수 있어야 한다. AWS ALB가 이 방식.

TLS 통과(TLS passthrough) — 로드 밸런서가 암호화된 트래픽을 그대로 백엔드 서버로 전달. 서버가 TLS를 해독. 장점은 — 종단 간(end-to-end) 암호화, 내부 네트워크가 신뢰할 수 없어도 안전. 단점은 — 로드 밸런서가 HTTP 내용을 못 보니 L7 분배가 안 됨(L4만 가능). 또한 — 각 서버에 인증서를 설치해야 함. AWS NLB의 TLS 리스너가 이 방식.

특성 TLS 종단 (termination) TLS 통과 (passthrough)
암호화 해독 위치 로드 밸런서 백엔드 서버
L7 분배 가능 (HTTP 검사) 불가능 (L4만)
서버 부담 낮음 (암호화 안 함) 높음 (각자 암호화)
보안 LB-서버 간 평문 종단 간 암호화
인증서 위치 로드 밸런서 각 서버

연결 드레이닝 — 서버를 부드럽게 빼는 기술

서버를 업데이트하거나 교체할 때 — 갑자기 트래픽을 끊으면 — 처리 중인 요청이 실패한다. 연결 드레이닝(connection draining) 또는 우아한 종료(graceful shutdown) 은 — 서버를 로테이션에서 천천히 빼는 기술이다.

과정: (1) 로드 밸런서가 해당 서버를 "새 요청 안 보냄" 상태로 표시. (2) 이미 진행 중인 연결은 완료될 때까지 기다림. (3) 모든 연결이 끝나면 — 서버를 완전히 제거.

AWS ELB의 "deregistration delay"(기본 300초)가 이 역할. Kubernetes의 terminationGracePeriodSeconds(기본 30초)도 같은 개념. 드레이닝 시간 동안 — 진행 중인 요청이 안전하게 끝나고, 새 요청은 다른 서버로 간다.

로드 밸런서와 배포 전략

로드 밸런서는 배포 전략(deployment strategy) 의 핵심 도구다. foundations 05에서 본 패턴들을 로드 밸런서로 실천한다.

블루-그린 배포(blue-green) — 두 환경(블루=현재 버전, 그린=새 버전)을 둔다. 로드 밸런서가 블루를 가리키다가 — 새 버전 배포 후 그린으로 전환(switch). 문제가 생기면 블루로 즉시 롤백. 로드 밸런서의 타겟 그룹(target group)을 바꾸는 것만으로 전환이 끝난다.

카나리 배포(canary) — 새 버전을 소수 서버(예: 10%)에만 배포. 로드 밸런서가 전체 트래픽의 10%만 새 버전으로 보낸다. 에러율·지연을 모니터링하면서 점진적으로 비율을 높인다(10% → 25% → 50% → 100%). 문제가 생기면 즉시 0%로 되돌린다. AWS ALB의 가중치 기반 타겟 그룹(weighted target groups)이 이 패턴을 지원한다.

글로벌 로드 밸런싱 — DNS 기반 부하 분산

지금까지 본 로드 밸런서는 — 하나의 데이터센터(리전) 안에서 트래픽을 분산했다. 하지만 글로벌 서비스는 — 여러 리전(서울·도쿄·버지니아)에 서버를 두고 — 사용자에게 가장 가까운 리전으로 보내야 한다. 이걸 글로벌 로드 밸런싱(global load balancing) 이라 부른다.

방식은 두 가지:

  • DNS 기반 — DNS 해석 시 사용자의 위치(재귀 서버의 IP로 추정)를 보고 — 가장 가까운 리전의 IP를 반환. AWS Route 53의 "지연 기반 라우팅(latency-based routing)"·Cloudflare의 Argo가 이 방식.
  • Anycast — 여러 리전이 같은 IP 주소를 광고하고, BGP 라우팅이 자연스럽게 가장 가까운 리전으로 패킷을 보내는 기술. Cloudflare·Google·AWS Global Accelerator가 Anycast를 쓴다.

Anycast가 DNS 기반보다 빠르다 — DNS 캐싱 지연이 없고, BGP가 실시간으로 라우팅하니까. 하지만 — Anycast는 BGP 제어가 필요해서 자체 구축이 어렵다. 클라우드의 관리형 서비스(AWS Global Accelerator·Cloudflare)를 쓰는 게 일반적이다.

실습 — 로드 밸런싱 상태 직접 확인

1. nginx 업스트림(백엔드 서버) 상태

# nginx upstream 서버 상태 (stub_status 모듈)
curl -s http://localhost/nginx_status 2>/dev/null | head -5
# 또는 upstream 블록에서 설정한 백엔드
grep -A 5 'upstream' /etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf 2>/dev/null | head -15

확인할 것: max_failsfail_timeout 설정. backup 표시가 있으면 — 장애 시에만 사용되는 예비 서버.

2. HAProxy 통계 페이지

# HAProxy 통계 (설정된 경우)
curl -s http://localhost:8404/stats 2>/dev/null | head -20 || echo "HAProxy stats 미설정"

확인할 것: 각 백엔드 서버의 STATUS(UP/DOWN), CUR(현재 연결 수), RATE(요청 속도). DOWN이면 — 헬스체크 실패.

3. 로드 밸런서의 헬스체크 로직 확인

# nginx에서 헬스체크 설정 확인
grep -E 'health_check|proxy_next_upstream|max_fails|fail_timeout' /etc/nginx/*.conf /etc/nginx/conf.d/*.conf 2>/dev/null
# 또는 HAProxy
grep -E 'check|inter|fall|rise' /etc/haproxy/haproxy.cfg 2>/dev/null | head -10

확인할 것: inter(체크 주기), fall(연속 실패 횟수), rise(연속 성공 횟수). 예: inter 5s fall 3 rise 2 = 5초마다 체크, 3번 실패 시 DOWN, 2번 성공 시 UP으로 복귀.

4. AWS ALB/NLB 상태 (클라우드 환경)

# ALB의 대상 그룹(Target Group) 헬스 상태
aws elbv2 describe-target-health --target-group-arn <ARN> --query 'TargetHealthDescriptions[*].[Target.Id,TargetHealth.State]' --output table 2>/dev/null || echo "AWS CLI 미설정"

확인할 것: 각 인스턴스의 Statehealthy인지 unhealthy인지. unhealthy이면 — 헬스체크가 실패하고 있다는 뜻.

미검증: nginx status 모듈은 별도 설정(stub_status) 필요. HAProxy 통계 페이지는 별도 설정(listen 8404) 필요. AWS CLI는 자격증명이 설정된 환경에서만 동작.

판단 표 — 로드 밸런서 선택

환경 권장 로드 밸런서 이유
단순 HTTP 서비스 AWS ALB 또는 nginx L7 기능(URL 분배), 관리형이 편리
TCP/UDP 서비스 (DB, 게임) AWS NLB 또는 HAProxy(L4) L4 분배, 낮은 지연
매우 높은 처리량 L4 + DSR 응답이 LB를 안 거침
Kubernetes 클러스터 Ingress Controller (nginx/Envoy/Traefik) K8s 통합, 선언적 설정
마이크로서비스 Service Mesh(Istio/Linkerd) 또는 API Gateway L7 + 트래픽 제어 + 관측성
비용 최소화 nginx 오픈소스 무료, 충분한 기능
관리 편의성 우선 AWS ALB/NLB 또는 GCP Load Balancer 관리형, 자동 확장

로드 밸런싱은 "분산"과 "우회"의 기술이다

도입의 AWS S3 장애로 돌아가자. 로드 밸런서는 정상일 때 — 트래픽을 골고루 분산하고(fair distribution). 장애가 났을 때 — 건강한 서버만 골라서 트래픽을 보내고(failover). 두 역할 모두 — foundations 04에서 본 redundancy의 실천이다. 로드 밸런서가 없으면 — 여러 서버를 둬도 트래픽이 한 곳에 몰리고, 장애 서버에 계속 요청을 보낸다.

이것으로 network fundamentals 영역이 끝난다. OSI 7계층에서 시작해 — L2(이더넷·VLAN)→ L3(IP·라우팅) → L4(TCP·UDP·혼잡 제어) → L7(DNS·HTTP·TLS·로드 밸런싱)까지. 패킷이 물리 케이블에서 출발해 — 브라우저 화면에 도달하는 전체 경로를 다뤘다. 다음 영역은 datacenter and cloud — 물리 시설(전력·냉각)에서 클라우드 네이티브까지. 인프라가 모이는 곳, 데이터센터와 클라우드를 본다.

로드 밸런서 vs 서비스 메시 — 현대의 분산

마이크로서비스 환경에서는 — 로드 밸런서 외에 서비스 메시(service mesh) 가 또 다른 부하 분산 계층이 된다. Istio·Linkerd 같은 서비스 메시는 — 각 서비스(Pod)에 사이드카 프록시(Envoy) 를 두고 — 서비스 간 트래픽을 분산한다. 전통적 로드 밸런서가 "외부 → 클러스터" 입구를 담당한다면 — 서비스 메시는 "클러스터 내부 — 서비스 간" 트래픽을 담당한다.

계층 역할 전형 도구
글로벌 LB 리전 간 분산 Route 53, Cloudflare, Global Accelerator
외부 LB 인터넷 → 클러스터 AWS ALB, nginx, HAProxy
서비스 메시 클러스터 내부 — 서비스 간 Istio, Linkerd, Consul Connect
클라이언트 LB 클라이언트가 직접 분산 gRPC client-side LB, Ribbon

현대 클라우드 네이티브 환경은 — 이 네 계층이 겹쳐서 동작한다. 어느 계층에서 분산하느냐가 — 아키텍처 설계의 핵심 질문이다.
로드 밸런싱은 — "분산"과 "우회"의 기술이다. 정상일 때는 트래픽을 골고루 분산하고, 장애 시에는 건강한 서버만 골라서 보낸다. foundations 04의 redundancy를 실천하는 핵심 메커니즘이다. 로드 밸런서가 없으면 — 여러 서버를 둬도 트래픽이 한 곳에 몰리고, 장애 서버에 계속 요청을 보낸다.


참고

  • AWS, "Elastic Load Balancing Documentation" — ALB/NLB/CLB 공식 문서. 접근 2026-07-21
  • HAProxy, "HAProxy Configuration Manual" — L4/L7 로드 밸런싱 실무. 접근 2026-07-21. URL: https://docs.haproxy.org/
  • nginx, "Using nginx as HTTP load balancer" — nginx 로드 밸런싱 가이드. 접근 2026-07-21
  • Karger, D. et al. "Consistent Hashing and Random Trees", MIT 1997 — 일관적 해시 원논문. 접근 2026-07-21
  • Fox, A., Gribble, S. et al. "Cluster-Based Scalable Network Services", SOSP 1997 — 로드 밸런싱 분산 시스템. 접근 2026-07-21
  • Kurose, J. F., Ross, K. W. 8th ed, 2021, Ch.2·Ch.6 — 로드 밸런싱. 접근 2026-07-21
  • Bird, M. , O'Reilly, 2023 — HAProxy 실전. 접근 2026-07-21