고(트래픽) 웹사이트를 위한 필수 Nginx 성능 튜닝 체크리스트

이 필수 Nginx 튜닝 체크리스트를 통해 고(트래픽) 웹사이트의 최고 성능을 확보하십시오. 이 포괄적인 가이드는 워커 프로세스 최적화, 연결 관리, 버퍼 미세 조정, 강력한 캐싱 구현과 같은 중요한 구성을 다룹니다. Gzip 압축 활용, 로깅 간소화, 타임아웃 조정, SSL/TLS 보안 설정을 통해 더 빠른 로드 시간과 서버 부하 감소를 달성하는 방법을 배우십시오. 바쁜 서버에서 탁월한 속도와 안정성을 위해 Nginx 설정을 향상시키세요.

58 조회수

고트래픽 웹사이트를 위한 필수 Nginx 성능 튜닝 체크리스트

상당한 트래픽을 경험하는 모든 웹사이트에서 Nginx는 강력하고 효율적인 웹 서버 및 리버스 프록시로 돋보입니다. 하지만 단순히 Nginx를 배포하는 것만으로는 높은 부하에서 최적의 성능을 보장하기에 충분하지 않습니다. 적절한 구성 및 튜닝은 Nginx의 잠재력을 최대한 발휘하고 웹 애플리케이션이 빠르고 반응성이 뛰어나며 안정적으로 유지되도록 하는 데 매우 중요합니다.

이 문서는 고트래픽 환경의 성능을 최적화하기 위해 특별히 고안된 주요 Nginx 구성 및 지시문에 대한 포괄적인 체크리스트를 제공합니다. 워커 프로세스 및 연결 관리부터 버퍼 미세 조정, 강력한 캐싱 전략 구현, 압축 최적화에 이르기까지 모든 것을 다룹니다. 이러한 영역을 체계적으로 해결함으로써 서버 부하를 크게 줄이고, 콘텐츠 전달 속도를 높이며, 전반적인 사용자 경험을 개선할 수 있습니다.

1. 워커 프로세스 및 연결 최적화

Nginx는 마스터-워커 프로세스 모델을 활용합니다. 마스터 프로세스는 구성을 읽고 실제 클라이언트 요청을 처리하는 워커 프로세스를 관리합니다. 이러한 부분을 올바르게 구성하면 동시성 및 리소스 활용률을 크게 향상시킬 수 있습니다.

worker_processes

이 지시문은 Nginx가 생성할 워커 프로세스의 수를 결정합니다. 일반적으로 이 값을 auto로 설정하면 Nginx가 CPU 코어 수를 감지하고 동일한 수의 워커 프로세스를 생성하며, 이는 일반적인 모범 사례입니다.

worker_connections

단일 워커 프로세스가 열 수 있는 최대 동시 연결 수를 정의합니다. 이 설정은 worker_processes와 함께 Nginx가 처리할 수 있는 총 이론적 동시 연결 수(worker_processes * worker_connections)를 결정합니다.

multi_accept

워커 프로세스가 한 번에 여러 개의 새 연결을 수락할 수 있도록 하여 높은 부하에서 발생할 수 있는 잠재적인 병목 현상을 방지합니다.

# /etc/nginx/nginx.conf

worker_processes auto; # 일반적으로 'auto' 또는 CPU 코어 수로 설정합니다.

events {
    worker_connections 1024; # 서버 용량 및 예상 부하에 따라 조정합니다.
    multi_accept on;
}

팁: 서버의 CPU 사용량을 모니터링하십시오. worker_processesauto로 설정되어 있고 CPU 활용률이 지속적으로 높으면, worker_connections를 늘리거나 서버 리소스를 확장하는 것을 고려할 수 있습니다.

2. 효율적인 연결 관리

Nginx가 네트워크 연결을 처리하는 방식을 최적화하면 오버헤드를 줄이고 반응성을 개선할 수 있습니다.

keepalive_timeout

