Apache可通过mod_cache_disk等模块,结合SetEnvIfNoCase标记请求特征、Vary头支持内容协商、CacheIgnoreHeaders精准控制,为满足条件的复杂动态请求(如带特定查询参数或Accept头的API)实现安全缓存。

Apache 本身不直接处理“复杂请求”的语义判断(比如是否含认证头、是否为 POST/PUT、是否带 Cookie),但它可以通过模块组合和精细规则,为满足特定条件的动态请求(如带查询参数的 API、登录态下的个性化页面片段、含 Accept 头的响应变体)实现可落地的缓存加速。关键不是让所有复杂请求都缓存,而是识别其中“可安全缓存”的子集,并隔离风险。
识别并标记可缓存的复杂请求
复杂请求能否缓存,取决于它是否具备“可重复性”和“无副作用”。Apache 不会自动判断,需你主动定义规则:
- 用 mod_rewrite 或 mod_setenvif 提取请求特征:比如匹配特定 query string(
?v=202606)、Accept 头(application/json)、或不含敏感 Cookie(!Cookie或!^.*user_id=.*$) - 为符合条件的请求设置环境变量,例如:
SetEnvIfNoCase Request_URI "\.json$" is_api=1SetEnvIfNoCase Cookie "(^|;\s*)session_id=" no_cache=1 - 后续缓存指令通过
env=!no_cache条件启用,确保含 session 的请求跳过缓存
启用磁盘缓存并绑定条件路径
mod_cache_disk 是承载复杂请求缓存的主力,它支持按 URL、Header、Query 等多维键生成缓存文件:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 启用模块(Debian/Ubuntu 常用):
a2enmod cache cache_disk expires headers - 在虚拟主机或全局配置中设置基础缓存区:
<IfModule mod_cache.c><br> CacheRoot "/var/cache/apache2/disk"<br> CacheDirLevels 2<br> CacheDirLength 1<br> CacheIgnoreHeaders Set-Cookie Vary<br></IfModule>
- 对目标路径启用缓存,并附加键值控制:
<LocationMatch "^/api/v1/(products|users)"><br> CacheEnable disk<br> CacheIgnoreNoLastMod On<br> CacheStorePrivate Off<br> CacheStoreNoStore Off<br> CacheKeyBaseURL "https://yourdomain.com"<br></LocationMatch>
用 Vary 头支持内容协商缓存
当同一 URL 返回不同格式(JSON/XML)、压缩状态(gzip/br)或语言(en/zh)时,必须用 Vary 显式声明缓存变体维度,否则 Apache 可能混存错误版本:
- 在后端响应中输出:
Header always set Vary "Accept, Accept-Encoding, Accept-Language" - 或在 Apache 配置中统一添加(适用于所有 API):
<Location "/api/"><br> Header always append Vary "Accept"<br> Header always append Vary "Accept-Encoding"<br></Location>
- 注意:
CacheIgnoreHeaders Vary必须禁用,否则缓存将忽略变体逻辑
设置精细过期与强制刷新策略
复杂请求通常不能靠固定时间(如 1 小时)控制,需结合响应头与手动干预:
- 优先信任后端返回的
Cache-Control和Expires,Apache 默认遵循;若后端未设,用CacheDefaultExpire补充 - 对高时效接口(如实时股价),后端应返回
Cache-Control: max-age=30, public,Apache 自动按此缓存 30 秒 - 支持手动清理:运行
find /var/cache/apache2/disk -name "*products*" -delete清除某类缓存;生产环境建议封装为脚本 + 定时任务

















