/엔지니어/네트워킹 / 서버/Nginx 고급 운영 — 로드밸런싱 · 캐싱 · R
네트워킹 / 서버고급UbuntuDebianCentOSRHELNginx로드밸런싱캐싱

Nginx 고급 운영 — 로드밸런싱 · 캐싱 · Rate Limiting · 보안 헤더

upstream 로드밸런싱 전략, proxy_cache 콘텐츠 캐싱, limit_req rate limiting, 보안 헤더까지 — 프로덕션 Nginx를 완전히 제어하는 심화 가이드.

프로덕션 Nginx 설정 구조

단순 리버스 프록시를 넘어, Nginx를 로드밸런서·캐시서버·WAF 전방 배치 레이어로 활용하는 패턴을 다룹니다.


1. upstream 로드밸런싱 전략

기본 구성 (Round Robin)

Nginx
http {
  upstream app_servers {
    least_conn;          # 최소 연결 수 기준 분배 (Round Robin 대신 권장)

    server 10.0.1.10:8080 weight=3;   # 가중치: 트래픽 30%
    server 10.0.1.11:8080 weight=2;
    server 10.0.1.12:8080 weight=1;
    server 10.0.1.13:8080 backup;     # 나머지 전부 다운 시 사용

    keepalive 32;        # upstream keepalive 연결 풀
    keepalive_timeout 60s;
  }

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

    location / {
      proxy_pass http://app_servers;
      proxy_http_version 1.1;
      proxy_set_header Connection "";         # keepalive 유지
      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;
    }
  }
}

세션 지속성 (Sticky Session)

Nginx
upstream app_servers {
  ip_hash;              # 동일 클라이언트 IP는 항상 같은 서버로
  server 10.0.1.10:8080;
  server 10.0.1.11:8080;
}

헬스체크 (Nginx Plus 없이 수동 구현)

Nginx
upstream app_servers {
  server 10.0.1.10:8080 max_fails=3 fail_timeout=30s;
  server 10.0.1.11:8080 max_fails=3 fail_timeout=30s;
}
# max_fails: 30초 내 3번 실패 시 해당 서버 일시 제외

2. proxy_cache — 콘텐츠 캐싱

Nginx
http {
  # 캐시 저장소 정의 (nginx.conf 최상단 http 블록)
  proxy_cache_path /var/cache/nginx
    levels=1:2                    # 디렉터리 계층 구조
    keys_zone=app_cache:50m       # 메모리 내 키 저장소 50MB
    max_size=10g                  # 최대 디스크 사용량
    inactive=60m                  # 60분간 미접근 시 삭제
    use_temp_path=off;

  server {
    location / {
      proxy_pass http://app_servers;

      proxy_cache app_cache;
      proxy_cache_key "$scheme$request_method$host$request_uri";
      proxy_cache_valid 200 302 10m;   # 200/302 응답 10분 캐시
      proxy_cache_valid 404      1m;
      proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
      proxy_cache_lock on;             # 동일 키 중복 요청 방지 (thundering herd)
      proxy_cache_lock_timeout 5s;

      # 캐시 상태 헤더 노출 (디버깅용)
      add_header X-Cache-Status $upstream_cache_status;
    }

    # 캐시 우회: 특정 조건에서
    location /api/user {
      proxy_pass http://app_servers;
      proxy_cache_bypass $cookie_session;  # 세션 쿠키 있으면 캐시 건너뜀
      proxy_no_cache $cookie_session;
    }

    # 캐시 퍼지 (내부에서만 허용)
    location ~ /purge(/.*) {
      allow 127.0.0.1;
      deny all;
      proxy_cache_purge app_cache "$scheme$request_method$host$1";
    }
  }
}
Bash
# 캐시 상태 확인
curl -I https://example.com/static/logo.png | grep X-Cache-Status
# HIT / MISS / BYPASS / UPDATING

# 캐시 디렉터리 크기 확인
du -sh /var/cache/nginx

