设置Apache缓存策略

通过在 Apache 中配置 Web 缓存策略,可以指示浏览器及中间代理(如 CDN)复用已下载的资源,减少不必要的网络请求。这可以提升页面加载速度,同时减少服务器压力和带宽消耗。

说明

免责声明:本文档可能包含第三方产品信息,该信息仅供参考。阿里云对第三方产品的性能、可靠性以及操作可能带来的潜在影响,不做任何暗示或其他形式的承诺。

策略选型

Apache模块

优点

缺点

使用场景

mod_expires

语法简单,可快速为不同类型文件设置过期时间。

功能有限,无法设置no-storeimmutable等复杂的Cache-Control指令。

仅适用于非常简单的、只需设置max-age的场景。

mod_headers

可以设置完整的HTTP头,支持所有Cache-Control指令,如immutable

语法相对mod_expires稍复杂。

需要精细化、完整化缓存策略的生产环境。

操作步骤

步骤一:启用所需模块

在配置缓存策略前,请确保 headers 和 expires 模块已在 Apache 中启用。

  • 检查模块是否已加载执行 apachectl -Mhttpd -M 命令,检查输出列表中是否包含 headers_moduleexpires_module

  • 启用模块(如果未加载):

    • 对于 Debian/Ubuntu 系统:

      sudo a2enmod headers expires
      sudo systemctl restart apache2
    • 对于 CentOS/RHEL/Alibaba Cloud Linux 系统:模块通常默认编译或加载。如果确实缺失,请检查 /etc/httpd/conf.modules.d/ 目录下的配置文件,确保对应的 LoadModule 行没有被注释。

步骤二:选择配置文件位置

推荐将缓存相关的配置集中存放在一个专用的配置文件中,或直接写入站点的虚拟主机(VirtualHost)配置块。

  • 推荐位置:在 /etc/httpd/conf.d/ (CentOS/RHEL)或 /etc/apache2/conf-available/(Debian/Ubuntu)目录下创建一个新文件,例如 cache.conf

  • 不推荐位置:避免在 .htaccess 文件中进行配置。Apache 需要在每次请求时读取并解析 .htaccess,会带来不必要的性能开销。

步骤三:按场景配置缓存策略

设置全局默认缓存过期时间

mod_expires

<IfModule mod_expires.c>
    # 启用mod_expires功能
    ExpiresActive On
    # 所有资源默认缓存时间为 1 周
    ExpiresDefault "access plus 1 week"
</IfModule>

mod_headers

<IfModule mod_headers.c>
    # 设置 Cache-Control 头,缓存时间为 1 天
    Header set Cache-Control "max-age=86400, public"
</IfModule>

按指定类型设置缓存策略

mod_expires

<IfModule mod_expires.c>
    # 启用mod_expires功能
    ExpiresActive On

    # 默认缓存时间为 1 天
    ExpiresDefault "access plus 1 day"

    # 图片资源缓存 1 个月
    ExpiresByType image/jpeg "access plus 1 month"
    ExpiresByType image/png "access plus 1 month"
    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/svg+xml "access plus 1 month"

    # CSS 和 JS 文件缓存 1 周
    ExpiresByType text/css "access plus 1 week"
    ExpiresByType application/javascript "access plus 1 week"

    
</IfModule>

mod_headers

<IfModule mod_headers.c>
    # 图片资源缓存 1 个月
    <FilesMatch "\.(jpg|jpeg|png|gif|svg)$">
        Header set Cache-Control "max-age=2592000, public"
    </FilesMatch>

    # CSS 和 JS 文件缓存 1 周
    <FilesMatch "\.(css|js)$">
        Header set Cache-Control "max-age=604800, public"
    </FilesMatch>
</IfModule>

禁用特定类型资源的缓存

mod_expires

<IfModule mod_expires.c>
    # 启用mod_expires功能
    ExpiresActive On
    # HTML 文件不缓存
    ExpiresByType text/html "access plus 0 seconds"
</IfModule>

mod_headers

<IfModule mod_headers.c>
    #  HTML 文件禁用了缓存
    <FilesMatch "\.html$">
        Header set Cache-Control "no-store, no-cache, must-revalidate"
        Header set Pragma "no-cache"
        Header set Expires "0"
    </FilesMatch>
</IfModule>

设置自定义缓存策略

根据mod_expiresmod_headers的语法规则,编写适合自身业务的策略。

mod_expires基本语法

<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresDefault "base_time plus time_unit"
    ExpiresByType mime_type "base_time plus time_unit"
