🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

Load Balancing 실전 구현 가이드 - 슬라이드 1/13
A

AI Generated

2025. 11. 5. · 10 Views

Load Balancing 실전 구현 가이드

고가용성 시스템을 위한 Load Balancing 핵심 개념과 실전 구현 방법을 다룹니다. Nginx, HAProxy, 그리고 클라우드 환경에서의 로드 밸런싱 전략을 실제 코드로 학습합니다.


카테고리:TypeScript
언어:JavaScript
메인 태그:#LoadBalancing
서브 태그:
#Nginx#HAProxy#HighAvailability#Clustering

들어가며

이 글에서는 Load Balancing 실전 구현 가이드에 대해 상세히 알아보겠습니다. 총 12가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.

목차

  1. Round_Robin_Load_Balancer
  2. Weighted_Round_Robin
  3. Least_Connections_Algorithm
  4. Nginx_HTTP_Load_Balancing
  5. Health_Check_구현
  6. Sticky_Session_구현
  7. IP_Hash_Load_Balancing
  8. Circuit_Breaker_패턴
  9. Rate_Limiting_구현
  10. HAProxy_Configuration
  11. DNS_Round_Robin
  12. Auto_Scaling_Integration

1. Round Robin Load Balancer

개요

가장 기본적인 로드 밸런싱 알고리즘으로, 요청을 순차적으로 서버에 분배합니다. 모든 서버가 동일한 성능을 가진 경우 효과적입니다.

코드 예제

class RoundRobinBalancer {
  private servers: string[] = ['server1', 'server2', 'server3'];
  private current = 0;

  getNextServer(): string {
    const server = this.servers[this.current];
    this.current = (this.current + 1) % this.servers.length;
    return server;
  }
}

설명

current 인덱스를 사용해 서버 배열을 순회하며, 모듈로 연산으로 마지막 서버 이후 첫 번째 서버로 돌아갑니다.


2. Weighted Round Robin

개요

서버의 성능이 다를 때 사용하는 가중치 기반 라운드 로빈입니다. 성능이 좋은 서버에 더 많은 요청을 분배합니다.

코드 예제

class WeightedRoundRobin {
  private servers = [
    { name: 'server1', weight: 5, currentWeight: 0 },
    { name: 'server2', weight: 3, currentWeight: 0 }
  ];

  getNextServer(): string {
    let total = this.servers.reduce((sum, s) => sum + s.weight, 0);
    let best = this.servers.reduce((max, s) => {
      s.currentWeight += s.weight;
      return s.currentWeight > max.currentWeight ? s : max;
    });
    best.currentWeight -= total;
    return best.name;
  }
}

설명

각 서버의 현재 가중치를 누적하고, 가장 높은 가중치를 가진 서버를 선택한 후 전체 가중치만큼 차감합니다.


3. Least Connections Algorithm

개요

현재 연결 수가 가장 적은 서버로 요청을 보내는 알고리즘입니다. 요청 처리 시간이 다양한 환경에 적합합니다.

코드 예제

class LeastConnectionBalancer {
  private servers = new Map([
    ['server1', 0], ['server2', 0], ['server3', 0]
  ]);

  getNextServer(): string {
    return [...this.servers.entries()]
      .reduce((min, curr) => curr[1] < min[1] ? curr : min)[0];
  }

  incrementConnection(server: string) { this.servers.set(server, this.servers.get(server)! + 1); }
  decrementConnection(server: string) { this.servers.set(server, this.servers.get(server)! - 1); }
}

설명

Map으로 각 서버의 연결 수를 관리하고, reduce를 사용해 최소 연결 수를 가진 서버를 찾습니다.


4. Nginx HTTP Load Balancing

개요

Nginx를 사용한 HTTP 로드 밸런싱 설정입니다. upstream 블록으로 백엔드 서버 그룹을 정의합니다.

코드 예제

upstream backend {
    least_conn;
    server backend1.example.com weight=3;
    server backend2.example.com weight=2;
    server backend3.example.com backup;
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
    }
}

설명

least_conn 알고리즘 사용, weight로 가중치 설정, backup 서버 지정이 가능합니다. proxy_pass로 요청을 전달합니다.


5. Health Check 구현

개요

서버의 상태를 주기적으로 확인하여 장애 서버를 자동으로 제외합니다. 시스템 가용성을 높이는 핵심 기능입니다.

코드 예제

class HealthChecker {
  private healthStatus = new Map<string, boolean>();

  async checkHealth(server: string): Promise<boolean> {
    try {
      const response = await fetch(`http://${server}/health`, { timeout: 3000 });
      const isHealthy = response.ok;
      this.healthStatus.set(server, isHealthy);
      return isHealthy;
    } catch {
      this.healthStatus.set(server, false);
      return false;
    }
  }

  getHealthyServers(servers: string[]): string[] {
    return servers.filter(s => this.healthStatus.get(s) !== false);
  }
}

설명

각 서버의 /health 엔드포인트를 확인하고, 응답이 정상이면 healthy로 표시합니다. timeout으로 무응답 서버를 빠르게 감지합니다.


6. Sticky Session 구현

개요

특정 클라이언트의 요청을 항상 같은 서버로 전달합니다. 세션 데이터가 서버에 저장된 경우 필수적입니다.

코드 예제

class StickySessionBalancer {
  private sessionMap = new Map<string, string>();
  private servers = ['server1', 'server2', 'server3'];

  getServer(sessionId: string): string {
    if (!this.sessionMap.has(sessionId)) {
      const server = this.servers[Math.floor(Math.random() * this.servers.length)];
      this.sessionMap.set(sessionId, server);
    }
    return this.sessionMap.get(sessionId)!;
  }
}

설명

sessionId를 키로 사용하여 서버를 매핑합니다. 첫 요청 시 랜덤으로 서버를 할당하고, 이후 같은 세션은 동일 서버로 라우팅됩니다.


7. IP Hash Load Balancing

개요

클라이언트 IP 주소를 해시하여 서버를 결정합니다. 같은 IP는 항상 같은 서버로 연결되어 세션 유지가 가능합니다.

코드 예제

class IPHashBalancer {
  private servers = ['server1', 'server2', 'server3'];

  getServer(clientIP: string): string {
    const hash = this.hashCode(clientIP);
    const index = Math.abs(hash) % this.servers.length;
    return this.servers[index];
  }

  private hashCode(str: string): number {
    return str.split('').reduce((hash, char) =>
      ((hash << 5) - hash) + char.charCodeAt(0), 0);
  }
}

설명

문자열 해시 함수로 IP를 숫자로 변환하고, 서버 개수로 나눈 나머지를 인덱스로 사용합니다.


8. Circuit Breaker 패턴

개요

장애 서버로의 요청을 차단하여 연쇄 장애를 방지합니다. 일정 시간 후 자동으로 복구를 시도합니다.

코드 예제

class CircuitBreaker {
  private failures = 0;
  private state: 'CLOSED' | 'OPEN' | 'HALF_OPEN' = 'CLOSED';
  private threshold = 5;

  async call(fn: () => Promise<any>): Promise<any> {
    if (this.state === 'OPEN') throw new Error('Circuit is OPEN');

    try {
      const result = await fn();
      this.onSuccess();
      return result;
    } catch (error) {
      this.onFailure();
      throw error;
    }
  }

  private onFailure() {
    this.failures++;
    if (this.failures >= this.threshold) this.state = 'OPEN';
  }
  private onSuccess() { this.failures = 0; this.state = 'CLOSED'; }
}

설명

실패 횟수가 임계값을 초과하면 OPEN 상태로 전환하여 모든 요청을 차단합니다. 성공 시 CLOSED로 복구됩니다.


9. Rate Limiting 구현

개요

서버 과부하를 방지하기 위해 일정 시간당 요청 수를 제한합니다. Token Bucket 알고리즘을 사용합니다.

