Apache 缓存配置 #

缓存概述 #

缓存类型 #

text
┌─────────────────────────────────────────────────────────────┐
│                    Apache 缓存类型                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  浏览器缓存                                                 │
│  ├── 通过 HTTP 头控制                                       │
│  ├── Expires / Cache-Control                               │
│  ├── 减少重复请求                                          │
│  └── 客户端控制                                            │
│                                                             │
│  服务器缓存                                                 │
│  ├── mod_cache 模块                                        │
│  ├── 缓存后端响应                                          │
│  ├── 减少后端压力                                          │
│  └── 服务器控制                                            │
│                                                             │
│  代理缓存                                                   │
│  ├── 反向代理缓存                                          │
│  ├── 缓存代理内容                                          │
│  └── CDN 缓存                                              │
│                                                             │
└─────────────────────────────────────────────────────────────┘

浏览器缓存配置 #

启用必要模块 #

bash
# Ubuntu/Debian
sudo a2enmod expires
sudo a2enmod headers
sudo systemctl restart apache2

mod_expires 配置 #

apache
# ============================================
# mod_expires 浏览器缓存配置
# ============================================

<IfModule mod_expires.c>
    # 启用过期控制
    ExpiresActive On
    
    # 默认缓存时间
    ExpiresDefault "access plus 1 month"
    
    # HTML 文件 - 短缓存
    ExpiresByType text/html "access plus 1 hour"
    
    # CSS 和 JavaScript - 长缓存
    ExpiresByType text/css "access plus 1 year"
    ExpiresByType text/javascript "access plus 1 year"
    ExpiresByType application/javascript "access plus 1 year"
    ExpiresByType application/x-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/svg+xml "access plus 1 year"
    ExpiresByType image/x-icon "access plus 1 year"
    ExpiresByType image/webp "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 application/vnd.ms-fontobject "access plus 1 year"
    ExpiresByType font/ttf "access plus 1 year"
    ExpiresByType font/otf "access plus 1 year"
    
    # 视频和音频 - 长缓存
    ExpiresByType video/mp4 "access plus 1 year"
    ExpiresByType video/webm "access plus 1 year"
    ExpiresByType audio/mpeg "access plus 1 year"
    ExpiresByType audio/ogg "access plus 1 year"
    
    # 文档文件 - 中等缓存
    ExpiresByType application/pdf "access plus 1 month"
    ExpiresByType application/xml "access plus 1 hour"
    ExpiresByType application/json "access plus 0 seconds"
    
    # 数据文件 - 不缓存
    ExpiresByType text/xml "access plus 0 seconds"
</IfModule>

时间格式说明 #

text
┌─────────────────────────────────────────────────────────────┐
│                    Expires 时间格式                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  基准时间:                                                 │
│  access    访问时间                                        │
│  now       等同于 access                                   │
│  modification  文件修改时间                                │
│                                                             │
│  时间单位:                                                 │
│  years     年                                              │
│  months    月                                              │
│  weeks     周                                              │
│  days      天                                              │
│  hours     小时                                            │
│  minutes   分钟                                            │
│  seconds   秒                                              │
│                                                             │
│  示例:                                                     │
│  "access plus 1 month"                                     │
│  "access plus 1 year"                                      │
│  "access plus 2 weeks 3 days"                              │
│  "modification plus 1 month"                               │
│  "access plus 0 seconds"  # 不缓存                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

mod_headers 配置 #

apache
# ============================================
# mod_headers Cache-Control 配置
# ============================================

<IfModule mod_headers.c>
    # HTML - 不缓存
    <FilesMatch "\.(html|htm)$">
        Header set Cache-Control "no-cache, no-store, must-revalidate"
        Header set Pragma "no-cache"
        Header set Expires 0
    </FilesMatch>
    
    # CSS/JS - 强缓存
    <FilesMatch "\.(css|js)$">
        Header set Cache-Control "public, max-age=31536000, immutable"
    </FilesMatch>
    
    # 图片 - 强缓存
    <FilesMatch "\.(jpg|jpeg|png|gif|svg|webp|ico)$">
        Header set Cache-Control "public, max-age=31536000, immutable"
    </FilesMatch>
    
    # 字体 - 强缓存
    <FilesMatch "\.(woff|woff2|ttf|otf|eot)$">
        Header set Cache-Control "public, max-age=31536000, immutable"
    </FilesMatch>
    
    # 视频/音频 - 强缓存
    <FilesMatch "\.(mp4|webm|mp3|ogg|wav)$">
        Header set Cache-Control "public, max-age=31536000, immutable"
    </FilesMatch>
    
    # PDF - 中等缓存
    <FilesMatch "\.pdf$">
        Header set Cache-Control "public, max-age=2592000"
    </FilesMatch>
    
    # JSON/XML - 不缓存
    <FilesMatch "\.(json|xml)$">
        Header set Cache-Control "no-cache, no-store, must-revalidate"
    </FilesMatch>