</IfModule>
  • ExpiresActive On:启用 mod_expires 模块的功能。

  • ExpiresDefault:设置默认的缓存时间的指令,适用于所有未明确指定类型的资源。

  • ExpiresByType:针对特定 MIME 类型设置缓存时间的指令。

  • mime_typeMIME 类型,例如:image/jpegimage/giftext/csstext/html

  • base_time:缓存时间的基准,通常是 access(用户访问时)或 modification(文件修改时)。

  • time_unit:时间单位,例如:

    • seconds(秒)

    • minutes(分钟)

    • hours(小时)

    • days(天)

    • weeks(周)

    • months(月)

    • years(年)

mod_headers基本语法

<IfModule mod_headers.c>
    Header set|append|unset header_name "value"
</IfModule>
  • Header set:设置指定的 HTTP 头字段值。

  • Header append:在现有值的基础上追加内容。

  • Header unset:删除指定的 HTTP 头字段。

  • header_name:要操作的 HTTP 头字段名称,例如 Cache-ControlExpires

  • value:设置的值。

<FilesMatch>简介

<FilesMatch>的主要作用是通过正则表达式匹配文件名或路径,从而针对符合条件的文件应用特定的配置规则。例如:

  • 为图片文件(如 .jpg.png)设置较长的缓存时间。

  • 禁止某些敏感文件(如 .htaccess 或 .log 文件)被访问。

  • 为静态资源(如 CSS 和 JS 文件)添加特定的 HTTP 头。

<FilesMatch>基本语法如下:

<FilesMatch "正则表达式"> </FilesMatch>
  • 正则表达式:用于匹配文件名或路径的正则表达式。常见的匹配模式包括:

    • \.(扩展名)$:匹配特定扩展名的文件。例如,\.(jpg|jpeg|png)$ 匹配所有 .jpg.jpeg和 .png 文件。

    • ^/路径/:匹配特定路径下的文件。

    • .*:匹配任意文件名。

步骤四:验证配置并应用

在修改配置后,请务必先检查语法再平滑地重载服务,以避免服务中断。

  • 检查配置语法在应用更改前,运行语法检查命令确保没有错误。

    • CentOS/RHEL/Alibaba Cloud Linux:sudo httpd -t

    • Debian/Ubuntu:sudo apache2ctl -t

    如果看到 Syntax OK,则可以继续。

  • 应用配置(推荐平滑重载)

    使用 reload 命令可以在不中断现有连接的情况下应用新配置。

    • CentOS/RHEL/Alibaba Cloud Linux:sudo systemctl reload httpd

    • Debian/Ubuntu:sudo systemctl reload apache2

拓展阅读:Web缓存的工作原理

Web 缓存主要分为两类:强缓存和协商缓存。

  • 强缓存:当浏览器请求一个资源时,会先检查本地缓存。如果缓存未过期(依据 Cache-Control 的 max-age 或 Expires 头部判断),浏览器将直接从本地磁盘或内存中读取资源副本,完全不与服务器通信。HTTP 状态码通常为 200 (from disk cache) 或 200 (from memory cache)。这是最高效的缓存方式。

  • 协商缓存:当强缓存失效(已过期)或未设置时,浏览器会向服务器发起一个条件请求。

    1. 浏览器在请求头中携带缓存标识,如 If-None-Match(值为上次响应的 ETag) 或 If-Modified-Since (值为上次响应的 Last-Modified 日期)。

    2. 服务器根据收到的标识判断资源是否有变化。

    3. 若资源未变,服务器返回 304 Not Modified 状态码,响应体为空。浏览器继续使用本地的旧副本。

    4. 若资源已更新,服务器返回 200 OK 状态码和全新的资源内容。

通过配置 Apache 来控制以下关键的 HTTP 响应头,以实现缓存策略:

缓存相关HTTP响应头

响应头

作用

常用指令/值

Cache-Control

HTTP/1.1 引入,用于精确控制缓存行为,优先级高于 Expires

public:可被任意缓存(浏览器、CDN)存储。

private:只能被终端用户的浏览器缓存。

no-cache:强制进行协商缓存,每次都必须向服务器验证。

no-store:完全禁止缓存,不存储任何副本。

max-age=<seconds>:设置强缓存的有效时长(秒)。

s-maxage=<seconds>:专用于共享缓存(如 CDN)的 max-age

must-revalidate:缓存过期后,必须向源服务器验证,不能使用陈旧副本。

immutable:表示响应正文在新鲜期内不会改变,浏览器无需再发起条件请求。

Expires

HTTP/1.0 的旧标准,提供一个绝对的过期时间点。当 Cache-Control 的 max-age 存在时,此头部将被忽略。

Expires: Wed, 21 Oct 2025 07:28:00 GMT

ETag

实体标签(Entity Tag),服务器为资源生成的唯一标识符(如文件内容的哈希值)。ETag 比 Last-Modified 更精确。

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

Last-Modified

资源在服务器上最后被修改的时间。精度较低(到秒),且在某些场景下(如文件内容未变但元数据变了)可能不准确。

Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT