데브포일 홈
WordPress 자동화
Guest
STAGE 20 · Lv.98

로드 밸런싱과 CDN 전략

로드 밸런서 설정, Cloudflare CDN, 풀 페이지 캐싱, 오브젝트 캐싱(Redis/Memcached), DB 복제를 마스터합니다.

고가용성 WordPress 인프라: 다운타임 0을 향한 여정

단일 서버의 한계와 스케일링의 필요성

단일 서버 WordPress 아키텍처는 트래픽 한계, 단일 장애점, 지역별 지연시간이라는 세 가지 근본적 문제를 가지고 있습니다. 일 방문자 10,000명을 넘기거나, WooCommerce에서 동시 주문이 증가하거나, 해외 사용자가 늘어나면 이 문제들이 동시에 나타납니다.


고가용성(HA) 인프라의 핵심 목표:

- 99.99% 업타임: 연간 다운타임 52분 이내 (일반 호스팅은 99.9% = 8.7시간)

- 글로벌 빠른 응답: 전 세계 어디서든 TTFB 200ms 이내

- 트래픽 급증 대응: 갑자기 트래픽이 10배 증가해도 서비스 유지

- 자동 장애 복구: 서버 하나가 다운되어도 사용자는 전혀 인식하지 못함

- 무중단 배포: 업데이트 시에도 서비스 중단 없음

🌍
310+
Cloudflare 글로벌
엣지 서버 도시 수
50-80%
Redis 캐시 적용 시
DB 부하 감소
🔄
0초
로드 밸런서의
장애 전환 시간
💰
70%
CDN으로 절약되는
서버 대역폭 비용

로드 밸런싱 아키텍처 설계

👥
사용자
트래픽
🌐
Cloudflare
CDN/WAF
⚖️
Nginx
로드 밸런서
🖥️
WP 서버 1,2,3
(PHP-FPM)
💾
DB Primary
+ Redis

Nginx 로드 밸런서 완전 설정

Nginx는 리버스 프록시 + 로드 밸런서로서 탁월한 성능을 발휘합니다. 적은 메모리로 수만 개의 동시 연결을 처리할 수 있으며, 다양한 로드 밸런싱 알고리즘을 지원합니다. 아래는 프로덕션 환경에서 사용하는 완전한 Nginx 로드 밸런서 설정입니다.

# ============================================
# Nginx 로드 밸런서 설정
# /etc/nginx/nginx.conf (로드 밸런서 서버)
# ============================================

user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;

events {
    worker_connections 4096;
    multi_accept on;
    use epoll;
}

