通过在 Apache 中配置 Web 缓存策略,可以指示浏览器及中间代理(如 CDN)复用已下载的资源,减少不必要的网络请求。这可以提升页面加载速度,同时减少服务器压力和带宽消耗。
免责声明:本文档可能包含第三方产品信息,该信息仅供参考。阿里云对第三方产品的性能、可靠性以及操作可能带来的潜在影响,不做任何暗示或其他形式的承诺。
策略选型
Apache模块 | 优点 | 缺点 | 使用场景 |
mod_expires | 语法简单,可快速为不同类型文件设置过期时间。 | 功能有限,无法设置 | 仅适用于非常简单的、只需设置 |
mod_headers | 可以设置完整的HTTP头,支持所有 | 语法相对 | 需要精细化、完整化缓存策略的生产环境。 |
操作步骤
步骤一:启用所需模块
在配置缓存策略前,请确保 headers 和 expires 模块已在 Apache 中启用。
检查模块是否已加载执行
apachectl -M
或httpd -M
命令,检查输出列表中是否包含headers_module
和expires_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_expires
和mod_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_type
:MIME 类型,例如:image/jpeg
、image/gif
、text/css
、text/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-Control
、Expires
。value
:设置的值。
步骤四:验证配置并应用
在修改配置后,请务必先检查语法再平滑地重载服务,以避免服务中断。
检查配置语法在应用更改前,运行语法检查命令确保没有错误。
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)
。这是最高效的缓存方式。协商缓存:当强缓存失效(已过期)或未设置时,浏览器会向服务器发起一个条件请求。
浏览器在请求头中携带缓存标识,如
If-None-Match
(值为上次响应的ETag
) 或If-Modified-Since
(值为上次响应的Last-Modified
日期)。服务器根据收到的标识判断资源是否有变化。
若资源未变,服务器返回
304 Not Modified
状态码,响应体为空。浏览器继续使用本地的旧副本。若资源已更新,服务器返回
200 OK
状态码和全新的资源内容。
通过配置 Apache 来控制以下关键的 HTTP 响应头,以实现缓存策略: