Apache HTTP Server 完全指南 / 性能调优
性能调优
Apache 性能调优是确保服务器高效运行的关键。本章介绍 Keep-Alive、压缩、连接池、MPM 调优等技术。
1. MPM 调优
1.1 选择合适的 MPM
# 查看当前 MPM
apachectl -V | grep MPM
# 切换 MPM (Debian/Ubuntu)
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo systemctl restart apache2
1.2 prefork MPM 调优
<IfModule mpm_prefork_module>
# 启动时创建的进程数
StartServers 5
# 最小空闲进程数
MinSpareServers 5
# 最大空闲进程数
MaxSpareServers 10
# 最大并发请求数
MaxRequestWorkers 256
# 每个进程最大请求数(0=无限)
MaxConnectionsPerChild 10000
</IfModule>
参数计算:
MaxRequestWorkers= 可用内存 / 每个进程内存使用- 每个进程约 10-50MB,根据模块和应用复杂度
1.3 worker MPM 调优
<IfModule mpm_worker_module>
# 启动时创建的进程数
StartServers 3
# 最小线程数
MinSpareThreads 75
# 最大线程数
MaxSpareThreads 250
# 每个进程的线程数
ThreadsPerChild 25
# 最大并发请求数
MaxRequestWorkers 400
# 每个进程最大请求数
MaxConnectionsPerChild 10000
</IfModule>
1.4 event MPM 调优(推荐)
<IfModule mpm_event_module>
# 启动时创建的进程数
StartServers 3
# 最小线程数
MinSpareThreads 75
# 最大线程数
MaxSpareThreads 250
# 每个进程的线程数
ThreadsPerChild 25
# 最大并发请求数
MaxRequestWorkers 400
# 每个进程最大请求数(防内存泄漏)
MaxConnectionsPerChild 10000
# Keep-Alive 超时线程数
AsyncRequestWorkerFactor 2
</IfModule>
1.5 MPM 配置公式
# 总内存 = 服务器内存 - 系统保留 - 其他服务
# 可用内存 = 总内存 * 0.8
# 每进程内存 = 使用 ps aux 查看 httpd RSS
# MaxRequestWorkers = 可用内存 / 每进程内存
# 示例:4GB 内存服务器
# 可用内存 = 4GB * 0.8 = 3.2GB
# 每进程内存 = 30MB
# MaxRequestWorkers = 3200MB / 30MB ≈ 106
# 监控进程内存
ps aux | grep httpd | awk '{sum+=$6; count++} END {print "平均内存: " sum/count/1024 " MB"}'
2. Keep-Alive 配置
2.1 基本配置
# 启用 Keep-Alive
KeepAlive On
# 最大请求数(每连接)
MaxKeepAliveRequests 100
# Keep-Alive 超时(秒)
KeepAliveTimeout 5
2.2 Keep-Alive 调优
# 高流量站点
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2
# 静态内容服务器
KeepAlive On
MaxKeepAliveRequests 1000
KeepAliveTimeout 10
# API 服务器
KeepAlive On
MaxKeepAliveRequests 50
KeepAliveTimeout 15
# 禁用 Keep-Alive(高并发场景)
KeepAlive Off
2.3 按 MIME 类型配置
# 使用 SetEnvIf
<IfModule mod_setenvif.c>
SetEnvIf Request_URI "\.(jpg|jpeg|png|gif|ico|css|js)$" static_content
</IfModule>
<IfModule mod_headers.c>
# 静态内容保持连接
Header set Connection keep-alive env=static_content
</IfModule>
3. 压缩配置
3.1 mod_deflate
<IfModule mod_deflate.c>
# 启用压缩
DeflateCompressionLevel 6
# 压缩类型
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/atom+xml
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE font/woff
AddOutputFilterByType DEFLATE font/woff2
# 排除旧浏览器
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
# 排除已压缩内容
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|zip|gz|bz2|rar|mp[34]|avi|wmv|flv)$ no-gzip dont-vary
# Vary 头
Header append Vary User-Agent env=!dont-vary
</IfModule>
3.2 mod_brotli(更高效)
# 启用 Brotli
sudo a2enmod brotli
sudo systemctl reload apache2
<IfModule mod_brotli.c>
# 启用 Brotli
BrotliCompressionQuality 6
# Brotli 类型
AddOutputFilterByType BROTLI_COMPRESS text/html
AddOutputFilterByType BROTLI_COMPRESS text/css
AddOutputFilterByType BROTLI_COMPRESS text/javascript
AddOutputFilterByType BROTLI_COMPRESS application/javascript
AddOutputFilterByType BROTLI_COMPRESS application/json
AddOutputFilterByType BROTLI_COMPRESS application/xml
AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
# Brotli 优先于 gzip
BrotliAlterETag NoChange
</IfModule>
3.3 压缩级别对比
| 级别 | 压缩率 | CPU 使用 | 适用场景 |
|---|---|---|---|
| 1 | 低 | 低 | CPU 受限 |
| 6 | 中 | 中 | 默认推荐 |
| 9 | 高 | 高 | 带宽受限 |
4. 静态文件优化
4.1 浏览器缓存
<IfModule mod_expires.c>
ExpiresActive On
# 默认过期时间
ExpiresDefault "access plus 1 month"
# 按类型设置
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType font/woff "access plus 1 year"
</IfModule>
<IfModule mod_headers.c>
# Cache-Control 头
<LocationMatch "\.(css|js|jpg|jpeg|png|gif|ico|webp|svg|woff|woff2)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</LocationMatch>
</IfModule>
4.2 ETag 配置
# 方案 1:禁用 ETag(推荐使用 Last-Modified)
Header unset ETag
FileETag None
# 方案 2:仅使用 MTime
FileETag MTime
# 方案 3:MTime + Size
FileETag MTime Size
4.3 静态文件服务优化
# 专用静态文件服务器配置
<VirtualHost *:80>
ServerName static.example.com
DocumentRoot /var/www/static
# 禁用 .htaccess
AllowOverride None
# 简化选项
Options -Indexes -FollowSymLinks -Includes -ExecCGI
# Keep-Alive
KeepAlive On
MaxKeepAliveRequests 1000
KeepAliveTimeout 10
# 压缩
<IfModule mod_deflate.c>
DeflateCompressionLevel 9
AddOutputFilterByType DEFLATE text/css application/javascript image/svg+xml
</IfModule>
# 缓存
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 year"
Header set Cache-Control "public, max-age=31536000, immutable"
</IfModule>
# 禁止脚本执行
<Directory "/var/www/static">
php_flag engine off
RemoveHandler .php .phtml .php3 .php4 .php5
RemoveType .php .phtml .php3 .php4 .php5
</Directory>
</VirtualHost>
5. 连接优化
5.1 超时设置
# 连接超时(秒)
Timeout 300
# Keep-Alive 超时
KeepAliveTimeout 5
# 代理超时
ProxyTimeout 300
# 请求超时(mod_reqtimeout)
<IfModule mod_reqtimeout.c>
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
5.2 发送缓冲区
# 启用发送缓冲区
EnableSendfile On
EnableMMAP On
# TCP_NODELAY
SetEnv nokeepalive
5.3 网络优化
# 系统级别优化(/etc/sysctl.conf)
# net.core.somaxconn = 65535
# net.ipv4.tcp_max_tw_buckets = 65535
# net.ipv4.tcp_tw_reuse = 1
# net.ipv4.tcp_fin_timeout = 30
# net.ipv4.tcp_keepalive_time = 300
# net.ipv4.tcp_keepalive_probes = 5
# net.ipv4.tcp_keepalive_intvl = 15
# net.core.netdev_max_backlog = 65535
6. 反向代理优化
6.1 代理连接池
# 保持后端连接
<Proxy http://backend-cluster>
ProxySet keepalive=On
</Proxy>
# 连接池大小
ProxyPass / http://localhost:8080/ keepalive=On max=100 smax=10 timeout=300
# 连接超时
ProxyPass / http://localhost:8080/ connectiontimeout=5 timeout=300
# 重试设置
ProxyPass / http://localhost:8080/ retry=30 acquire=3000
6.2 代理缓存优化
# 启用代理缓存
CacheRoot /var/cache/apache2/proxy
CacheEnable disk /
CacheDefaultExpire 60
CacheMaxExpire 3600
CacheLastModifiedFactor 0.1
# 缓存锁
CacheLock on
CacheLockPath /tmp/mod_cache-lock
CacheLockMaxAge 5
7. PHP 性能优化
7.1 PHP-FPM 配置
# 使用 Unix Socket(比 TCP 更快)
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
</FilesMatch>
# 或使用 TCP
<FilesMatch \.php$>
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>
7.2 PHP-FPM 进程池
; /etc/php/8.2/fpm/pool.d/www.conf
[www]
user = www-data
group = www-data
; 动态进程管理
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
; 慢日志
slowlog = /var/log/php-fpm-slow.log
request_slowlog_timeout = 5s
8. 监控与基准测试
8.1 性能监控
# Apache 服务器状态
<Location "/server-status">
SetHandler server-status
Require ip 127.0.0.1
</Location>
# 访问 http://localhost/server-status
# 实时监控
watch -n 1 "curl -s http://localhost/server-status?auto"
# 监控脚本
#!/bin/bash
while true; do
echo "=== $(date) ==="
curl -s http://localhost/server-status?auto
echo ""
sleep 5
done
8.2 基准测试
# 使用 ab (Apache Bench)
ab -n 10000 -c 100 http://localhost/
# 使用 wrk
wrk -t12 -c400 -d30s http://localhost/
# 使用 siege
siege -c 100 -t 60s http://localhost/
# 带并发的详细测试
ab -n 10000 -c 100 -k -H "Accept-Encoding: gzip, deflate" http://localhost/
# 测试结果分析
# Requests per second: 吞吐量
# Time per request: 响应时间
# Transfer rate: 传输速率
8.3 性能指标
| 指标 | 目标值 | 说明 |
|---|---|---|
| 响应时间 | < 200ms | 平均响应时间 |
| 吞吐量 | > 1000 req/s | 每秒请求数 |
| 错误率 | < 0.1% | 错误请求比例 |
| CPU 使用 | < 70% | 平均 CPU 使用率 |
| 内存使用 | < 80% | 内存使用率 |
| 并发连接 | 按需 | 同时在线连接数 |
9. 业务场景
9.1 高流量网站配置
# MPM 配置
<IfModule mpm_event_module>
StartServers 4
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 10000
</IfModule>
# Keep-Alive
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2
# 压缩
DeflateCompressionLevel 6
# 缓存
CacheRoot /var/cache/apache2/mod_cache_disk
CacheEnable disk /
CacheDefaultExpire 60
9.2 API 服务器配置
# 优化 JSON 响应
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE application/xml
</IfModule>
# 代理优化
ProxyPass /api http://localhost:3000/api keepalive=On timeout=60
# 日志优化
CustomLog /var/log/apache2/api.log "%h %t \"%r\" %>s %b %D"
10. 注意事项
- 逐步调整:每次只调整一个参数,观察效果
- 监控告警:调整后密切监控服务器状态
- 压力测试:调整前进行基准测试
- 备份配置:修改前备份配置文件
- 文档记录:记录每次调整和效果
11. 扩展阅读
12. 总结
Apache 性能调优是一个系统工程:
- MPM 调优:选择合适的 MPM 和参数
- 连接优化:Keep-Alive、超时设置
- 压缩优化:减少传输数据量
- 缓存优化:减少重复计算和请求
- 监控基准:持续监控和测试
合理的性能调优可以显著提升服务器处理能力。