유지(keep-alive)되는 클라이언트 연결이 열린 상태로 유지되는 시간을 지정합니다. 연결을 재사용하면 새로운 TCP 연결 및 SSL 핸드셰이크를 설정하는 오버헤드가 줄어듭니다. 일반적인 값은 애플리케이션의 상호 작용성에 따라 15~65초입니다.

sendfile

사용자 공간 버퍼링을 우회하여 파일 디스크립터 간의 직접적인 데이터 전송을 활성화합니다. 이는 정적 파일을 서비스할 때 성능을 크게 향상시킵니다.

tcp_nopush

sendfile과 함께 작동합니다. Nginx는 HTTP 헤더와 파일의 시작 부분을 하나의 패킷으로 전송하려고 시도합니다. 그 후에는 전체 패킷으로 데이터를 전송합니다. 이는 전송되는 패킷의 수를 줄여줍니다.

tcp_nodelay

Nginx에게 버퍼링 없이 데이터가 사용 가능해지는 즉시 데이터를 전송하도록 지시합니다. 이는 처리량을 최대화하는 것보다 낮은 대기 시간이 더 중요한 상호 작용 애플리케이션(예: 채팅 애플리케이션 또는 실시간 업데이트)에 유용합니다.

http {
    keepalive_timeout 65; # 65초 동안 유지 연결
    sendfile on;
    tcp_nopush on; # sendfile이 on이어야 합니다.
    tcp_nodelay on; # 동적 콘텐츠를 프록시할 때 유용합니다.
}

3. 버퍼 최적화

Nginx는 클라이언트 요청과 업스트림 서버(예: 애플리케이션 서버)의 응답을 처리하기 위해 버퍼를 사용합니다. 이러한 버퍼의 크기를 적절하게 조정하면 불필요한 디스크 I/O를 방지하고, 메모리 사용량을 줄이며, 처리량을 개선할 수 있습니다.

클라이언트 버퍼

  • client_body_buffer_size: 클라이언트 요청 본문을 위한 버퍼 크기입니다. 본문이 이 크기를 초과하면 임시 파일에 기록됩니다.
  • client_header_buffer_size: 클라이언트 요청의 첫 번째 줄 및 헤더를 위한 버퍼 크기입니다.
  • large_client_header_buffers: 클라이언트 요청 헤더를 읽기 위한 더 큰 버퍼의 개수와 크기를 정의합니다. 많은 쿠키나 긴 리퍼러(referer) 헤더가 있는 요청에 유용합니다.

프록시 버퍼 (리버스 프록시 설정용)

  • proxy_buffers: 프록시된 서버로부터 응답을 읽는 데 사용되는 버퍼의 개수와 크기입니다.
  • proxy_buffer_size: 응답을 읽는 데 사용되는 첫 번째 버퍼의 크기입니다. 일반적으로 헤더만 포함하는 경우가 많으므로 더 작습니다.
  • proxy_busy_buffers_size: 주어진 시점에 '사용 중'(클라이언트에게 활발하게 전송되는 중) 상태에 있을 수 있는 응답 버퍼의 최대 양입니다.

FastCGI 버퍼 (PHP-FPM 등용)

  • fastcgi_buffers: FastCGI 서버로부터 응답을 읽는 데 사용되는 버퍼의 개수와 크기입니다.
  • fastcgi_buffer_size: 응답을 읽는 데 사용되는 첫 번째 버퍼의 크기입니다.
http {
    # Client Buffers (클라이언트 버퍼)
    client_body_buffer_size 1M; # 예상 요청 본문 크기(예: 파일 업로드)를 기반으로 조정
    client_header_buffer_size 1k;
    large_client_header_buffers 4 8k; # 4개의 버퍼, 각각 8KB 크기

    # Proxy Buffers (Nginx가 리버스 프록시 역할을 하는 경우)
    proxy_buffers 8 16k; # 8개의 버퍼, 각각 16KB
    proxy_buffer_size 16k; # 첫 번째 버퍼 16KB
    proxy_busy_buffers_size 16k; # 최대 16KB의 사용 중인 버퍼

    # FastCGI Buffers (Nginx가 PHP-FPM과 함께 작동하는 경우)
    fastcgi_buffers 116 8k; # 116개의 버퍼, 각각 8KB (예: WordPress용)
    fastcgi_buffer_size 16k; # 첫 번째 버퍼 16KB
}

