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

Apache HTTP Server 完全指南 / 缓存配置

缓存配置

Apache 提供了多种缓存机制,可以显著提高网站性能和用户体验。

1. 缓存类型

1.1 Apache 缓存模块

模块功能
mod_cache缓存核心框架
mod_cache_disk磁盘缓存存储
mod_cache_socache共享对象缓存(内存)
mod_expires过期头控制
mod_headersHTTP 头操作
mod_file_cache文件缓存

1.2 缓存层次

客户端缓存 → CDN 缓存 → Apache 缓存 → 后端应用

2. mod_cache 基础

2.1 启用模块

# 启用缓存模块
sudo a2enmod cache
sudo a2enmod cache_disk
sudo a2enmod cache_socache
sudo a2enmod socache_shmcb
sudo a2enmod expires
sudo a2enmod headers
sudo systemctl reload apache2

2.2 磁盘缓存配置

# /etc/apache2/conf-available/cache-disk.conf

<IfModule mod_cache.c>
    <IfModule mod_cache_disk.c>
        # 缓存根目录
        CacheRoot /var/cache/apache2/mod_cache_disk
        
        # 缓存目录深度
        CacheDirLevels 2
        CacheDirLength 1
        
        # 缓存大小限制
        CacheDefaultExpire 3600
        CacheMaxExpire 86400
        CacheLastModifiedFactor 0.1
        
        # 缓存锁
        CacheLock on
        CacheLockPath /tmp/mod_cache-lock
        CacheLockMaxAge 5
        
        # 缓存大小
        CacheMaxFileSize 1000000
        CacheMinFileSize 1
    </IfModule>
</IfModule>

2.3 共享内存缓存

<IfModule mod_cache.c>
    <IfModule mod_cache_socache.c>
        # 使用共享内存
        CacheSocache shmcb
        CacheSocacheMaxSize 102400
        
        # 默认过期时间
        CacheDefaultExpire 300
        CacheMaxExpire 86400
        CacheIgnoreNoLastMod On
        CacheIgnoreQueryString On
        CacheIgnoreCacheControl On
        CacheStoreExpired On
        CacheStoreNoStore On
    </IfModule>
</IfModule>

3. 缓存规则

3.1 基本缓存规则

# 缓存静态文件
<IfModule mod_cache.c>
    CacheDefaultExpire 3600
    
    # 缓存图片
    <LocationMatch "\.(jpg|jpeg|png|gif|ico|webp)$">
        CacheEnable disk
        CacheDefaultExpire 604800
        Header set Cache-Control "public, max-age=604800"
    </LocationMatch>
    
    # 缓存 CSS/JS
    <LocationMatch "\.(css|js)$">
        CacheEnable disk
        CacheDefaultExpire 86400
        Header set Cache-Control "public, max-age=86400"
    </LocationMatch>
    
    # 缓存字体
    <LocationMatch "\.(woff|woff2|ttf|eot|svg)$">
        CacheEnable disk
        CacheDefaultExpire 604800
        Header set Cache-Control "public, max-age=604800"
    </LocationMatch>
</IfModule>

3.2 条件缓存

<IfModule mod_cache.c>
    # 不缓存动态内容
    CacheDisable /api
    CacheDisable /admin
    CacheDisable /login
    
    # 不缓存特定文件
    <LocationMatch "\.(php|cgi|pl|py)$">
        CacheDisable on
    </LocationMatch>
    
    # 根据响应头缓存
    CacheIgnoreCacheControl Off
    CacheIgnoreNoLastMod On
    CacheIgnoreQueryString Off
    CacheIgnoreHostname On
    
    # 仅缓存成功响应
    CacheDetailHeader on
</IfModule>

3.3 代理缓存

# 反向代理缓存
<IfModule mod_cache.c>
    CacheRoot /var/cache/apache2/proxy_cache
    CacheDefaultExpire 60
    CacheMaxExpire 3600
    CacheLastModifiedFactor 0.1
    
    # 启用代理缓存
    CacheEnable disk /
    
    # 不缓存特定请求
    CacheDisable /api/dynamic
    CacheDisable /api/auth
    
    # Vary 头处理
    CacheIgnoreNoLastMod On
    CacheIgnoreQueryString Off
    CacheVary By Accept-Encoding
</IfModule>

4. mod_expires 详解

4.1 启用模块

sudo a2enmod expires
sudo a2enmod headers
sudo systemctl reload apache2

