Apache需通过模块组合与显式规则实现动态内容差异化缓存:一、启用mod_cache及mod_cache_disk并配置磁盘缓存路径与忽略Set-Cookie头;二、利用Vary响应头使Apache按X-Region、User-Agent等请求头生成不同缓存键;三、通过RewriteCond/RewriteRule将地理码编码进URL路径以固化缓存维度;四、用Header指令禁用HTML和JSON等敏感响应的缓存,并验证缓存命中状态。

Apache 本身不直接支持“按用户地区、设备类型或登录状态等维度自动差异化缓存动态内容”,必须通过组合模块与显式规则来构造不同缓存键。核心思路是:让不同维度的请求生成逻辑上不同的 URL 或 Vary 头,从而被 Apache 视为独立缓存项。
一、启用基础缓存模块并配置磁盘缓存
这是所有动态缓存的前提。仅靠 mod_expires 或 mod_headers 无法缓存响应体,必须启用 mod_cache 和 mod_cache_disk(或 mod_cache_socache)。
- 启用模块:
sudo a2enmod cache cache_disk headers expires - 创建缓存目录并授权:
sudo mkdir -p /var/cache/apache2/dynamic && sudo chown www-data:www-data /var/cache/apache2/dynamic - 在虚拟主机或全局配置中添加:
<IfModule mod_cache.c>
<IfModule mod_cache_disk.c>
CacheRoot /var/cache/apache2/dynamic
CacheEnable disk /
CacheDirLevels 2
CacheDirLength 1
CacheIgnoreHeaders Set-Cookie
CacheIgnoreNoLastMod On
CacheDefaultExpire 60
</IfModule>
</IfModule>
注意:CacheIgnoreHeaders Set-Cookie 是关键——否则含 Cookie 的请求默认不缓存;若需缓存已登录用户的个性化内容,应改用 Vary 策略而非忽略。
二、用 Vary 响应头实现轻量级差异化
当后端能输出标准 Vary 头(如 Vary: User-Agent, X-Region),且前端/反向代理已注入对应请求头时,Apache 会自动将这些头值纳入缓存键计算。
Apache 2.4.62 官方 tar.gz 源码包是 Linux 及类 Unix 系统构建 Web 服务器的核心基础。通过源码编译安装,开发者能够灵活定制模块、优化性能并精准控制安装路径,满足多样化的业务需求。
- 确保后端(PHP/Python/Node.js)在响应中设置:
Vary: X-Region, User-Agent - 若由 Nginx 或 CDN 注入地理头(如
X-Region: cn),Apache 无需额外提取,只需确认该头出现在原始请求中 - 验证方式:用
curl -I https://yoursite.com/api/data查看响应是否含Vary,再对比不同X-Region值的请求是否返回不同X-Cache: HIT
⚠️ 注意:Vary 维度越多,缓存碎片化越严重。不建议对高基数字段(如完整 IP)使用 Vary。
三、用 URL 重写固化地理/设备维度
比 Vary 更可控、更兼容的方式:把差异化变量编码进 URL 路径,使缓存系统天然识别为不同资源。
- 前提:已部署 GeoIP2 模块并可获取
%{GEOIP_COUNTRY_CODE} - 添加重写规则(在
<VirtualHost>内): RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^([A-Z]{2})$
RewriteRule ^/(api/.*)$ /%1/$1 [E=REGION:%1,L]
Header set X-Cache-Key "%{REGION}e-%{REQUEST_URI}e" env=REGION - 效果:请求
/api/news来自 CN → 实际处理/cn/api/news,缓存键即为该路径 - 配合
CacheIgnoreURLSessionIdentifiers可进一步清理 query 参数干扰
四、禁用不应缓存的动态响应
避免把带敏感信息或强时效性的内容误缓存,需主动排除。
- 对 HTML 页面设短缓存或禁止存储:
Header set Cache-Control "no-cache, must-revalidate" - 对 JSON API 响应(Content-Type: application/json)统一拦截:
<If "%{CONTENT_TYPE} == 'application/json'">
Header set Cache-Control "no-store"
</If> - 对含 Set-Cookie 的响应,默认已被
CacheIgnoreHeaders Set-Cookie排除;若需缓存带 Cookie 的静态片段(如未登录态 banner),应改用Vary: Cookie并谨慎评估风险
不复杂但容易忽略:差异化缓存的有效性,最终取决于缓存键是否真正分离。无论用 Vary、URL 重写还是自定义 CacheKeyBaseURL,都要用 curl -v 或浏览器开发者工具验证响应头和缓存命中状态。

















