Nginx 성능 최적화가 중요한 이유
Nginx는 리버스 프록시, 정적 파일 서빙, 로드밸런싱을 동시에 담당하는 웹 인프라의 핵심입니다. 기본 설정만으로도 동작하지만, 프록시 캐시, Gzip 압축, Upstream 튜닝을 적용하면 응답 속도와 서버 부하를 획기적으로 개선할 수 있습니다.
Proxy Cache 설정
Nginx의 proxy_cache는 백엔드 응답을 디스크/메모리에 캐싱하여 동일 요청 시 백엔드를 호출하지 않습니다.
# /etc/nginx/nginx.conf (http 블록)
http {
# 캐시 존 정의: 10MB 메모리 키 영역, 최대 1GB 디스크
proxy_cache_path /var/cache/nginx/api
levels=1:2
keys_zone=api_cache:10m
max_size=1g
inactive=60m
use_temp_path=off;
proxy_cache_path /var/cache/nginx/static
levels=1:2
keys_zone=static_cache:5m
max_size=2g
inactive=7d;
}
# server 블록에서 캐시 적용
server {
listen 443 ssl http2;
server_name api.example.com;
# API 응답 캐시
location /api/products {
proxy_pass http://backend;
proxy_cache api_cache;
proxy_cache_valid 200 10m; # 200 응답: 10분
proxy_cache_valid 404 1m; # 404 응답: 1분
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_use_stale error timeout updating
http_500 http_502 http_503;
# 캐시 상태 헤더 (디버깅용)
add_header X-Cache-Status $upstream_cache_status;
}
# 정적 파일 캐시 (장기)
location /static/ {
proxy_pass http://cdn_backend;
proxy_cache static_cache;
proxy_cache_valid 200 7d;
proxy_ignore_headers Cache-Control Expires;
}
}
| X-Cache-Status | 의미 |
|---|---|
| HIT | 캐시에서 응답 |
| MISS | 캐시 없음, 백엔드 호출 |
| STALE | 만료된 캐시 사용 (백엔드 장애 시) |
| UPDATING | 갱신 중, 이전 캐시 제공 |
| BYPASS | 캐시 우회 (proxy_cache_bypass) |
캐시 우회와 퍼지
# 로그인 사용자는 캐시 우회
proxy_cache_bypass $http_authorization;
proxy_no_cache $http_authorization;
# 특정 쿠키가 있으면 캐시 안 함
map $http_cookie $no_cache {
default 0;
"~*session_id" 1;
}
proxy_no_cache $no_cache;
# 캐시 퍼지 (nginx-cache-purge 모듈)
location ~ /purge(/.*) {
allow 10.0.0.0/8;
deny all;
proxy_cache_purge api_cache "$scheme$request_method$host$1";
}
Gzip·Brotli 압축
응답 본문을 압축하면 전송 크기를 60~80% 줄일 수 있습니다.
http {
# Gzip 압축
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5; # 1~9, 5가 성능/압축률 균형점
gzip_min_length 256; # 256B 이하는 압축 안 함
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
image/svg+xml
font/woff2;
# Brotli 압축 (ngx_brotli 모듈 필요, Gzip보다 15~20% 더 작음)
brotli on;
brotli_comp_level 4;
brotli_types
text/plain
text/css
application/javascript
application/json
image/svg+xml;
}
| 설정 | 권장값 | 이유 |
|---|---|---|
| gzip_comp_level | 4~6 | 7 이상은 CPU 대비 압축률 향상 미미 |
| gzip_min_length | 256 | 작은 응답은 압축 오버헤드가 더 큼 |
| gzip_proxied | any | 프록시된 요청도 압축 |
Upstream 로드밸런싱 튜닝
Nginx 리버스 프록시 실전 가이드에서 기본 설정을 다뤘다면, 여기서는 성능 최적화에 집중합니다.
upstream backend {
# 최소 연결 수 기반 라우팅
least_conn;
# keepalive 커넥션 풀
keepalive 32;
keepalive_timeout 60s;
keepalive_requests 1000;
server 10.0.1.10:8080 weight=3 max_fails=3 fail_timeout=30s;
server 10.0.1.11:8080 weight=3 max_fails=3 fail_timeout=30s;
server 10.0.1.12:8080 weight=1 backup; # 백업 서버
}
server {
location /api/ {
proxy_pass http://backend;
# Upstream keepalive 필수 설정
proxy_http_version 1.1;
proxy_set_header Connection "";
# 타임아웃 설정
proxy_connect_timeout 5s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
# 버퍼링 최적화
proxy_buffering on;
proxy_buffer_size 8k;
proxy_buffers 8 8k;
proxy_busy_buffers_size 16k;
# 실패 시 다음 서버로 재시도
proxy_next_upstream error timeout http_502 http_503;
proxy_next_upstream_tries 2;
proxy_next_upstream_timeout 10s;
}
}
로드밸런싱 알고리즘
| 알고리즘 | 설정 | 적합한 상황 |
|---|---|---|
| Round Robin | 기본값 | 서버 스펙 동일, 균등 분배 |
| Least Connections | least_conn |
요청 처리 시간이 불균일 |
| IP Hash | ip_hash |
세션 어피니티 필요 |
| Random Two | random two least_conn |
대규모 클러스터, 부하 분산 최적 |
Worker·Connection 튜닝
# /etc/nginx/nginx.conf
worker_processes auto; # CPU 코어 수만큼 자동 설정
worker_rlimit_nofile 65535; # 파일 디스크립터 한도
events {
worker_connections 4096; # 워커당 동시 연결 수
multi_accept on; # 한 번에 여러 연결 수락
use epoll; # Linux epoll 사용
}
http {
sendfile on;
tcp_nopush on; # sendfile과 함께 사용, 패킷 최적화
tcp_nodelay on; # 작은 패킷 즉시 전송
# 클라이언트 타임아웃
client_body_timeout 12s;
client_header_timeout 12s;
send_timeout 10s;
# 연결 재사용
keepalive_timeout 65s;
keepalive_requests 100;
# 요청 크기 제한
client_max_body_size 10m;
client_body_buffer_size 128k;
}
최대 동시 연결 수 = worker_processes × worker_connections. 4코어에 4096이면 최대 16,384 동시 연결을 처리합니다.
보안 헤더와 SSL 최적화
Nginx Rate Limiting 심화와 함께 적용하면 완성도 높은 보안 설정이 됩니다.
server {
# SSL 최적화
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_protocols TLSv1.3 TLSv1.2;
ssl_prefer_server_ciphers off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 1.1.1.1 valid=300s;
# 보안 헤더
add_header X-Frame-Options DENY 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=63072000; includeSubDomains; preload" always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
}
정리
Nginx 성능 최적화는 Proxy Cache로 백엔드 부하를 줄이고, Gzip/Brotli로 전송량을 최소화하며, Upstream keepalive로 연결 오버헤드를 제거하는 세 축으로 구성됩니다. Worker 수와 연결 한도를 서버 스펙에 맞게 튜닝하고, SSL Session Cache와 OCSP Stapling으로 TLS 핸드셰이크 비용을 줄이면 체감 성능이 크게 향상됩니다.