4.2 基本配置

<IfModule mod_expires.c>
    # 启用过期控制
    ExpiresActive On
    
    # 默认过期时间
    ExpiresDefault "access plus 1 month"
    
    # 按 MIME 类型设置
    ExpiresByType text/html "access plus 0 seconds"
    ExpiresByType text/css "access plus 1 year"
    ExpiresByType application/javascript "access plus 1 year"
    ExpiresByType application/json "access plus 0 seconds"
    
    # 图片
    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 image/x-icon "access plus 1 year"
    
    # 字体
    ExpiresByType font/woff "access plus 1 year"
    ExpiresByType font/woff2 "access plus 1 year"
    ExpiresByType application/font-woff "access plus 1 year"
    ExpiresByType application/font-woff2 "access plus 1 year"
    
    # 视频/音频
    ExpiresByType video/mp4 "access plus 1 year"
    ExpiresByType audio/mpeg "access plus 1 year"
    
    # 文档
    ExpiresByType application/pdf "access plus 1 month"
</IfModule>

4.3 缓存控制头

<IfModule mod_headers.c>
    # Cache-Control 头
    <LocationMatch "\.(css|js|jpg|jpeg|png|gif|ico|webp|woff|woff2)$">
        Header set Cache-Control "public, max-age=31536000, immutable"
    </LocationMatch>
    
    <LocationMatch "\.(html|htm)$">
        Header set Cache-Control "no-cache, must-revalidate"
    </LocationMatch>
    
    <LocationMatch "\.(php|cgi|pl)$">
        Header set Cache-Control "no-store, no-cache, must-revalidate"
    </LocationMatch>
    
    # ETag 控制
    Header unset ETag
    
    # Last-Modified 控制
    FileETag None
</IfModule>

5. 浏览器缓存策略

5.1 缓存策略表

资源类型策略max-age
HTMLno-cache0
CSS/JSimmutable1 年
图片public1 年
字体immutable1 年
API 响应no-store0
静态文件public1 月

5.2 版本化文件名

# 使用文件哈希的静态资源(长期缓存)
<IfModule mod_headers.c>
    # 包含哈希的文件名
    <LocationMatch "\.[a-f0-9]{8}\.(css|js|jpg|png|gif|woff2)$">
        Header set Cache-Control "public, max-age=31536000, immutable"
    </LocationMatch>
</IfModule>

5.3 条件请求

# ETag 配置
<IfModule mod_headers.c>
    # 禁用 ETag(使用 Last-Modified)
    Header unset ETag
    FileETag None
    
    # 或者启用 ETag
    FileETag MTime Size
</IfModule>

6. 反向代理缓存

6.1 代理缓存配置

# /etc/apache2/conf-available/proxy-cache.conf

<IfModule mod_cache.c>
    # 缓存根目录
    CacheRoot /var/cache/apache2/proxy_cache
    
    # 缓存目录结构
    CacheDirLevels 2
    CacheDirLength 1
    
    # 默认缓存时间
    CacheDefaultExpire 60
    CacheMaxExpire 3600
    CacheLastModifiedFactor 0.1
    
    # 缓存锁
    CacheLock on
    CacheLockPath /tmp/proxy_cache-lock
    CacheLockMaxAge 5
    
    # 忽略特定头
    CacheIgnoreNoLastMod On
    CacheIgnoreQueryString Off
    CacheIgnoreCacheControl Off
    
    # 存储设置
    CacheStoreExpired On
    CacheStoreNoStore On
    
    # 详细头
    CacheDetailHeader on
    CacheHeader on
</IfModule>

6.2 按路径缓存

<VirtualHost *:80>
    ServerName www.example.com
    
    # 启用缓存
    CacheEnable disk /
    
    # API 不缓存
    CacheDisable /api
    
    # 静态资源长期缓存
    <LocationMatch "\.(css|js|jpg|png|gif)$">
        CacheDefaultExpire 604800
        Header set Cache-Control "public, max-age=604800"
    </LocationMatch>
    
    # 动态内容短期缓存
    <Location "/">
        CacheDefaultExpire 60
    </Location>
    
    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/
</VirtualHost>

6.3 清除缓存

# 启用缓存清除(需要 mod_cache_disk)
# 使用第三方模块 mod_cache_purge

# 安装
sudo apt install libapache2-mod-cache-purge
sudo a2enmod cache_purge

