Nginx 和 Apache 是世界上部署最广泛的两个 Web 服务器。它们合计为超过 60% 的网站提供服务。Nginx 以其事件驱动架构主导高流量站点,而 Apache 在共享主机和需要 .htaccess 配置的应用中仍然流行。
架构:根本区别
Nginx 和 Apache 之间的核心架构差异决定了它们的性能特征、资源使用和配置理念。
Apache:基于进程/线程 (MPM)
Apache 使用多处理模块 (MPM) 架构。默认 MPM 是 event,也可使用 prefork 和 worker。
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.4 | Nginx 1.27 |
|---|---|---|
| 静态文件服务 (请求/秒) | ~15,000-25,000 | ~50,000-100,000 |
| 并发连接 (10K) | 性能下降 | 稳定 |
| 10K连接的内存 | ~300-600MB | ~30-50MB |
| PHP (通过 PHP-FPM) | mod_php 或 PHP-FPM | PHP-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 仍然是最经过验证的选择。
相关工具和指南
- JSON Formatter - Format Nginx/Apache JSON configs
- JSON to YAML Converter - Convert config formats
- Regex Tester - Test URL rewrite patterns
- Nginx Config Examples
- Nginx Location Block Regex Guide
- .htaccess Redirect Cheat Sheet
- DNS Record Types Guide