DevToolBox免费
博客

Nginx vs Apache 2026:该选哪个 Web 服务器?

13 分钟作者 DevToolBox

NginxApache 是世界上部署最广泛的两个 Web 服务器。它们合计为超过 60% 的网站提供服务。Nginx 以其事件驱动架构主导高流量站点,而 Apache 在共享主机和需要 .htaccess 配置的应用中仍然流行。

架构:根本区别

Nginx 和 Apache 之间的核心架构差异决定了它们的性能特征、资源使用和配置理念。

Apache:基于进程/线程 (MPM)

Apache 使用多处理模块 (MPM) 架构。默认 MPM 是 event,也可使用 preforkworker

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
PHP (通过 PHP-FPM)mod_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 使用集中式配置文件。没有 .htaccess 等效功能。

# 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:

  • 高流量 — 高效处理数千并发连接
  • 反向代理 — 代理到后端应用
  • 负载均衡 — 分发流量
  • 静态内容 — 最大速度提供静态文件
  • Docker/K8s — 轻量级容器友好

选择 Apache:

  • 共享主机 — .htaccess 按目录配置
  • WordPress/PHP — 传统 LAMP
  • 动态模块 — 运行时加载

两者一起使用

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 传统上用于 WordPress。但 Nginx 配置得当性能更好。

应该用 Nginx 作为 Apache 的反向代理吗?

这是一种流行的模式,可以兼得两者优势。

Caddy 和 Traefik 呢?

Caddy 适合简单部署。Traefik 适合容器编排。但 Nginx 和 Apache 仍然是最经过验证的选择。

相关工具和指南

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

{ }JSON Formatter

相关文章

Nginx 配置指南:从基础设置到生产部署

Nginx 完整配置指南。学习 server block、反向代理、SSL/TLS、负载均衡、缓存和安全头部配置。

Nginx 配置示例:反向代理、SSL 和静态站点

生产级 Nginx 配置示例:反向代理、SSL/TLS、静态文件服务、负载均衡和安全头。

Docker Compose 教程:从基础到生产就绪的技术栈

完整的 Docker Compose 教程:docker-compose.yml 语法、服务、网络、卷、环境变量、健康检查,以及 Node.js、Python、WordPress 的实际案例。