# 配置清除接口
<Location "/purge">
    SetHandler purge
    Require ip 127.0.0.1
    Require ip 192.168.1.0/24
</Location>

# 使用方法
# curl -X PURGE http://example.com/path/to/clear

7. CDN 集成

7.1 CDN 回源配置

<VirtualHost *:80>
    ServerName origin.example.com
    
    # CDN 头传递
    <IfModule mod_headers.c>
        # 传递 CDN 头
        RequestHeader set X-Forwarded-Proto "https"
        RequestHeader set X-Real-IP "%{REMOTE_ADDR}s"
    </IfModule>
    
    # 源站缓存控制
    <IfModule mod_expires.c>
        ExpiresActive On
        
        # 静态资源长期缓存
        <LocationMatch "\.(css|js|jpg|png|gif|woff2)$">
            ExpiresDefault "access plus 1 year"
            Header set Cache-Control "public, max-age=31536000, immutable"
        </LocationMatch>
        
        # 动态内容
        <LocationMatch "\.(php|html)$">
            ExpiresDefault "access plus 0 seconds"
            Header set Cache-Control "no-cache, must-revalidate"
        </LocationMatch>
    </IfModule>
    
    # Vary 头
    Header append Vary Accept-Encoding
</VirtualHost>

7.2 边缘缓存配置

# 边缘服务器配置
<VirtualHost *:80>
    ServerName edge.example.com
    
    CacheRoot /var/cache/apache2/edge
    CacheEnable disk /
    CacheDefaultExpire 300
    CacheMaxExpire 3600
    
    # 回源配置
    ProxyPass / http://origin.example.com/
    ProxyPassReverse / http://origin.example.com/
</VirtualHost>

8. 性能优化

8.1 缓存性能配置

# /etc/apache2/conf-available/cache-performance.conf

<IfModule mod_cache.c>
    # 内存缓存(快速)
    <IfModule mod_cache_socache.c>
        CacheSocache shmcb
        CacheSocacheMaxSize 102400
        CacheDefaultExpire 300
    </IfModule>
    
    # 磁盘缓存(持久)
    <IfModule mod_cache_disk.c>
        CacheRoot /var/cache/apache2/mod_cache_disk
        CacheDirLevels 2
        CacheDirLength 1
        CacheMaxFileSize 10485760
        CacheMinFileSize 1
    </IfModule>
    
    # 缓存锁
    CacheLock on
    CacheLockPath /tmp/mod_cache-lock
    CacheLockMaxAge 5
</IfModule>

8.2 缓存监控

# 查看缓存目录大小
du -sh /var/cache/apache2/

# 监控缓存命中
tail -f /var/log/apache2/access.log | grep "X-Cache"

# 缓存统计脚本
#!/bin/bash
CACHE_DIR="/var/cache/apache2/mod_cache_disk"
echo "缓存文件数: $(find $CACHE_DIR -type f | wc -l)"
echo "缓存大小: $(du -sh $CACHE_DIR | cut -f1)"
echo "缓存目录数: $(find $CACHE_DIR -type d | wc -l)"

9. 业务场景

9.1 静态资源加速

# 静态资源服务器
<VirtualHost *:80>
    ServerName static.example.com
    DocumentRoot /var/www/static
    
    # 长期缓存
    <IfModule mod_expires.c>
        ExpiresActive On
        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"
    </IfModule>
    
    # 压缩
    <IfModule mod_deflate.c>
        AddOutputFilterByType DEFLATE text/css application/javascript
    </IfModule>
</VirtualHost>

9.2 API 响应缓存

<VirtualHost *:80>
    ServerName api.example.com
    
    # 启用缓存
    CacheEnable disk /api/products
    CacheDefaultExpire 300
    
    # 不缓存需要认证的请求
    CacheDisable /api/users
    CacheDisable /api/orders
    
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
</VirtualHost>

10. 注意事项

  1. 缓存一致性:确保缓存失效机制正常工作
  2. 内存使用:监控缓存内存使用,避免 OOM
  3. 磁盘空间:定期清理过期缓存
  4. 敏感数据:不要缓存包含敏感信息的响应
  5. 测试验证:修改缓存配置后充分测试

11. 扩展阅读

12. 总结

Apache 缓存配置可以显著提升性能:

  • 浏览器缓存:减少重复请求
  • 代理缓存:减轻后端压力
  • CDN 缓存:全球加速

合理配置缓存策略是性能优化的关键。