</IfModule>

Cache-Control 指令说明 #

text
┌─────────────────────────────────────────────────────────────┐
│                    Cache-Control 指令                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  可缓存性:                                                 │
│  public          可被任何缓存存储                           │
│  private         仅浏览器可缓存                            │
│  no-cache        使用前需验证                              │
│  no-store        不缓存                                    │
│                                                             │
│  过期时间:                                                 │
│  max-age=秒      最大缓存时间                              │
│  s-maxage=秒     共享缓存最大时间                          │
│  max-stale=秒    可接受过期时间                            │
│  min-fresh=秒    最小新鲜时间                              │
│                                                             │
│  重新验证:                                                 │
│  must-revalidate  必须重新验证                             │
│  proxy-revalidate 代理必须重新验证                         │
│  immutable        资源永不改变                             │
│  no-transform     不转换响应内容                           │
│                                                             │
│  常用组合:                                                 │
│  不缓存:no-cache, no-store, must-revalidate               │
│  强缓存:public, max-age=31536000, immutable               │
│  协商缓存:no-cache, max-age=0                             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

ETag 配置 #

ETag 基础 #

apache
# ============================================
# ETag 配置
# ============================================

# 启用 ETag
FileETag MTime Size

# ETag 组成
# INode   文件 inode 号
# MTime   修改时间
# Size    文件大小

# 完整配置
FileETag INode MTime Size

# 禁用 ETag(如果使用 Last-Modified)
# FileETag None

# 为静态资源设置 ETag
<Directory /var/www/html/static>
    FileETag MTime Size
</Directory>

ETag vs Last-Modified #

apache
# ============================================
# ETag 与 Last-Modified 对比
# ============================================

# ETag 方式
# 优点:精确识别文件变化
# 缺点:需要计算,占用资源
FileETag MTime Size

# Last-Modified 方式
# 优点:简单,性能好
# 缺点:只能精确到秒
# 默认启用,无需配置

# 组合使用
<Directory /var/www/html/static>
    FileETag MTime Size
    # Last-Modified 自动启用
</Directory>

服务器缓存配置 #

启用 mod_cache #

bash
# Ubuntu/Debian
sudo a2enmod cache
sudo a2enmod cache_disk
sudo a2enmod cache_socache
sudo systemctl restart apache2

磁盘缓存配置 #

apache
# ============================================
# mod_cache_disk 磁盘缓存
# ============================================

# 缓存根目录
CacheRoot /var/cache/apache2/mod_cache_disk

# 目录层级
CacheDirLevels 2
CacheDirLength 1

# 最大缓存大小
CacheMaxFileSize 10000000
CacheMinFileSize 1

# 缓存配置
<IfModule mod_cache.c>
    <IfModule mod_cache_disk.c>
        CacheRoot /var/cache/apache2/proxy
        CacheDirLevels 2
        CacheDirLength 1
        CacheMaxFileSize 10000000
    </IfModule>
    
    # 启用缓存
    CacheQuickHandler on
    
    # 缓存锁
    CacheLock on
    CacheLockPath /tmp/cachelock
    CacheLockMaxAge 5
</IfModule>

代理缓存配置 #

apache
# ============================================
# 反向代理缓存配置
# ============================================

<IfModule mod_cache.c>
    <IfModule mod_cache_disk.c>
        CacheRoot /var/cache/apache2/proxy
        CacheDirLevels 2
        CacheDirLength 1
    </IfModule>
    
    # 启用缓存
    CacheQuickHandler on
</IfModule>

<VirtualHost *:80>
    ServerName api.example.com
    
    # 启用缓存
    <Location />
        CacheEnable disk
        CacheHeader on
        CacheDefaultExpire 3600
        CacheMaxExpire 86400
        CacheLastModifiedFactor 0.5
        CacheIgnoreHeaders Set-Cookie
        CacheIgnoreNoLastMod On
    </Location>
    
    # 代理配置
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
</VirtualHost>

缓存条件控制 #

apache
# ============================================
# 缓存条件控制
# ============================================

<VirtualHost *:80>
    ServerName example.com
    
    # 仅缓存 GET 请求
    <Location />
        CacheEnable disk
        CacheAllowMethods GET
    </Location>
    
    # 排除特定 URL
    <Location /api>
        CacheDisable
    </Location>
    
    <Location /admin>
        CacheDisable
    </Location>
    
    # 排除带查询参数的请求
    CacheIgnoreQueryString On
    
    # 忽略特定头
    CacheIgnoreHeaders Set-Cookie Authorization
