한양과학기술고등학교

에듀테크 프로젝트 대시보드

로드 밸런싱

로드 밸런싱 (Load Balancing)

한 대의 서버로는 감당이 안 될 때 — 요청을 여러 서버에 공평하게 나눠주는 기술

인기 있는 웹사이트에는 1초에 수천, 수만 개의 요청이 쏟아진다. 서버 한 대의 CPU와 메모리로는 절대 감당할 수 없다. 그래서 똑같은 앱을 여러 대의 서버에 복제해 놓고, 그 앞에 로드 밸런서(LB)를 세운다. 사용자는 로드 밸런서 하나의 주소만 알면 되고, LB가 알아서 "지금 덜 바쁜 서버"로 요청을 넘겨준다.

비유하자면 은행 입구의 번호표 기계 + 안내 직원이다. 손님(요청)은 창구가 몇 개인지 신경 쓸 필요 없이 번호표만 뽑으면, 안내 직원(LB)이 "3번 창구 비었습니다" 하고 보내준다.

① 직접 굴려보는 로드 밸런서

알고리즘을 바꿔가며 요청 보내기를 눌러보자. 서버 이름을 클릭하면 그 서버를 다운시킬 수 있다 (헬스 체크로 LB가 감지해 자동으로 제외한다). 가중치가 있는 서버는 ×2 로 표시된다.

🧑‍💻 클라이언트
203.0.113.7
⚖️ Load Balancer
Round Robin
offset0xf.com
0보낸 요청
0처리 완료
0실패(전 서버 다운)
—편차(최대−최소)

② 대표적인 분배 알고리즘

알고리즘동작 방식장점 / 단점
Round Robin서버 목록을 1 → 2 → 3 → 1 … 순서대로 돌아가며 배정구현이 단순하고 균등. 단, 서버 성능이 제각각이거나 요청 처리 시간이 들쭉날쭉하면 불균형
Weighted RR성능 좋은 서버에 가중치(예: 2)를 줘 그만큼 더 자주 배정서버 스펙이 다를 때 유용. 가중치를 손으로 정해야 함
Least Connections현재 처리 중인 연결이 가장 적은 서버로 보냄요청 길이가 불규칙할 때 효과적. LB가 연결 상태를 계속 추적해야 함
IP Hashhash(클라이언트 IP) % 서버수 로 항상 같은 서버에 배정세션 고정(스티키)에 유리. 특정 IP에 트래픽이 몰리면 불균형, 서버 수가 바뀌면 매핑이 흔들림
Random / P2C무작위로 하나 고르거나, 둘을 뽑아 덜 바쁜 쪽 선택("Power of Two Choices")상태 추적이 거의 없어 가볍고, P2C는 놀랍도록 균등

③ L4 vs L7 — 어느 계층에서 나누나

L4 (전송 계층)

IP 주소와 포트만 보고 TCP/UDP 패킷을 그대로 전달한다. 내용은 안 열어봐서 아주 빠르고 처리량이 크다. 대신 "URL이 /api 로 시작하면 API 서버로" 같은 판단은 못 한다.

L7 (응용 계층)

HTTP 요청을 실제로 파싱해서 경로·헤더·쿠키·호스트명을 보고 라우팅한다. 경로별 분배, 스티키 세션(쿠키), TLS 종료, 압축, 캐싱까지 가능. Nginx·HAProxy·ALB가 여기 속한다.

④ 헬스 체크와 무중단

LB는 주기적으로 각 서버에 GET /health 같은 요청을 보낸다. 응답이 없거나 5xx가 몇 번 연속되면 그 서버를 풀에서 뺀다(위 데모의 "다운"). 살아나면 다시 넣는다.

덕분에 배포할 때 서버를 한 대씩 빼서 새 버전으로 교체하고 다시 넣는 롤링 업데이트가 가능하다 — 사용자는 서비스 중단을 느끼지 못한다.

스티키 세션의 함정: 로그인 정보를 특정 서버 메모리에만 저장하면, 그 사용자는 계속 같은 서버로 가야 한다(IP Hash/쿠키). 그 서버가 죽으면 로그인이 풀린다. 그래서 요즘은 세션을 Redis 같은 공용 저장소나 JWT로 빼서 "아무 서버나 처리 가능한(stateless)" 구조로 만든다.

⑤ 이 서버(offset0xf.com)의 Nginx도 사실 L7 프록시다

지금 이 사이트는 서버 1대라 "분배"는 안 하지만, Nginx가 요청을 받아 Gunicorn으로 넘기는 구조 자체가 L7 리버스 프록시다. 서버를 늘린다면 upstream 블록에 서버만 추가하면 된다.

# /etc/nginx/sites-available/offset0xf.com
upstream school_app {
    # least_conn;  ← 연결 수 최소 방식으로 바꾸려면 주석 해제
    server 127.0.0.1:8001;              # 지금은 이 한 대
    # server 10.0.1.12:8001 weight=2;   ← 성능 좋은 2호기 (가중치 2)
    # server 10.0.1.13:8001 backup;     ← 평소엔 놀다가 장애 시 투입
}

server {
    listen 443 ssl;
    server_name offset0xf.com;

    location / {
        proxy_pass http://school_app;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_next_upstream error timeout http_502;  # 한 서버 실패 시 다음 서버로 재시도
    }
}

한 줄 정리

로드 밸런서 = "단일 진입점" 뒤에 여러 서버를 숨기고, 알고리즘(Round Robin·Least Conn·IP Hash…)으로 트래픽을 나눠 확장성과 가용성을 동시에 얻는 장치. 핵심은 서버를 stateless 하게 만드는 것.