자동화&툴 리뷰

[완벽 가이드] Nginx 설정 최적화 팁 — SSL, 캐싱, 리버스 프록시까지 실전 정리

노동1호 2026. 4. 16. 02:02

웹 서버 성능은 서비스 체감 속도의 첫 번째 관문입니다. 전 세계 웹 트래픽의 약 34%가 Nginx로 처리되고 있으며, 올바른 설정 하나로 응답 시간을 30~50% 단축할 수 있습니다. 하지만 많은 개발자가 기본 설정만으로 운영하거나, 복사-붙여넣기한 설정을 이해 없이 사용하고 있습니다.

nginx server optimization configuration

이 글에서는 실무에서 바로 적용할 수 있는 Nginx 설정 최적화 팁을 단계별로 정리합니다. 리소스 튜닝부터 SSL 최적화, 캐싱, 보안 헤더까지 핵심만 콕콕 집어드리겠습니다.

1. Worker 프로세스와 커넥션 튜닝

Nginx의 성능은 기본적으로 worker_processesworker_connections 설정에서 출발합니다.

Worker 프로세스 최적화

# CPU 코어 수만큼 Worker 프로세스 할당
worker_processes auto;

# 각 Worker가 처리할 수 있는 최대 동시 커넥션
events {
    worker_connections 4096;
    multi_accept on;
}

worker_processes auto는 서버의 CPU 코어 수에 맞춰 자동으로 프로세스를 생성합니다. 8코어 서버라면 8개의 Worker가 병렬로 요청을 처리하게 됩니다. multi_accept on은 새로운 커넥션을 한 번에 여러 개 받아들이도록 설정하여, 트래픽 급증 시 커넥션 대기 시간을 줄여줍니다.

파일 디스크립터 늘리기

# /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535

OS 레벨에서 파일 디스크립터 제한을 늘려주지 않으면, Nginx 설정을 아무리 올려도 "too many open files" 에러가 발생합니다. ulimit -n으로 현재 제한을 확인하고, 필요하면 위처럼 설정하세요.

2. HTTP/2와 SSL/TLS 최적화

HTTPS는 필수가 된 지 오래지만, 잘못된 SSL 설정은 TTFB(Time To First Byte)를 50~300ms까지 늘릴 수 있습니다. 실제로 GitHub 이슈에서도 HTTPS 경유 시 레이턴시가 수백 배 늘어나는 사례가 보고된 바 있습니다.

SSL 세션 캐시와 OCSP Stapling

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

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # SSL 세션 캐시 — 재연결 시 핸드셰이크 생략
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # OCSP Stapling — 인증서 유효성 검사를 서버에서 미리 수행
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 1.1.1.1 valid=300s;
    resolver_timeout 5s;

    # 최신 프로토콜만 허용
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
}

ssl_session_cache shared:SSL:10m은 약 40,000개의 SSL 세션을 메모리에 캐싱합니다. 이미 핸드셰이크를 완료한 클라이언트는 이후 연결에서 핸드셰이크를 건너뛰어 응답 속도가 크게 개선됩니다.

OCSP Stapling은 클라이언트가 인증서 폐기 여부를 확인하기 위해 CA에 직접 요청하는 대신, 서버가 미리 확인한 결과를 함께 전송하는 방식입니다. 이를 통해 100~300ms의 추가 레이턴시를 제거할 수 있습니다.

3. 정적 파일 캐싱과 Gzip 압축

정적 자원(JS, CSS, 이미지)은 브라우저 캐시와 서버 압축 설정만으로 전송량을 60~80% 줄일 수 있습니다.

브라우저 캐시 헤더 설정

nginx server optimization configuration
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2|svg)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
    access_log off;
}

immutable 디렉티브는 브라우저가 만료 시간 전에 조건부 요청(If-Modified-Since)조차 보내지 않도록 막아, 불필요한 요청을 원천 차단합니다. 해시가 포함된 파일 이름(app.a1b2c3.js)에 사용하기 좋습니다.

Gzip 압축 설정

gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 4;
gzip_min_length 256;
gzip_types
    text/plain
    text/css
    text/xml
    text/javascript
    application/json
    application/javascript
    application/xml+rss
    application/atom+xml
    image/svg+xml;

gzip_comp_level 4는 압축률과 CPU 사용량의 최적 밸런스 포인트입니다. 1~3은 압축률이 낮고, 6 이상은 CPU 비용 대비 압축 효율이 떨어집니다. gzip_min_length 256은 256바이트 미만의 파일은 압축하지 않아, 압축 오버헤드보다 파일 크기가 더 작은 경우를 방지합니다.

4. 리버스 프록시 버퍼링 최적화

Nginx를 리버스 프록시로 사용할 때, 버퍼링 설정은 백엔드 응답 속도와 Nginx 자원 사용량에 직접적인 영향을 미칩니다.

proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;

# 백엔드 타임아웃 설정
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;

# 업스트림 커넥션 유지
upstream backend {
    server 127.0.0.1:8000;
    keepalive 32;
}

server {
    location /api/ {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
    }
}

keepalive 32는 Nginx와 백엔드 간의 커넥션을 풀링하여, 매 요청마다 TCP 핸드셰이크가 발생하는 것을 방지합니다. 이 설정 하나로 API 응답 지연이 10~30ms 개선되는 경우가 많습니다.

5. 보안 헤더와 접근 제한

성능 최적화와 함께 보안 설정도 필수입니다. 몇 줄의 헤더 추가로 크로스사이트 스크립팅(XSS), 클릭재킹, MIME 스니핑을 방지할 수 있습니다.

# 보안 헤더
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 Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

# DDoS/Brute Force 방지
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

location /api/login {
    limit_req zone=api burst=20 nodelay;
    proxy_pass http://backend;
}

limit_req_zone은 초당 10회 요청으로 제한하면서, burst=20 nodelay로 순간적인 트래픽 급증은 허용합니다. 이 설정은 API 엔드포인트 보호에 특히 효과적입니다.

6. Nginx vs 대안: 언제 다른 도구를 고려해야 할까

Nginx는 리버스 프록시와 정적 파일 서빙에 탁월하지만, 모든 상황에 최선은 아닙니다.

  • 순수 L4 로드밸런싱이 필요하다면: HAProxy가 TCP/UDP 레벨에서 더 유연하고 성능이 좋습니다. 특히 세션 기반 라우팅이 필요할 때 유리합니다.
  • 컨테이너 환경이라면: Caddy가 자동 HTTPS와 더 간단한 설정으로 인기를 얻고 있습니다. Docker 내부에서 Nginx를 쓸 때 발생하는 DNS 리졸빙 문제도 Caddy는 자동으로 처리합니다.
  • 대규모 트래픽 분산이라면: Cloudflare나 AWS ALB 같은 매니지드 서비스를 앞단에 두고, Nginx는 애플리케이션 레벨에서만 사용하는 구조가 운영 효율이 좋습니다.

요약: 체크리스트로 확인하는 핵심 설정

위에서 다룬 핵심 최적화를 한눈에 정리합니다.

카테고리설정기대 효과
Worker 튜닝worker_processes autoCPU 코어 활용 극대화
커넥션worker_connections 4096동시 처리 능력 향상
SSL 캐시ssl_session_cache shared:SSL:10m재연결 핸드셰이크 생략
OCSPssl_stapling on인증서 검사 레이턴시 제거
브라우저 캐시expires 1y; immutable조건부 요청 완전 차단
Gzipgzip_comp_level 4전송량 60~80% 감소
업스트림keepalive 32백엔드 커넥션 재사용
보안limit_req_zoneDDoS/Brute Force 방지

Nginx의 진정한 힘은 단순한 웹 서버를 넘어, 리버스 프록시, 로드밸런서, 캐시 서버를 하나의 설정 파일로 통합 제어할 수 있다는 데 있습니다. 이 글의 설정들을 하나씩 적용하면서, nginx -t로 문법을 검증하고 nginx -s reload로 무중단 반영해 보세요. 서버 응답 속도가 눈에 띄게 개선될 것입니다.