DevToolBox무료
블로그

Nginx vs Apache 2026: 어떤 웹 서버를 선택해야 할까?

13분by DevToolBox

NginxApache는 세계에서 가장 널리 배포된 웹 서버입니다.

아키텍처: 근본적인 차이

Nginx와 Apache의 핵심 아키텍처 차이가 성능을 결정합니다.

Apache: 프로세스/스레드 기반

Apache는 멀티 프로세싱 모듈(MPM) 아키텍처를 사용합니다.

Apache Architecture (Process/Thread Model):

  Master Process
  ├── Worker Process 1
  │   ├── Thread 1 → handles connection A
  │   ├── Thread 2 → handles connection B
  │   └── Thread N → handles connection C
  ├── Worker Process 2
  │   ├── Thread 1 → handles connection D
  │   └── Thread N → handles connection E
  └── Worker Process N...

  MPM Modes:
  - prefork: 1 process per connection (safe for non-thread-safe modules like mod_php)
  - worker:  threads within process pool (more efficient)
  - event:   listener thread for keep-alive (best for Apache 2.4+)

Nginx: 이벤트 기반, 논블로킹

Nginx는 비동기 이벤트 기반 아키텍처를 사용합니다.

Nginx Architecture (Event-Driven):

  Master Process (reads config, manages workers)
  ├── Worker Process 1 (single thread, event loop)
  │   └── Event Loop: handles 1000s of connections via epoll/kqueue
  │       ├── Connection A (non-blocking I/O)
  │       ├── Connection B (non-blocking I/O)
  │       ├── Connection C (non-blocking I/O)
  │       └── ... (thousands more)
  ├── Worker Process 2 (single thread, event loop)
  │   └── Event Loop: handles 1000s more connections
  └── Worker Process N (typically = CPU cores)

  Key: No thread-per-connection overhead
  Result: 10K+ connections with ~30-50MB RAM

성능 벤치마크

워크로드 유형에 따라 다릅니다.

지표Apache 2.4Nginx 1.27
정적 파일 (요청/초)~15,000-25,000~50,000-100,000
동시 연결 (10K)성능 저하안정적
10K 연결 메모리~300-600MB~30-50MB
PHPmod_php/PHP-FPMPHP-FPM
리버스 프록시양호우수
SSL/TLS양호우수

설정 비교

Apache와 Nginx는 설정 방식이 다릅니다.

Apache: .htaccess + httpd.conf

Apache는 .htaccess를 통한 분산 설정을 지원합니다.

# Apache Virtual Host Configuration (/etc/apache2/sites-available/example.conf)
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example/public

    <Directory /var/www/example/public>
        AllowOverride All
        Require all granted
        Options -Indexes +FollowSymLinks
    </Directory>

    # Enable mod_rewrite
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

    # PHP via mod_php (prefork MPM required)
    <FilesMatch \.php$>
        SetHandler application/x-httpd-php
    </FilesMatch>

    # Or PHP via PHP-FPM (recommended with event MPM)
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
    </FilesMatch>

    # Logging
    ErrorLog ${APACHE_LOG_DIR}/example-error.log
    CustomLog ${APACHE_LOG_DIR}/example-access.log combined
</VirtualHost>

# .htaccess file (per-directory, no restart needed)
# /var/www/example/public/.htaccess
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]

Nginx: 중앙 집중식 설정

Nginx는 중앙 집중식 설정 파일을 사용합니다.

# Nginx Server Block (/etc/nginx/sites-available/example.conf)
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    root /var/www/example/public;
    index index.html index.php;

    # SSL
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    # Static files with caching
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # PHP via PHP-FPM
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # SPA fallback (equivalent to .htaccess rewrite)
    location / {
        try_files $uri $uri/ /index.html;
    }

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;

    # Gzip compression
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;
    gzip_min_length 1000;

    access_log /var/log/nginx/example-access.log;
    error_log /var/log/nginx/example-error.log;
}

기능 비교

Feature              Apache 2.4                   Nginx 1.27
-------------------------------------------------------------------
Module System        Dynamic (load at runtime)     Static + dynamic (since 1.9.11)
.htaccess            Full support                  Not supported
URL Rewriting        mod_rewrite (regex)            rewrite directive (simpler)
Reverse Proxy        mod_proxy + mod_proxy_http     Native proxy_pass
Load Balancing       mod_proxy_balancer             Native upstream module
Caching              mod_cache                      Native proxy_cache + FastCGI
WebSocket            mod_proxy_wstunnel             Native support
HTTP/2               mod_http2                      Native
HTTP/3 (QUIC)        Experimental                   Native since 1.25.0
Scripting            mod_lua                        OpenResty (Lua), njs (JS)
Config Reload        Restart required               Graceful reload (zero downtime)
Per-dir Config       .htaccess (runtime)            Not available
License              Apache 2.0                     BSD 2-Clause