# 캐시 전체 초기화
sudo rm -rf /var/cache/nginx/*
sudo nginx -s reload

3. Rate Limiting — DDoS / 무차별 대입 방어

Nginx
http {
  # 요청 속도 제한 존 정의
  limit_req_zone $binary_remote_addr zone=api_limit:20m rate=10r/s;
  limit_req_zone $binary_remote_addr zone=login_limit:10m rate=3r/m;
  limit_req_zone $http_x_api_key    zone=key_limit:10m  rate=100r/s;

  # 연결 수 제한 존
  limit_conn_zone $binary_remote_addr zone=conn_limit:20m;

  server {
    # API 엔드포인트: 초당 10req, 버스트 20개 허용
    location /api/ {
      limit_req zone=api_limit burst=20 nodelay;
      limit_conn conn_limit 20;
      limit_req_status 429;

      proxy_pass http://app_servers;
    }

    # 로그인: 분당 3회, 초과 시 큐잉 (nodelay 없음)
    location /auth/login {
      limit_req zone=login_limit burst=5;
      limit_req_status 429;
      proxy_pass http://app_servers;
    }

    # Rate Limit 초과 응답 커스터마이징
    error_page 429 /rate_limit.json;
    location = /rate_limit.json {
      internal;
      default_type application/json;
      return 429 '{"error":"Too Many Requests","retry_after":60}';
    }
  }
}

4. 보안 헤더 및 SSL 강화

Nginx
http {
  # TLS 설정
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers off;
  ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';

  # HSTS (Strict-Transport-Security)
  add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

  # DH 파라미터 생성 및 적용
  ssl_dhparam /etc/nginx/dhparam.pem;    # openssl dhparam -out /etc/nginx/dhparam.pem 4096

  # OCSP Stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8 8.8.4.4 valid=300s;

  server {
    # 보안 헤더 일괄 설정
    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 Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' cdn.example.com; img-src 'self' data: cdn.example.com; style-src 'self' 'unsafe-inline';" always;

    # 서버 정보 숨기기
    server_tokens off;

    # HTTP → HTTPS 리다이렉트
    if ($scheme = http) {
      return 301 https://$host$request_uri;
    }
  }
}

5. 성능 튜닝 — worker 및 커넥션 최적화

Nginx
# /etc/nginx/nginx.conf

user nginx;
worker_processes auto;          # CPU 코어 수에 맞게 자동 설정
worker_rlimit_nofile 65535;     # 파일 디스크립터 한도

events {
  worker_connections 4096;      # worker당 최대 연결 수
  use epoll;                    # Linux 최적화 이벤트 방식
  multi_accept on;              # 한 번에 여러 연결 수락
}

http {
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;

  keepalive_timeout 65;
  keepalive_requests 1000;

  # Gzip 압축
  gzip on;
  gzip_vary on;
  gzip_proxied any;
  gzip_comp_level 6;
  gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss;
  gzip_min_length 1024;

  # 버퍼 튜닝
  proxy_buffer_size 128k;
  proxy_buffers 4 256k;
  proxy_busy_buffers_size 256k;

  # 타임아웃
  proxy_connect_timeout 5s;
  proxy_send_timeout 60s;
  proxy_read_timeout 60s;
}
Bash
# 설정 검증
sudo nginx -t

# 무중단 설정 리로드
sudo nginx -s reload

# 실시간 연결 통계
sudo nginx -V 2>&1 | grep with-http_stub_status
# status 페이지 확인
curl http://localhost/nginx_status
#Nginx#로드밸런싱#캐싱#rate-limiting#보안헤더#웹서버#성능최적화
편집 안내 · Editorial Note

이 가이드는 AI 도구를 활용해 초안을 구성하고 사람이 명령어·문맥을 검토해 발행했습니다. 운영체제와 도구 버전에 따라 결과가 달라질 수 있으므로 적용 전 공식 문서를 함께 확인하세요. 오류를 발견하시면 이메일로 제보해 주세요.

질문 & 답변 (Q&A)

이 가이드에 대해 궁금한 점을 질문해보세요. 확인 후 답변드립니다.