http {
    # 기본 설정
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    client_max_body_size 64M;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # 로그 설정
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$upstream_addr" '
                    'response_time=$upstream_response_time';

    access_log /var/log/nginx/access.log main;

    # Gzip 압축
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_comp_level 5;
    gzip_types text/plain text/css text/xml application/json
               application/javascript application/xml text/javascript
               application/x-font-ttf font/opentype image/svg+xml;

    # ============================================
    # 업스트림 서버 풀 정의
    # ============================================

    # WordPress 애플리케이션 서버 풀
    upstream wordpress_backend {
        # 로드 밸런싱 알고리즘
        # round_robin (기본) - 순차적 분배
        # least_conn - 가장 적은 연결 수의 서버로
        # ip_hash - 같은 IP는 같은 서버로 (세션 유지)
        least_conn;

        # 서버 목록 (weight로 비중 조절 가능)
        server 10.0.1.10:80 weight=3 max_fails=3 fail_timeout=30s;
        server 10.0.1.11:80 weight=3 max_fails=3 fail_timeout=30s;
        server 10.0.1.12:80 weight=2 max_fails=3 fail_timeout=30s;

        # 백업 서버 (주 서버 모두 다운 시에만 사용)
        server 10.0.1.20:80 backup;

        # 헬스 체크 간격 설정 (Nginx Plus 또는 nginx_upstream_check_module)
        # check interval=5000 rise=2 fall=3 timeout=3000 type=http;
        # check_http_send "GET /wp-json/monitor/v1/health HTTP/1.0\r\nHost: example.com\r\n\r\n";
        # check_http_expect_alive http_2xx;

        # 커넥션 캐시 (킵얼라이브)
        keepalive 32;
    }

    # ============================================
    # 서버 블록 (프론트엔드)
    # ============================================
    server {
        listen 80;
        server_name example.com www.example.com;

        # HTTPS 리다이렉트
        return 301 https://$host$request_uri;
    }

    server {
        listen 443 ssl http2;
        server_name example.com www.example.com;

        # SSL 설정
        ssl_certificate /etc/nginx/certs/fullchain.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
        ssl_prefer_server_ciphers off;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 1d;

        # 보안 헤더
        add_header X-Frame-Options SAMEORIGIN always;
        add_header X-Content-Type-Options nosniff always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

        # 정적 파일은 CDN에서 직접 서빙 (로드 밸런서에서도 캐시)
        location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|mp4|webp|avif)$ {
            proxy_pass http://wordpress_backend;
            proxy_cache static_cache;
            proxy_cache_valid 200 30d;
            proxy_cache_key "$scheme$host$request_uri";
            add_header X-Cache-Status $upstream_cache_status;
            expires 30d;
        }

        # wp-admin 요청은 세션 유지 (ip_hash 효과)
        location /wp-admin {
            proxy_pass http://wordpress_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_cookie_domain ~\.example\.com example.com;
        }

        # 일반 요청
        location / {
            proxy_pass http://wordpress_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_set_header Connection "";

            # 프록시 캐시 (비로그인 사용자만)
            proxy_cache page_cache;
            proxy_cache_valid 200 10m;
            proxy_cache_bypass $http_cookie;
            proxy_no_cache $http_cookie;

            # 타임아웃
            proxy_connect_timeout 10s;
            proxy_send_timeout 30s;
            proxy_read_timeout 30s;

            # 장애 시 다음 서버로 전환
            proxy_next_upstream error timeout http_502 http_503 http_504;
            proxy_next_upstream_tries 3;
            proxy_next_upstream_timeout 10s;
        }

        # 헬스 체크 엔드포인트 (로드 밸런서 자체)
        location /lb-health {
            access_log off;
            return 200 "OK";
        }
    }

    # 프록시 캐시 영역 정의
    proxy_cache_path /var/cache/nginx/page levels=1:2 keys_zone=page_cache:50m
                     max_size=1g inactive=60m use_temp_path=off;
    proxy_cache_path /var/cache/nginx/static levels=1:2 keys_zone=static_cache:100m
                     max_size=5g inactive=7d use_temp_path=off;
}
로드 밸런싱 알고리즘 동작 방식 장점 적합한 상황
Round Robin (기본)순차적으로 서버에 분배간단, 균등 분배서버 사양이 동일할 때
Least Connections연결이 가장 적은 서버로부하 불균형 방지요청 처리 시간이 다양할 때
IP Hash클라이언트 IP 기반 고정세션 유지 보장로그인 세션이 중요할 때
Weighted가중치 기반 분배서버 사양 차이 반영서버 사양이 다를 때
Random무작위 선택편향 없는 분배동일 사양, 스테이트리스

WordPress 로드 밸런싱의 핵심 과제: 세션과 파일 공유

WordPress를 로드 밸런싱할 때 반드시 해결해야 하는 두 가지 문제가 있습니다:

1. 세션 공유: 사용자가 서버 A에서 로그인한 후 서버 B로 분배되면 로그인 상태가 풀립니다. 해결책: Redis/Memcached에 세션을 저장하거나, IP Hash/스티키 세션을 사용하세요.

2. 파일 공유: 서버 A에 업로드된 이미지가 서버 B에는 없습니다. 해결책: NFS/GlusterFS로 공유 파일시스템을 구성하거나, S3 + CloudFront로 미디어를 외부 저장소에 보관하세요.

🔒
여기까지는 미리보기입니다
로드 밸런싱과 CDN 전략
무료 가입하면 이어서 볼 수 있고, 강의를 완료할 때마다 XP와 레벨이 쌓입니다.
Google로 3초 만에 시작 →🧵 Threads로 시작무료 공개 강의 둘러보기 (Lv.1~3)