경고: 버퍼를 너무 작게 설정하면 디스크 I/O 및 성능 저하가 발생할 수 있습니다. 너무 크게 설정하면 과도한 메모리를 소비할 수 있습니다. 테스트를 통해 균형점을 찾으십시오.

4. 강력한 캐싱 전략 구현

캐싱은 성능을 개선하고 백엔드 서버의 부하를 줄이는 가장 효과적인 방법 중 하나입니다. Nginx는 강력한 콘텐츠 캐시 역할을 할 수 있습니다.

proxy_cache_path

캐시 디렉토리의 경로, 크기, 하위 디렉토리 수준 수, 비활성 항목이 캐시에 남아 있는 기간을 정의합니다.

proxy_cache

주어진 location 블록에 대해 캐싱을 활성화하며, proxy_cache_path에 정의된 영역을 참조합니다.

proxy_cache_valid

특정 HTTP 상태 코드를 가진 응답을 Nginx가 캐시해야 하는 시간을 설정합니다.

proxy_cache_revalidate

활성화되면 Nginx는 If-Modified-SinceIf-None-Match 헤더를 사용하여 캐시된 콘텐츠를 백엔드와 재검증하여 대역폭 사용량을 줄입니다.

proxy_cache_use_stale

백엔드 서버가 다운되었거나, 응답하지 않거나, 오류를 겪고 있는 경우 Nginx가 오래된(stale) 캐시된 콘텐츠를 제공하도록 지시합니다. 이는 가용성을 크게 향상시킵니다.

expires

정적 파일의 클라이언트 측 캐싱을 위해 Cache-ControlExpires 헤더를 설정합니다. 이는 Nginx에 대한 반복 요청을 최소화합니다.

http {
    # http 블록에 프록시 캐시 영역 정의
    proxy_cache_path /var/cache/nginx/my_cache levels=1:2 keys_zone=my_cache:10m inactive=60m max_size=10g;

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://my_upstream_backend;
            proxy_cache my_cache; # 이 location에 대해 캐싱 활성화
            proxy_cache_valid 200 302 10m; # 성공적인 응답을 10분 동안 캐시
            proxy_cache_valid 404 1m; # 404 오류를 1분 동안 캐시
            proxy_cache_revalidate on;
            proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
            add_header X-Cache-Status $upstream_cache_status; # 디버깅에 도움
        }

        # 브라우저에 정적 파일을 더 오랫동안 캐시
        location ~* \.(jpg|jpeg|gif|png|css|js|ico|woff|woff2|ttf|svg|eot)$ {
            expires 30d; # 30일 동안 캐시
            add_header Cache-Control "public, no-transform";
            # 정적 파일의 경우, 프록시되지 않은 경우 Nginx에서 직접 서비스하는 것을 고려
            root /var/www/html;
        }
    }
}

5. Gzip 압축 활성화

응답을 클라이언트에게 보내기 전에 압축하면 특히 텍스트 기반 콘텐츠의 경우 대역폭 사용량을 크게 줄이고 페이지 로드 시간을 개선할 수 있습니다.

gzip on

gzip 압축을 활성화합니다.

gzip_comp_level

압축 수준(1-9)을 설정합니다. 레벨 1은 압축률이 낮고 가장 빠르며, 레벨 9는 압축률이 최대이고 가장 느립니다. 레벨 6이 일반적으로 좋은 균형을 제공합니다.

gzip_types

압축해야 하는 MIME 유형을 지정합니다. 일반적인 텍스트, CSS, JavaScript 및 JSON 유형을 포함합니다.

gzip_min_length

압축을 활성화해야 하는 응답의 최소 길이(바이트)를 설정합니다. 작은 파일은 큰 이점이 없으며 압축 오버헤드로 인해 오히려 느려질 수 있습니다.

gzip_proxied