코드 예제

class RateLimiter {
  private tokens: number;
  private lastRefill: number;

  constructor(private maxTokens = 100, private refillRate = 10) {
    this.tokens = maxTokens;
    this.lastRefill = Date.now();
  }

  tryAcquire(): boolean {
    this.refill();
    if (this.tokens > 0) {
      this.tokens--;
      return true;
    }
    return false;
  }

  private refill() {
    const now = Date.now();
    const elapsed = (now - this.lastRefill) / 1000;
    this.tokens = Math.min(this.maxTokens, this.tokens + elapsed * this.refillRate);
    this.lastRefill = now;
  }
}

설명

시간에 비례하여 토큰을 충전하고, 요청마다 토큰을 소비합니다. 토큰이 없으면 요청을 거부합니다.


10. HAProxy Configuration

개요

HAProxy를 사용한 고급 로드 밸런싱 설정입니다. TCP/HTTP 모드, SSL 터미네이션, 헬스체크를 포함합니다.

코드 예제

frontend http_front
    bind *:80
    mode http
    default_backend http_back

backend http_back
    mode http
    balance leastconn
    option httpchk GET /health
    server srv1 10.0.0.1:8080 check weight 3
    server srv2 10.0.0.2:8080 check weight 2
    server srv3 10.0.0.3:8080 check backup

설명

frontend는 요청을 받는 포트, backend는 실제 서버들을 정의합니다. httpchk로 헬스체크, check로 서버 모니터링을 활성화합니다.


11. DNS Round Robin

개요

DNS 레벨에서 여러 IP를 반환하여 로드를 분산합니다. 가장 간단하지만 세밀한 제어는 어렵습니다.

코드 예제

// DNS 레코드 설정 (BIND 형식)
example.com.  IN  A  192.168.1.10
example.com.  IN  A  192.168.1.11
example.com.  IN  A  192.168.1.12

// Node.js에서 DNS 조회
import dns from 'dns';

dns.resolve4('example.com', (err, addresses) => {
  console.log(addresses); // ['192.168.1.10', '192.168.1.11', '192.168.1.12']
  const server = addresses[Math.floor(Math.random() * addresses.length)];
});

설명

DNS 서버가 여러 IP를 순환하며 반환하고, 클라이언트는 받은 IP 중 하나를 선택합니다. 캐싱 문제로 실시간 제어가 어렵습니다.


12. Auto Scaling Integration

개요

로드에 따라 서버를 자동으로 추가/제거하는 오토 스케일링과 로드 밸런서를 연동합니다.

코드 예제

class AutoScalingBalancer {
  private servers: string[] = ['server1'];
  private requestCount = 0;

  async handleRequest(req: any) {
    this.requestCount++;
    if (this.requestCount > 1000 && this.servers.length < 5) {
      await this.scaleUp();
    } else if (this.requestCount < 100 && this.servers.length > 1) {
      await this.scaleDown();
    }
    return this.getServer();
  }

  private async scaleUp() {
    const newServer = `server${this.servers.length + 1}`;
    this.servers.push(newServer);
    console.log(`Scaled up: ${newServer}`);
  }

  private async scaleDown() {
    const removed = this.servers.pop();
    console.log(`Scaled down: ${removed}`);
  }

  private getServer() { return this.servers[Math.floor(Math.random() * this.servers.length)]; }
}

설명

요청 수를 모니터링하여 임계값 초과 시 서버를 추가하고, 낮을 때는 제거합니다. 클라우드 API와 연동하여 실제 인스턴스 생성/삭제가 가능합니다.


마치며

이번 글에서는 Load Balancing 실전 구현 가이드에 대해 알아보았습니다. 총 12가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.

관련 태그

#LoadBalancing #Nginx #HAProxy #HighAvailability #Clustering

#LoadBalancing#Nginx#HAProxy#HighAvailability#Clustering#TypeScript

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.