본문 바로가기

로드 밸런서

L4와 L7 로드 밸런서의 라우팅 기준을 비교하고 분산 알고리즘·헬스 체크·세션 유지 방식을 설계합니다.

서비스의 사용자가 늘어나면, 하나의 서버로는 모든 요청을 처리할 수 없습니다.

서버를 여러 대로 확장(Scale Out)하면, 들어오는 요청을 어떤 기준으로 어떤 서버에 보낼지 결정해야 합니다.

이 역할을 하는 것이 로드 밸런서(Load Balancer)입니다.


L4 vs L7 로드 밸런서

로드 밸런서는 동작하는 계층에 따라 두 종류로 나뉩니다.

L4 로드 밸런서는 전송 계층(TCP/UDP)에서 동작합니다.

IP 주소, 포트, 프로토콜 같은 연결/흐름 정보를 기준으로 트래픽을 분배하고, HTTP 헤더나 URL 경로는 해석하지 않습니다.

HTTP 내용 분석을 생략할 수 있지만 실제 지연·처리량은 구현과 설정·부하에 따라 달라집니다.

AWS의 NLB(Network Load Balancer)가 대표적입니다.

L7 로드 밸런서는 애플리케이션 계층(HTTP)에서 동작합니다.

HTTP 헤더, URL 경로, 쿠키 등을 분석하여 라우팅 결정을 내립니다.