사용 시나리오

Nginx를 선택할 때:

  • 높은 트래픽
  • 리버스 프록시
  • 로드 밸런싱
  • 정적 콘텐츠

Apache를 선택할 때:

  • 공유 호스팅
  • WordPress/PHP
  • 동적 모듈

함께 사용

Nginx를 Apache 앞의 리버스 프록시로 사용하는 것이 인기 있는 아키텍처입니다.

# Nginx as reverse proxy in front of Apache
# /etc/nginx/sites-available/example.conf

upstream apache_backend {
    server 127.0.0.1:8080;  # Apache listens on port 8080
}

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;

    # Nginx serves static files directly (fast)
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff2)$ {
        root /var/www/example/public;
        expires 30d;
        access_log off;
    }

    # Dynamic requests go to Apache (PHP, .htaccess)
    location / {
        proxy_pass http://apache_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;
    }
}

리버스 프록시 설정

# Nginx reverse proxy to Node.js / Python / Go backend
upstream app_servers {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
    keepalive 64;
}

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 "";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # WebSocket support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

로드 밸런싱

# Nginx Load Balancing Strategies

# Round Robin (default)
upstream backend_rr {
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
    server 10.0.0.3:8080;
}

# Weighted Round Robin
upstream backend_weighted {
    server 10.0.0.1:8080 weight=5;   # gets 5x traffic
    server 10.0.0.2:8080 weight=3;
    server 10.0.0.3:8080 weight=1;
}

# Least Connections
upstream backend_least {
    least_conn;
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
}

# IP Hash (sticky sessions)
upstream backend_ip {
    ip_hash;
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
}

# Health checks and failover
upstream backend_health {
    server 10.0.0.1:8080 max_fails=3 fail_timeout=30s;
    server 10.0.0.2:8080 max_fails=3 fail_timeout=30s;
    server 10.0.0.3:8080 backup;  # only used when others fail
}

SSL/TLS 설정

# Nginx SSL/TLS Best Practices (2026)
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    # Modern TLS configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 1.1.1.1 8.8.8.8 valid=300s;

    # Session resumption
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # HSTS (15768000 seconds = 6 months)
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;
}

보안 비교

두 서버 모두 우수한 보안 기록을 가지고 있습니다.

Security Aspect          Apache                    Nginx
-----------------------------------------------------------------
CVE History              More CVEs (larger surface)  Fewer CVEs (smaller codebase)
.htaccess Risk           Can expose config errors    N/A (no .htaccess)
Default Config           Permissive                  Restrictive
Module Surface           Large (many loaded)          Minimal (compile what you need)
Rate Limiting            mod_ratelimit               limit_req / limit_conn (native)
WAF Integration          mod_security (mature)        ModSecurity + NAXSI
Access Control           .htaccess / <Directory>      allow/deny directives
Request Size Limits      LimitRequestBody             client_max_body_size

자주 묻는 질문

Nginx가 Apache보다 빠른가요?

정적 콘텐츠와 높은 동시성에서 Nginx가 빠릅니다. 동적 콘텐츠에서는 비슷합니다.

Nginx가 Apache를 완전히 대체할 수 있나요?

대부분의 경우 가능합니다. .htaccess가 필요한 경우 제외.

WordPress에는 어느 것이 좋은가요?

Apache가 전통적이지만, Nginx가 적절히 설정되면 더 빠릅니다.

Nginx를 Apache의 리버스 프록시로 사용해야 하나요?

두 가지의 장점을 모두 얻을 수 있는 인기 있는 패턴입니다.

Caddy와 Traefik은?

Caddy는 간단한 배포에, Traefik은 컨테이너 오케스트레이션에 적합합니다.

관련 도구 및 가이드

𝕏 Twitterin LinkedIn
도움이 되었나요?

최신 소식 받기

주간 개발 팁과 새 도구 알림을 받으세요.

스팸 없음. 언제든 구독 해지 가능.

Try These Related Tools

{ }JSON Formatter

Related Articles

Nginx 설정 가이드: 기본 설정부터 프로덕션까지

Nginx 완전 설정 가이드. 서버 블록, 리버스 프록시, SSL/TLS, 로드 밸런싱, 캐싱 설정을 배우세요.

Nginx 설정 예시: 리버스 프록시, SSL, 정적 사이트

프로덕션용 Nginx 설정 예시: 리버스 프록시, SSL/TLS, 정적 파일, 로드 밸런싱.

Docker Compose 튜토리얼: 기초부터 프로덕션 스택까지

완전한 Docker Compose 튜토리얼: docker-compose.yml 구문, 서비스, 네트워크, 볼륨, 환경변수, 헬스체크, Node.js/Python/WordPress 실전 예제.