DocumentRoot与代理缓存(mod_cache)作用对象不同,不可直接配合:前者服务本地静态文件,后者缓存反向代理的动态响应;需通过路径分离(如/static/走DocumentRoot、/api/走ProxyPass+CacheEnable)、缓存目录独立设置及环境变量精细控制缓存条件来协同工作。

DocumentRoot 和代理缓存(mod_cache)是两个不同层级的功能,不能直接“配合”使用,因为它们作用对象完全不同:
-
DocumentRoot定义的是 Apache 作为静态文件服务器时的根目录,响应的是本地磁盘上的.html、.js、.css等静态资源; - 代理缓存(
mod_cache_disk+mod_proxy)针对的是反向代理转发后的动态响应(如/api/xxx),缓存的是从后端(PHP、Java、Node.js 等)返回的内容,和DocumentRoot下的文件无关。
但如果你的目标是:让 Apache 同时服务静态资源(走 DocumentRoot)+ 缓存动态 API(走 ProxyPass + CacheEnable),那就需要明确分工、避免冲突。以下是关键配置逻辑和实操要点:
✅ 明确职责边界:静态 vs 动态路径分离
Apache 必须区分哪些请求该走本地文件系统(DocumentRoot),哪些该走反向代理并缓存。典型做法是用路径前缀做路由判断:
-
/或/static/→ 指向DocumentRoot,可配mod_expires做浏览器缓存 -
/api/或/v1/→ 用ProxyPass转发,并在<LocationMatch>中启用CacheEnable disk
示例配置片段:
DocumentRoot "/var/www/html"
# 静态资源:直接读取磁盘,不走代理
<Directory "/var/www/html">
Require all granted
</Directory>
# 动态 API:转发并缓存
ProxyPass "/api/" "http://backend-server:8080/api/"
ProxyPassReverse "/api/" "http://backend-server:8080/api/"
<LocationMatch "^/api/(products|users|orders)">
CacheEnable disk
CacheIgnoreHeaders Set-Cookie Vary
CacheStorePrivate Off
CacheStoreNoStore Off
</LocationMatch>⚠️ 注意:
DocumentRoot的路径不能覆盖代理路径(比如DocumentRoot "/var/www/html"和ProxyPass "/api/"是安全的;但如果设成DocumentRoot "/var/www/html/api",Apache 会优先尝试找本地文件,导致代理失效)。
✅ 缓存目录独立于 DocumentRoot
mod_cache_disk 的缓存文件必须放在单独目录,且不能是 DocumentRoot 子目录(否则可能被意外暴露或权限冲突):
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
<IfModule mod_cache_disk.c>
CacheRoot "/var/cache/apache2/proxy_cache"
CacheDirLevels 2
CacheDirLength 1
</IfModule>执行:
sudo mkdir -p /var/cache/apache2/proxy_cache sudo chown www-data:www-data /var/cache/apache2/proxy_cache
✅ 避免缓存污染:用环境变量精细控制
不是所有 /api/ 请求都该缓存。需过滤出安全、幂等、无用户上下文的 GET 请求:
SetEnvIfNoCase Request_Method "GET" is_cacheable=1
SetEnvIfNoCase Cookie "(^|;\s*)auth_token=|session=" no_cache=1
SetEnvIfNoCase Authorization "^Bearer " no_cache=1
<LocationMatch "^/api/">
CacheEnable disk env=is_cacheable:!no_cache
</LocationMatch>这样即使请求路径匹配 /api/,只要带 Token 或 Cookie,就不会进缓存。
✅ 验证是否生效:看响应头
成功缓存后,响应头应含:
-
X-Cache: HIT(命中)或X-Cache: MISS(未命中) -
Age:头显示已缓存秒数 -
Cache-Control:应与后端一致(如public, max-age=300)
若始终是 MISS,检查:
- 后端是否返回了
Cache-Control: private或Set-Cookie -
CacheIgnoreHeaders是否漏写了Vary(常见于Accept,Accept-Encoding) - 请求是否被
no_cache环境变量拦截
不复杂但容易忽略。核心就三点:路径不重叠、缓存目录独立、缓存条件收口。

