/api/* 요청은 API 서버 그룹으로, /static/* 요청은 정적 파일 서버 그룹으로 보내는 것이 가능합니다.

HTTPS 트래픽에서 URL이나 헤더를 기준으로 라우팅하려면 보통 로드 밸런서에서 TLS를 종료하고, 필요하면 백엔드로 다시 TLS를 연결합니다.

HTTPS 경로를 고르려면, L7 진입점에서 TLS를 종료합니다

클라이언트가 L7 진입점으로 HTTPS 요청을 보냅니다. 해당 요청을 API 서버 그룹으로 보냅니다. 각 단계의 값과 전환 이유를 비교합니다.

로드 밸런서 · HTTPS 경로 라우팅

HTTPS 경로를 고르려면, L7 진입점에서 TLS를 종료합니다

이 예는 /api/*와 /static/*을 서로 다른 서버 그룹으로 보냅니다. L4 흐름 정보만으로는 HTTP 경로를 읽지 않으며, TLS 종단 뒤 백엔드 구간의 TLS는 별도로 설정합니다.

TLS 종단 뒤 HTTP 경로를 해석하는 L7 라우팅클라이언트 TLS는 로드 밸런서에서 끝나며 경로가 api이면 API 그룹, static이면 정적 그룹으로 보낸다. 백엔드 TLS는 별도 설정이다.클라이언트HTTPS 요청L7 로드 밸런서TLS 종단 · 경로 해석/api/*API 서버 그룹/static/*정적 서버 그룹TLS
TLS 종단 뒤 HTTP 경로를 해석하는 L7 라우팅클라이언트 TLS는 로드 밸런서에서 끝나며 경로가 api이면 API 그룹, static이면 정적 그룹으로 보낸다. 백엔드 TLS는 별도 설정이다.클라이언트HTTPS 요청L7 로드 밸런서TLS 종단경로 해석/api/*API 서버 그룹/static/*정적 서버 그룹TLS

청록색은 클라이언트→로드 밸런서의 TLS 구간입니다. 회색은 그룹을 고르는 라우팅 관계이며 평문 전송을 강제하지 않습니다. 각 그룹 안의 대상 선택·헬스 체크·drain과 응답 경로는 생략했습니다.

이 예의 조건

  • 본문과 전체 도표의 예를 따라 HTTPS 요청부터 그룹 전달까지 진행합니다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
HTTPS 요청

클라이언트가 L7 진입점으로 HTTPS 요청을 보냅니다.

  • TLS·요청 경로 1: client→L7 TLS
  • TLS·요청 경로 2: /api/*
  • 클라이언트와 진입점 사이 TLS 구간
종단과 해석

진입점이 TLS를 종료하고 HTTP 경로를 읽습니다.

  • TLS·요청 경로 1: L7 path=/api/*
  • 복호화한 /api/*로 경로 판단; L4 정보만으로는 읽을 수 없음
그룹 전달

해당 요청을 API 서버 그룹으로 보냅니다.

  • TLS·요청 경로 1: /api/*→API
  • TLS·요청 경로 2: /static/*→정적은 대안
  • 백엔드 TLS는 별도 선택; 회색 전달선이 평문을 강제하지 않음

HTTPS 경로를 고르려면, L7 진입점에서 TLS를 종료합니다

클라이언트가 L7 진입점으로 HTTPS 요청을 보냅니다. 해당 요청을 API 서버 그룹으로 보냅니다. 각 단계의 값과 전환 이유를 비교합니다.

로드 밸런서 · HTTPS 경로 라우팅

HTTPS 경로를 고르려면, L7 진입점에서 TLS를 종료합니다

이 예는 /api/*와 /static/*을 서로 다른 서버 그룹으로 보냅니다. L4 흐름 정보만으로는 HTTP 경로를 읽지 않으며, TLS 종단 뒤 백엔드 구간의 TLS는 별도로 설정합니다.

TLS 종단 뒤 HTTP 경로를 해석하는 L7 라우팅클라이언트 TLS는 로드 밸런서에서 끝나며 경로가 api이면 API 그룹, static이면 정적 그룹으로 보낸다. 백엔드 TLS는 별도 설정이다.클라이언트HTTPS 요청L7 로드 밸런서TLS 종단 · 경로 해석/api/*API 서버 그룹/static/*정적 서버 그룹TLS
TLS 종단 뒤 HTTP 경로를 해석하는 L7 라우팅클라이언트 TLS는 로드 밸런서에서 끝나며 경로가 api이면 API 그룹, static이면 정적 그룹으로 보낸다. 백엔드 TLS는 별도 설정이다.클라이언트HTTPS 요청L7 로드 밸런서TLS 종단경로 해석/api/*API 서버 그룹/static/*정적 서버 그룹TLS

청록색은 클라이언트→로드 밸런서의 TLS 구간입니다. 회색은 그룹을 고르는 라우팅 관계이며 평문 전송을 강제하지 않습니다. 각 그룹 안의 대상 선택·헬스 체크·drain과 응답 경로는 생략했습니다.

이 예의 조건

  • 본문과 전체 도표의 예를 따라 HTTPS 요청부터 그룹 전달까지 진행합니다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
HTTPS 요청

클라이언트가 L7 진입점으로 HTTPS 요청을 보냅니다.

  • TLS·요청 경로 1: client→L7 TLS
  • TLS·요청 경로 2: /api/*
  • 클라이언트와 진입점 사이 TLS 구간
종단과 해석

진입점이 TLS를 종료하고 HTTP 경로를 읽습니다.

  • TLS·요청 경로 1: L7 path=/api/*
  • 복호화한 /api/*로 경로 판단; L4 정보만으로는 읽을 수 없음
그룹 전달

해당 요청을 API 서버 그룹으로 보냅니다.

  • TLS·요청 경로 1: /api/*→API
  • TLS·요청 경로 2: /static/*→정적은 대안
  • 백엔드 TLS는 별도 선택; 회색 전달선이 평문을 강제하지 않음

AWS의 ALB(Application Load Balancer)가 대표적입니다.

구분기준과 적용 범위
L4IP·포트·TCP/UDP 흐름으로 분산합니다. TLS 패스스루 또는 종단을 지원할 수 있고, WebSocket·gRPC도 전송 연결로 다룰 수 있습니다. AWS NLB가 한 예입니다.
L7HTTP의 Host·경로·헤더·쿠키를 해석합니다. 내용 기반 HTTPS 라우팅에는 TLS 종단이 필요합니다. HTTP/2·gRPC·WebSocket 지원 범위는 제품별로 확인하며 AWS ALB가 한 예입니다.

로드 밸런싱 알고리즘

알고리즘선택 기준과 주의점
라운드 로빈순서대로 분배합니다. 동일한 요청 수가 동일한 처리 부하를 뜻하지는 않습니다.
가중 순환가중치 비율을 반영합니다. 서버 성능 변화에 맞춰 값을 관리해야 합니다.
최소 연결현재 연결 수가 적은 대상을 선택합니다. 연결별 비용 차이는 별도 문제입니다.
가중 최소 연결연결 수와 가중치를 함께 반영합니다. 항상 가장 정확한 부하 추정은 아닙니다.
IP 해시같은 IP의 대상 일관성에 유리하지만 NAT 사용자 집중과 대상 변경을 고려합니다.
랜덤무작위로 선택합니다. 적은 표본에서는 분산 편차가 클 수 있습니다.
P2C무작위 후보 두 개를 부하 지표로 비교합니다. 지표의 신선도·비용에 영향을 받습니다.

IP 해시는 “같은 IP는 같은 서버로 가게 할 가능성”을 높이지만, NAT나 모바일망처럼 여러 사용자가 같은 공인 IP를 공유하면 특정 서버에 부하가 몰릴 수 있습니다.

쿠키 기반 sticky session도 비슷하게 장애와 불균형을 같이 고려해야 합니다.

예시: 요청 수와 부하를 구분하기 서버 A와 B에 라운드 로빈으로 요청을 두 개씩 보냈다고 합시다. 각 요청의 CPU 작업량을 A에서는 100ms와 100ms, B에서는 5ms와 5ms로 가정하면, 할당한 요청 수는 같아도 작업량 합은 A 200ms·B 10ms입니다. 이 가정한 작업량 비교는 대기·병렬 실행을 포함한 실제 응답 시간 측정이 아닙니다. 최소 연결도 연결마다 작업량이 다르면 같은 한계를 가질 수 있으므로, 어떤 값을 부하의 대리 지표로 사용하는지 먼저 봅니다.


헬스 체크

헬스 체크는 보통 HTTP 요청, TCP 연결, gRPC 헬스 체크 같은 방식으로 대상 서버가 트래픽을 받을 수 있는지 확인합니다.

단, 모든 헬스 체크가 같은 의미는 아닙니다.

liveness는 프로세스가 죽었는지 확인하는 얕은 체크에 가깝고, readiness는 지금 트래픽을 받아도 되는지 확인하는 체크입니다.

DB 연결 같은 의존성 검사는 readiness에는 유용하지만, liveness에 과하게 넣으면 일시적인 DB 장애가 전체 서버 재시작으로 번질 수 있습니다.

health_endpoint.py
# Flask 헬스 체크 엔드포인트 예: live와 ready를 분리
from flask import Flask, jsonify
import psycopg2

app = Flask(__name__)

@app.route("/live")
def live():
    return jsonify({"status": "alive"}), 200

@app.route("/ready")
def ready():
    checks = {"status": "ready"}
    try:
        conn = psycopg2.connect("dbname=mydb user=app")
        conn.close()
        checks["database"] = "ok"
    except Exception:
        checks["database"] = "fail"
        checks["status"] = "unhealthy"
        return jsonify(checks), 503

    return jsonify(checks), 200

이 코드는 Flask 엔드포인트를 정의하며 서버를 실행하는 명령은 포함하지 않습니다. /ready의 성공은 DB 연결·종료가 예외 없이 끝났다는 범위이고 쿼리 정확성이나 모든 요청의 성공을 보장하지 않습니다. 명시적인 DB 연결 시간 제한도 없습니다.

체크 결과로 할 조치를 나누기 위 코드에서 /live는 200을 반환하지만, /ready의 DB 연결 단계에서는 예외가 발생했다고 합시다. 프로세스가 응답할 수 있다는 판단과 새 업무 요청을 받을 준비가 됐다는 판단은 각각 무엇인가요? 이 두 결과만으로 프로세스를 즉시 재시작해야 한다고 결론 내릴 수 있는지도 생각해 보세요.

체크의 범위에 맞춘 풀이

/live는 이 엔드포인트가 응답하고 있다는 얕은 증거입니다. /ready는 예외 경로에서 database=fail, status=unhealthy, HTTP 503을 반환하므로 지정한 DB 연결 준비 검사는 실패했습니다. 준비 실패를 새 요청의 대상 제외에 연결할 수 있지만, 실제 제외 시점은 아래의 임계값과 정책에 달려 있습니다. DB 장애가 원인일 수 있으므로 이 두 결과만으로 재시작이 해법이라고 판단하지 않습니다. 모든 대상이 실패할 때도 무조건 전달이 차단된다고 가정하지 않고 제품의 fail-open 정책을 확인합니다.

로드 밸런서는 설정된 시간 제한·주기·성공/실패 임계값으로 대상을 판단합니다.

탐지 지연과 진행 중인 요청 때문에 무중단 전환이 보장되지는 않습니다. 모든 대상이 비정상일 때의 동작도 제품별로 다르며, AWS ALB는 이 경우 비정상 대상에도 전달하는 fail-open 동작을 정의합니다.

배포 시 대상 등록 해제와 drain은 헬스 체크 실패 판정과 별도입니다. 새 요청 중단과 기존 연결의 종료·완료 대기를 구분해 조정합니다.


Sticky Session과 세션 공유

세션 기반 인증에서 사용자의 세션이 서버 A의 메모리에 저장되어 있다면, 다음 요청이 서버 B로 가면 로그인 상태가 유지되지 않습니다.

상태 관리장애·확장 시 고려할 점
Sticky session같은 대상에 붙이는 정책입니다. 서버 메모리 상태는 장애 때 소실될 수 있고 대상별 부하가 불균등해질 수 있습니다.
Redis 공유여러 서버가 같은 세션을 읽습니다. Redis의 가용성·복제·일관성 운영이 필요합니다.
JWT서버 교체의 영향을 줄일 수 있지만 만료·폐기·키 회전과 별도 애플리케이션 상태 설계가 필요합니다.

서버 메모리에 사용자 상태를 묶지 않으려면 외부 세션 저장소나 토큰 기반 인증을 검토합니다. Sticky session도 요구에 맞는 선택일 수 있으므로 장애 시 상태와 부하 분포를 기준으로 결정합니다.

로드 밸런서는 단순히 “요청을 나누는 장비”가 아니라, TLS 종료 지점, 장애 감지 기준, 세션 상태, 배포 중 drain 전략까지 함께 결정하는 운영 경계입니다.

다음 절에서는 로드 밸런서와 함께 자주 등장하는 프록시와 VPN을 다루겠습니다.