프록시된 응답이라도 Nginx가 압축하도록 지시합니다. any가 일반적인 값입니다.

gzip_vary

응답에 Vary: Accept-Encoding 헤더를 추가하여, 프록시에게 응답이 Accept-Encoding 요청 헤더에 따라 달라질 수 있음을 알립니다.

http {
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6; # 압축 수준 1-9 (6이 좋은 균형점)
    gzip_buffers 16 8k; # 16개의 버퍼, 각각 8KB
    gzip_http_version 1.1; # 압축을 위한 최소 HTTP 버전
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
    gzip_min_length 1000; # 1KB보다 큰 응답만 압축
}

6. 로깅 최적화

로그는 모니터링 및 문제 해결에 필수적이지만, 과도하거나 최적화되지 않은 로깅은 특히 고트래픽 사이트에서 상당한 디스크 I/O를 유발할 수 있습니다.

access_log

  • 정적 자산에 대해 비활성화: 자주 액세스되는 정적 콘텐츠(이미지, CSS, JS)의 경우 access_log를 비활성화하면 많은 I/O를 절약할 수 있습니다.
  • 버퍼링: Nginx는 로그 항목을 디스크에 쓰기 전에 메모리에 버퍼링하여 디스크 쓰기 빈도를 줄일 수 있습니다. 여기서는 bufferflush 매개변수가 사용됩니다.

error_log

적절한 로깅 수준(crit, error, warn, info, debug)을 설정합니다. 프로덕션 환경에서는 로그가 넘치지 않으면서 중요한 문제를 포착하기 위해 일반적으로 warn 또는 error로 충분합니다.

http {
    server {
        # 동적 콘텐츠에 대한 기본 액세스 로그
        access_log /var/log/nginx/access.log main;

        location ~* \.(jpg|jpeg|gif|png|css|js|ico|woff|woff2|ttf|svg|eot)$ {
            access_log off; # 일반적인 정적 파일에 대한 로깅 비활성화
            expires 30d;
        }
    }

    # 주 HTTP 컨텍스트에 대한 버퍼링된 액세스 로그 예시
    # access_log /var/log/nginx/access.log main buffer=16k flush=5s;
    error_log /var/log/nginx/error.log warn; # 경고 이상만 로깅
}

7. 타임아웃 조정

적절하게 구성된 타임아웃은 Nginx가 비활성 연결을 너무 오래 유지하는 것을 방지하여 리소스를 확보합니다.

클라이언트 측 타임아웃

  • client_body_timeout: Nginx가 클라이언트가 요청 본문을 보낼 때까지 기다리는 시간입니다.
  • client_header_timeout: Nginx가 클라이언트가 요청 헤더를 보낼 때까지 기다리는 시간입니다.
  • send_timeout: Nginx가 응답을 전송한 후 클라이언트가 응답을 수락할 때까지 기다리는 시간입니다.

프록시/FastCGI 타임아웃 (해당되는 경우)

  • proxy_connect_timeout: 프록시된 서버와 연결을 설정하기 위한 타임아웃입니다.
  • proxy_send_timeout: 프록시된 서버로 요청을 전송하기 위한 타임아웃입니다.
  • proxy_read_timeout: 프록시된 서버로부터 응답을 읽기 위한 타임아웃입니다.
http {
    client_body_timeout 15s; # 클라이언트는 본문을 전송하는 데 15초가 주어집니다.
    client_header_timeout 15s; # 클라이언트는 헤더를 전송하는 데 15초가 주어집니다.
    send_timeout 15s; # Nginx는 클라이언트에게 응답을 전송하는 데 15초가 주어집니다.

    # 프록시 시나리오용
    proxy_connect_timeout 5s; # 업스트림에 연결하는 데 5초
    proxy_send_timeout 15s; # 업스트림에 요청을 전송하는 데 15초
    proxy_read_timeout 15s; # 업스트림으로부터 응답을 읽는 데 15초

    # FastCGI 시나리오용
    fastcgi_connect_timeout 5s;
    fastcgi_send_timeout 15s;
    fastcgi_read_timeout 15s;
}

