📌 고정 게시글

📢 공지합니다

이 게시글은 메인 페이지에 항상 고정되어 표시됩니다.

최코딩의 개발

로드밸런싱(Load Balancing)의 모든 것 본문

CS

로드밸런싱(Load Balancing)의 모든 것

seung_ho_choi.s 2025. 4. 27. 23:17
728x90

로드밸런싱은 현대 웹 서비스 아키텍처에서 가장 중요한 요소 중 하나입니다. 특히 트래픽이 많은 서비스를 안정적으로 운영하기 위해서는 필수적인 기술입니다. 이 글에서는 로드밸런싱의 개념부터 구현 방법까지 상세히 알아보겠습니다.

로드밸런서(Load Balancer)란?

로드밸런서는 여러 서버에 네트워크 트래픽을 분산시키는 장치 또는 기술을 말합니다. 서비스에 접속하는 클라이언트의 요청을 여러 서버에 효율적으로 분배하여 서버의 부하를 분산시키고, 전체 시스템의 가용성과 응답 속도를 향상시키는 역할을 합니다. 

즉, 로드밸런싱은 작업이나 기술을 의미하며, 로드밸런서는 그 작업을 수행하는 구체적인 도구나 시스템입니다. 당신의 예시에서는 NGINX가 로드밸런서이고, NGINX가 트래픽을 세 개의 애플리케이션 서버에 분산시키는 과정이 로드밸런싱입니다.

로드밸런서의 주요 기능

  1. 트래픽 분산: 여러 서버에 요청을 균등하게 분배합니다.
  2. 고가용성 보장: 특정 서버에 장애가 발생해도 서비스가 중단되지 않도록 합니다.
  3. 확장성 제공: 서버를 추가하거나 제거하여 시스템의 용량을 조절할 수 있습니다.
  4. 세션 관리: 사용자 세션을 관리하여 일관된 서비스 경험을 제공합니다.
  5. 헬스 체크: 서버의 상태를 주기적으로 확인하여 장애가 발생한 서버를 자동으로 제외시킵니다.

로드밸런싱 유형

로드밸런싱은 구현 방식과 동작 계층에 따라 여러 유형으로 나뉩니다.

1. L4 로드밸런싱 (Transport Layer)

L4 로드밸런서는 네트워크 계층(IP)과 전송 계층(TCP/UDP)의 정보를 바탕으로 트래픽을 분산합니다.

  • 특징:
    • IP 주소와 포트 번호를 기반으로 로드밸런싱
    • 패킷 내용을 확인하지 않음
    • 빠른 처리 속도
    • NAT(Network Address Translation) 기반 동작
  • 사용 사례:
    • 단순한 트래픽 분산이 필요한 경우
    • 처리 속도가 중요한 서비스

2. L7 로드밸런싱 (Application Layer)

L7 로드밸런서는 애플리케이션 계층의 정보(HTTP, HTTPS, FTP 등)를 기반으로 트래픽을 분산합니다.

  • 특징:
    • URL, HTTP 헤더, 쿠키 등 애플리케이션 계층의 정보를 분석
    • 콘텐츠 기반 라우팅 가능
    • SSL 종료 및 처리 가능
    • 보안 기능 제공 (WAF 등)
  • 사용 사례:
    • URL 기반 라우팅이 필요한 서비스
    • 콘텐츠 기반 분산이 필요한 경우
    • 보안이 중요한 서비스

3. DNS 로드밸런싱

DNS 서버가 도메인에 대한 요청을 여러 IP 주소로 분산시키는 방식입니다.

  • 특징:
    • 구현이 간단하고 비용이 저렴
    • 세부적인 제어가 어려움
    • DNS 캐싱으로 인한 즉시성 부족
  • 사용 사례:
    • 지역별 서비스 분산
    • 간단한 로드밸런싱이 필요한 경우

로드밸런싱 알고리즘

로드밸런서가 요청을 분산하는 방식은 여러 알고리즘을 통해 구현됩니다.

1. 라운드 로빈(Round Robin)

요청을 순차적으로 각 서버에 분배하는 방식입니다.

  • 장점: 구현이 간단하고 모든 서버를 균등하게 사용
  • 단점: 서버의 처리 능력 차이를 고려하지 않음

2. 가중치 라운드 로빈(Weighted Round Robin)

서버의 처리 능력에 따라 가중치를 부여하여 요청을 분배합니다.

  • 장점: 서버의 처리 능력 차이를 고려할 수 있음
  • 단점: 가중치 설정이 필요하며, 동적 조정이 어려움

3. 최소 연결(Least Connection)

현재 연결이 가장 적은 서버에 요청을 분배합니다.

  • 장점: 서버의 현재 부하 상태를 고려
  • 단점: 연결 수가 처리 부하를 정확히 반영하지 못할 수 있음

4. IP 해시(IP Hash)

클라이언트의 IP 주소를 해시하여 특정 서버에 요청을 지속적으로 연결합니다.

  • 장점: 세션 유지에 유리
  • 단점: 특정 IP의 트래픽이 많을 경우 불균형 발생 가능

5. 최소 응답 시간(Least Response Time)

응답 시간이 가장 빠른 서버에 요청을 분배합니다.

  • 장점: 사용자 경험 향상
  • 단점: 지속적인 모니터링 필요

로드밸런싱 구축 방법

로드밸런싱 환경을 구축하는 방법은 다양합니다. 필요에 따라 적절한 방법을 선택할 수 있습니다.

1. 클라우드 서비스 활용

AWS ELB(Elastic Load Balancer), Google Cloud Load Balancing, Azure Load Balancer 등의 클라우드 서비스를 활용하면 쉽게 로드밸런싱 환경을 구축할 수 있습니다.

  • 장점:
    • 인프라 관리 부담 감소
    • 확장성 및 가용성 보장
    • 다양한 기능 제공
  • 단점:
    • 비용 발생
    • 커스터마이징 제한

2. NGINX를 이용한 로드밸런싱

NGINX는 웹 서버이자 리버스 프록시로, 로드밸런서 역할을 할 수 있습니다.

  • 장점:
    • 높은 성능과 안정성
    • 다양한 로드밸런싱 알고리즘 지원
    • 상세한 설정 가능
  • 단점:
    • 직접 관리 필요
    • 초기 설정의 복잡성

3. HAProxy를 이용한 로드밸런싱

HAProxy는 고성능 TCP/HTTP 로드밸런서로, 대규모 트래픽 처리에 적합합니다.

  • 장점:
    • 높은 성능
    • 상세한 트래픽 제어
    • 실시간 모니터링
  • 단점:
    • 설정의 복잡성
    • 웹 서버 기능 부재

4. Docker와 Docker Compose를 이용한 로드밸런싱

Docker와 Docker Compose를 활용하면 컨테이너 기반의 로드밸런싱 환경을 쉽게 구축할 수 있습니다.

 

로드밸런싱 구축 실습

그럼 이젠 Docker Compose로 3개의 애플리케이션 컨테이너를 띄우고, Nginx를 이용해 가장 기본적인 L7 로드밸런싱 방식과 Round-Robin 기법으로 트래픽을 분산하는 로드밸서 환경을 구축해보겠습니다.

 

 

 

본 프로젝트의 시스템 아키텍처는 위와 같다. 서버는 AWS EC2를 활용했으며, 특히 인스턴스는 프리 티어 t2.micro가 아닌, 관련 업체로부터 지원받아 t3.large를 사용하였다. 확실히 서버 스펙이 크니 성능이 훨씬 뛰어났다. 참고로 t2.micro로 서버 3대 띄우면 렉걸린다.... 

 

version: '3.8'

services:
  app1:
    image: chltmdgh522/stdev:latest
    container_name: app1
    ports:
      - "8081:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - REDIS_PASSWORD=${REDIS_PASSWORD}
    depends_on:
      - redis

  app2:
    image: chltmdgh522/stdev:latest
    container_name: app2
    ports:
      - "8082:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - REDIS_PASSWORD=${REDIS_PASSWORD}
    depends_on:
      - redis

  app3:
    image: chltmdgh522/stdev:latest
    container_name: app3
    ports:
      - "8083:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - REDIS_HOST=redis
      - REDIS_PORT=6379
      - REDIS_PASSWORD=${REDIS_PASSWORD}
    depends_on:
      - redis

  redis:
    image: redis
    container_name: redis
    command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"]
    ports:
      - "6379:6379"
    environment:
      - REDIS_PASSWORD=${REDIS_PASSWORD}

 

위와 같이 포트번호를 달리해서 3개를 띄었다. 

 

upstream backend {
    server localhost:8081 max_fails=3 fail_timeout=30s;
    server localhost:8082 max_fails=3 fail_timeout=30s;
    server localhost:8083 max_fails=3 fail_timeout=30s;

}

server {
    server_name dream.anja.p-e.kr;
    
    location / {
        proxy_pass http://backend;
        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_set_header X-Forwarded-Proto $scheme;
        
        # 연결 유지 설정
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
    
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/dream.anja.p-e.kr/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/dream.anja.p-e.kr/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = dream.anja.p-e.kr) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    listen 80;
    server_name dream.anja.p-e.kr;
    return 404; # managed by Certbot
}

 

그리고 위와 같이 nginx 구성 파일에 upstream backend 블록에서 3개 서버를 묶어서 로드밸런싱 그룹을 만들었고, proxy_pass http://backend 로 요청을 넘기도록 설정했다. 무엇보다 SSL 인증서(Certbot) 설정도 깔끔하게 처리도 했다. 

 

이때 backend_servers라는 업스트림 그룹을 정의한다. (upstream이란 강의 상류를 뜻한다. 즉 위에서 아래로 '뿌려주는' 것이다.)
요청은 backend의 8080 포트로 보내고, max_fails는 최대 실패 횟수를 정의하는 것으로 여기서는 3번 연속 요청 실패 시 해당 서버를 사용하지 않도록 한다. fail_timeouts는 서버 실패 판정 후 쿨타임으로, 30초 동안 해당 서버로 요청을 보내지 않도록 한다.(헬스 체크)

 

Nginx 로드밸런서를 활용해 keepalive로 연결을 재활용하거나, least_conn, ip_hash 같은 분산 방식을 추가할 수 있다. 또한 SSL 트래픽을 Nginx에서 처리하거나, 보안 강화를 위해 WAF 같은 모듈을 연동하는 것도 가능하다.

 

docker-compose logs -f app1 app2 app3

 

 

이거는 각각의 서버 로그를 터미널에 실시간 출력하여 볼 수 있습니다. 

 

curl -k https://도메인주소

 

이걸 여러 번 반복해서 치면 요청이 8081 → 8082 → 8083 이렇게 돌아가는 걸 확인할 수 있습니다.

 

 

추가로 JMeter를 활용해 다수의 동시 요청을 보내 로드밸런싱이 정상적으로 동작하는지 검증하였다. 이를 통해 서버 간 트래픽 분산이 제대로 이루어지는 것을 확인할 수 있었다.

728x90

'CS' 카테고리의 다른 글

Docker에 관해  (0) 2025.05.09
Spring vs Spring Boot  (0) 2025.05.07
자바의 실행 환경  (1) 2025.05.06
쿠키 VS 세션  (1) 2025.05.04
AccessToken과 RefreshToken 인증 방식  (1) 2025.04.05