DevToolBoxFREE
BlogAdvertise

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은 컨테이너 오케스트레이션에 적합합니다.

관련 도구 및 가이드

도움이 되었나요?

Stay Updated

Get weekly dev tips and new tool announcements.

No spam. Unsubscribe anytime.

Partner Picks

Sponsor this article

Place your product next to this developer topic with tracked clicks.

Ask about article sponsorship

This site uses cookies for analytics and to display ads. By continuing to browse, you agree. Privacy Policy