强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

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 使用适用场景
1CPU 受限
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. 注意事项

  1. 逐步调整:每次只调整一个参数,观察效果
  2. 监控告警:调整后密切监控服务器状态
  3. 压力测试:调整前进行基准测试
  4. 备份配置:修改前备份配置文件
  5. 文档记录:记录每次调整和效果

11. 扩展阅读

12. 总结

Apache 性能调优是一个系统工程:

  • MPM 调优:选择合适的 MPM 和参数
  • 连接优化:Keep-Alive、超时设置
  • 压缩优化:减少传输数据量
  • 缓存优化:减少重复计算和请求
  • 监控基准:持续监控和测试

合理的性能调优可以显著提升服务器处理能力。