</VirtualHost>

.htaccess 缓存配置 #

apache
# ============================================
# .htaccess 缓存配置
# ============================================

# 启用过期控制
<IfModule mod_expires.c>
    ExpiresActive On
    
    # 图片
    ExpiresByType image/jpeg "access plus 1 year"
    ExpiresByType image/png "access plus 1 year"
    ExpiresByType image/gif "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    
    # CSS/JS
    ExpiresByType text/css "access plus 1 year"
    ExpiresByType application/javascript "access plus 1 year"
    
    # 字体
    ExpiresByType font/woff "access plus 1 year"
    ExpiresByType font/woff2 "access plus 1 year"
</IfModule>

# Cache-Control 头
<IfModule mod_headers.c>
    <FilesMatch "\.(jpg|jpeg|png|gif|svg|css|js|woff|woff2)$">
        Header set Cache-Control "public, max-age=31536000, immutable"
    </FilesMatch>
    
    <FilesMatch "\.(html|htm)$">
        Header set Cache-Control "no-cache, no-store, must-revalidate"
    </FilesMatch>
</IfModule>

缓存验证 #

条件请求 #

text
┌─────────────────────────────────────────────────────────────┐
│                    条件请求                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  客户端缓存验证流程:                                       │
│                                                             │
│  1. 首次请求                                                │
│     客户端 ──> 服务器                                       │
│     服务器返回内容 + ETag/Last-Modified                    │
│     客户端缓存内容                                          │
│                                                             │
│  2. 再次请求(使用 If-None-Match)                         │
│     客户端 ──> 服务器                                       │
│     If-None-Match: "etag-value"                            │
│                                                             │
│  3. 服务器验证                                              │
│     - ETag 匹配 ──> 304 Not Modified                       │
│     - ETag 不匹配 ──> 200 OK + 新内容                      │
│                                                             │
│  或使用 If-Modified-Since:                                │
│     If-Modified-Since: Wed, 21 Oct 2026 07:28:00 GMT       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

验证缓存配置 #

bash
# 测试缓存配置
curl -I https://example.com/style.css

# 输出应包含
# Cache-Control: public, max-age=31536000, immutable
# ETag: "abc123"
# Last-Modified: Wed, 21 Oct 2026 07:28:00 GMT

# 测试条件请求
curl -I -H 'If-None-Match: "abc123"' https://example.com/style.css
# 应返回 304 Not Modified

缓存最佳实践 #

静态资源缓存策略 #

text
┌─────────────────────────────────────────────────────────────┐
│                    静态资源缓存策略                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  HTML 文件:                                                │
│  Cache-Control: no-cache                                   │
│  原因:需要及时更新                                        │
│                                                             │
│  CSS/JS(带版本号):                                       │
│  Cache-Control: public, max-age=31536000, immutable        │
│  原因:文件名变化即新资源                                  │
│                                                             │
│  图片/字体:                                                │
│  Cache-Control: public, max-age=31536000, immutable        │
│  原因:很少变化                                            │
│                                                             │
│  API 响应:                                                 │
│  Cache-Control: no-cache 或 no-store                       │
│  原因:数据实时性要求高                                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

版本化静态资源 #

apache
# ============================================
# 版本化静态资源配置
# ============================================

# 方案 1:查询参数版本
# /style.css?v=1.0.0
# 浏览器会认为是新资源

# 方案 2:文件名版本
# /style.v1.0.0.css 或 /v1.0.0/style.css
# 配置长缓存
<FilesMatch "\.v[0-9]+\.[0-9]+\.[0-9]+\.(css|js)$">
    Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>

# 方案 3:内容哈希
# /style.abc123.css
<FilesMatch "\.[a-f0-9]{8,}\.(css|js)$">
    Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>

完整配置示例 #

apache
# ============================================
# 完整缓存配置示例
# ============================================

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/html
    
    # 浏览器缓存
    <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/svg+xml "access plus 1 year"
        ExpiresByType font/woff "access plus 1 year"
        ExpiresByType font/woff2 "access plus 1 year"
    </IfModule>
    
    # Cache-Control 头
    <IfModule mod_headers.c>
        <FilesMatch "\.(html|htm)$">
            Header set Cache-Control "no-cache, no-store, must-revalidate"
        </FilesMatch>
        
        <FilesMatch "\.(css|js|jpg|jpeg|png|gif|svg|woff|woff2)$">
            Header set Cache-Control "public, max-age=31536000, immutable"
        </FilesMatch>
    </IfModule>
    
    # ETag
    FileETag MTime Size
    
    <Directory /var/www/html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

下一步 #

掌握了缓存配置后,继续学习 Gzip 压缩,了解如何配置响应压缩提升传输效率!

最后更新:2026-03-29