8. SSL/TLS 최적화

HTTPS가 활성화된 사이트의 경우, SSL/TLS 설정을 최적화하는 것은 CPU 오버헤드를 줄이고 핸드셰이크 성능을 개선하는 데 중요합니다.

ssl_session_cachessl_session_timeout

동일한 클라이언트로부터의 후속 연결에 대해 계산 비용이 많이 드는 전체 TLS 핸드셰이크를 피하기 위해 SSL 세션 캐싱을 활성화합니다.

ssl_protocolsssl_ciphers

최신이면서 강력한 TLS 프로토콜(예: TLSv1.2TLSv1.3)과 안전한 암호화 스위트를 사용하십시오. ssl_prefer_server_ciphers on을 사용하여 서버 암호를 우선시하십시오.

ssl_stapling

OCSP 스테이플링(Stapling)을 활성화합니다. 이는 Nginx가 CA로부터 OCSP 응답을 주기적으로 가져와서 SSL/TLS 핸드셰이크에 "스테이플링"하는 기능입니다. 이는 별도의 OCSP 쿼리를 피하여 클라이언트 측 대기 시간을 줄입니다.

server {
    listen 443 ssl;
    ssl_certificate /etc/nginx/ssl/your_domain.crt;
    ssl_certificate_key /etc/nginx/ssl/your_domain.key;

    ssl_session_cache shared:SSL:10m; # 10MB 세션 데이터를 위한 공유 캐시
    ssl_session_timeout 10m; # 세션은 10분 후에 만료됩니다.

    ssl_protocols TLSv1.2 TLSv1.3; # 최신 보안 프로토콜 사용
    ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256';
    ssl_prefer_server_ciphers on;

    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s; # OCSP 쿼리를 위한 DNS 리졸버 지정
    resolver_timeout 5s;
}

9. 오픈 파일 캐시

Nginx는 자주 액세스되는 파일에 대한 파일 디스크립터를 캐시하여 파일을 열고 닫는 반복적인 시스템 호출의 필요성을 줄일 수 있습니다.

open_file_cache

캐시를 활성화하고, 최대 요소 수와 비활성 요소가 유지되는 기간을 지정합니다.

open_file_cache_valid

캐시가 요소의 유효성을 확인해야 하는 빈도를 설정합니다.

open_file_cache_min_uses

파일이 캐시에 남아 있기 위해 inactive 시간 내에 액세스되어야 하는 최소 횟수를 지정합니다.

open_file_cache_errors

Nginx가 파일을 열 때 발생하는 오류를 캐시해야 하는지 여부를 결정합니다.

http {
    open_file_cache max=100000 inactive=60s; # 60초 동안 최대 100,000개의 파일 디스크립터 캐시
    open_file_cache_valid 80s; # 80초마다 유효성 확인
    open_file_cache_min_uses 1; # 최소 한 번 사용된 파일 캐시
    open_file_cache_errors on; # 파일 열기와 관련된 오류 캐시
}

결론

Nginx 성능 튜닝은 일회성 설정이 아니라 지속적인 프로세스입니다. 이 체크리스트는 고트래픽 웹사이트를 최적화하기 위한 강력한 시작점을 제공합니다. '완벽한' 구성은 특정 애플리케이션, 트래픽 패턴 및 서버 리소스에 따라 크게 달라진다는 점을 기억하십시오. 프로덕션에 배포하기 전에 항상 스테이징 환경에서 변경 사항을 테스트하고, Nginx Plus의 라이브 활동 모니터링, Prometheus, Grafana 또는 기본 시스템 도구(예: top, iostat, netstat)와 같은 도구를 사용하여 Nginx 인스턴스 및 백엔드 서버를 지속적으로 모니터링하십시오.

이러한 최적화 사항들을 세심하게 적용하고 사용자 환경에 맞게 조정함으로써, 가장 까다로운 부하에서도 Nginx가 탁월한 속도, 효율성 및 안정성으로 콘텐츠를 제공하도록 보장할 수 있습니다.