文档目录
HTTP缓存策略

简介

本指南面向DouPHP项目的HTTP缓存策略配置,覆盖浏览器缓存、服务端缓存、CDN缓存与一致性保障,并提供监控与调试建议。内容基于仓库中现有的响应头处理、安全中间件、模板编译缓存、资源版本管理以及缓存清理能力进行系统化说明,帮助在生产环境中构建稳定高效的缓存体系。

项目结构

DouPHP采用多入口(前台、后台、API)与中间件管道架构,HTTP响应通过统一的Response对象输出,安全与基础响应头由中间件统一注入;静态资源路由由Web服务器规则接管;模板编译产物与资源版本管理提供本地缓存与失效机制;后台提供缓存清理服务。

graph TB
Client["客户端"] --> Nginx["Nginx/Apache<br/>静态资源直出/重写"]
Nginx --> Front["前台入口 index.php"]
Nginx --> Admin["后台入口 admin/index.php"]
Nginx --> Api["API入口 api/index.php"]
Front --> Resp["Response 发送响应头与正文"]
Admin --> Resp
Api --> Resp
Front --> SecMW["安全响应头中间件"]
Admin --> SecMW
Api --> SecMW
Front --> Tpl["模板编译缓存"]
Front --> Manifest["资源版本管理"]
Admin --> Clear["缓存清理服务"]

图表来源

  • .htaccess:10-45
  • core/web/http/Response.php:117-136
  • front/middleware/SecurityHeadersMiddleware.php:23-28
  • core/foundation/middleware/AbstractSecurityHeadersMiddleware.php:41-49
  • core/web/template/CompileCache.php:21-31
  • core/web/manifest/ManifestCacheGeneration.php:21-26
  • admin/service/cache/CacheClearService.php:24-44

章节来源

  • .htaccess:10-45
  • core/web/http/Response.php:117-136
  • front/middleware/SecurityHeadersMiddleware.php:23-28
  • core/foundation/middleware/AbstractSecurityHeadersMiddleware.php:41-49
  • core/web/template/CompileCache.php:21-31
  • core/web/manifest/ManifestCacheGeneration.php:21-26
  • admin/service/cache/CacheClearService.php:24-44

核心组件

  • 响应头输出:Response类负责设置并发送HTTP状态码与响应头,是浏览器缓存控制的关键出口。
  • 安全响应头中间件:在请求处理前后统一下发基线安全头,可扩展为包含缓存相关头。
  • 模板编译缓存:将模板编译为PHP产物并落盘,支持修订号与源文件变更检测,避免重复编译。
  • 资源版本管理:为前端脚本/样式等URL附加版本号参数,配合CDN与浏览器缓存实现强更新。
  • 缓存清理服务:提供删除缓存目录的能力,用于发布后强制刷新缓存。
  • API语言包缓存示例:演示了清除旧缓存头并设置长期缓存与ETag的实践。

章节来源

  • core/web/http/Response.php:24-136
  • front/middleware/SecurityHeadersMiddleware.php:23-28
  • core/foundation/middleware/AbstractSecurityHeadersMiddleware.php:41-49
  • core/web/template/CompileCache.php:21-31
  • core/web/manifest/ManifestCacheGeneration.php:21-26
  • admin/service/cache/CacheClearService.php:24-44
  • api/controller/bootstrap/LangController.php:40-58

架构总览

下图展示一次典型请求的缓存相关流程:客户端请求经Web服务器路由到应用,中间件注入安全头,控制器生成响应并通过Response发送;静态资源由Web服务器直接返回;模板编译与资源版本管理影响缓存命中与失效。

sequenceDiagram
participant C as "客户端"
participant W as "Web服务器"
participant M as "安全中间件"
participant R as "控制器/服务"
participant H as "Response"
C->>W : "请求页面或静态资源"
alt "静态资源"
W-->>C : "直接返回(可带缓存头)"
else "动态页面/API"
W->>M : "转发请求"
M->>R : "执行业务逻辑"
R->>H : "设置状态码与响应头"
H-->>C : "发送响应(含Cache-Control/ETag等)"
end

图表来源

  • .htaccess:10-45
  • core/foundation/middleware/AbstractSecurityHeadersMiddleware.php:41-49
  • core/web/http/Response.php:117-136

详细组件分析

浏览器缓存配置

  • Cache-Control头设置
    • 通过Response::setHeader设置Cache-Control,例如对静态资源使用“public, max-age=31536000, immutable”以启用长期缓存与不可变策略。
    • 对于需要实时更新的接口,应设置为no-store或较短max-age。
  • ETag机制实现
    • 使用Response::setHeader设置ETag,值为资源内容的哈希值,便于客户端条件请求与304响应。
    • 建议在控制器或服务层计算内容哈希,并在响应中附带。
  • Last-Modified头部优化
    • 若资源有明确的最后修改时间,可通过Last-Modified与If-Modified-Since实现条件请求,减少带宽消耗。
    • 结合ETag使用,优先ETag,其次Last-Modified。
flowchart TD
Start(["请求进入"]) --> CheckCC["检查是否应设置Cache-Control"]
CheckCC --> CCSet{"已设置?"}
CCSet -- "否" --> SetCC["设置Cache-Control"]
CCSet -- "是" --> Next1["继续"]
SetCC --> Next1
Next1 --> CheckETag{"是否需要ETag?"}
CheckETag -- "是" --> SetETag["计算内容哈希并设置ETag"]
CheckETag -- "否" --> Next2["继续"]
SetETag --> Next2
Next2 --> CheckLM{"是否需要Last-Modified?"}
CheckLM -- "是" --> SetLM["设置Last-Modified"]
CheckLM -- "否" --> End(["发送响应"])
SetLM --> End

图表来源

  • core/web/http/Response.php:55-62
  • api/controller/bootstrap/LangController.php:44-54

章节来源

  • core/web/http/Response.php:55-62
  • api/controller/bootstrap/LangController.php:44-54

服务端缓存策略

  • 页面级缓存
    • 对读多写少的页面,可在服务层缓存渲染结果,并结合版本号或内容哈希作为键。
    • 使用本地文件或分布式缓存存储,设置合理的TTL。
  • API响应缓存
    • 对幂等GET请求,可缓存响应体与头部,键包含查询参数与用户上下文。
    • 结合ETag与Last-Modified,支持条件请求与304响应。
  • 数据库查询结果缓存
    • 对热点查询结果进行缓存,键包含SQL与参数,TTL根据数据变化频率设定。
    • 写操作后主动失效相关缓存键,保证一致性。
classDiagram
class Response {
+setHeader(name, value) void
+send() void
}
class CompileCache {
+needsRecompile(sourcePath, compilePath) bool
+write(compilePath, compiledContent) bool
}
class ManifestCacheGeneration {
+current() int
+bump() int
+urlVersion(contentHash) string
}
Response <.. CompileCache : "使用编译产物"
Response <.. ManifestCacheGeneration : "URL版本化"

图表来源

  • core/web/http/Response.php:55-62
  • core/web/template/CompileCache.php:89-105
  • core/web/manifest/ManifestCacheGeneration.php:32-78

章节来源

  • core/web/template/CompileCache.php:21-31
  • core/web/manifest/ManifestCacheGeneration.php:21-26

CDN缓存配置

  • 静态资源缓存规则
    • 对JS/CSS/图片等静态资源,设置长缓存时间(如一年),并使用immutable提升性能。
    • 通过资源文件名或URL参数中的内容哈希确保更新时强制回源。
  • 动态内容缓存策略
    • 对API响应,按接口特性设置不同TTL;对频繁读取且变化少的数据可设置较长TTL。
    • 使用Vary头区分不同用户或语言版本的缓存。
  • 缓存失效机制
    • 发布新版本时,通过资源版本管理或CDN推送失效列表,确保客户端获取最新资源。
    • 结合ManifestCacheGeneration的世代号,使HTML中引用URL变化,打破浏览器与CDN缓存。
flowchart TD
Build["构建/发布"] --> Hash["生成内容哈希"]
Hash --> Version["拼接URL版本参数"]
Version --> Deploy["部署到CDN"]
Deploy --> Cache["CDN缓存命中"]
Cache --> Update{"版本变化?"}
Update -- "是" --> Bypass["跳过缓存/重新拉取"]
Update -- "否" --> Serve["返回缓存内容"]

图表来源

  • core/web/manifest/ManifestCacheGeneration.php:64-78
  • api/controller/bootstrap/LangController.php:52-54

章节来源

  • core/web/manifest/ManifestCacheGeneration.php:64-78
  • api/controller/bootstrap/LangController.php:52-54

缓存一致性保证

  • 版本号管理
    • 使用内容哈希与世代号双重机制,确保资源更新时URL变化,打破各级缓存。
  • 缓存预热
    • 发布后对热点资源进行预热,减少首次访问延迟。
  • 分布式缓存同步
    • 在多实例环境下,使用分布式缓存(如Memcached/Redis)共享缓存键与TTL,保证一致性。
    • 写操作后广播失效消息,通知各节点清理相关缓存。
sequenceDiagram
participant Dev as "开发者"
participant Build as "构建系统"
participant CDN as "CDN"
participant App as "应用服务"
Dev->>Build : "提交代码"
Build->>Build : "生成内容哈希"
Build->>CDN : "上传资源并设置长缓存"
Build->>App : "更新Manifest世代号"
App-->>CDN : "URL版本变化触发回源"

图表来源

  • core/web/manifest/ManifestCacheGeneration.php:46-62
  • core/web/template/CompileCache.php:107-155

章节来源

  • core/web/manifest/ManifestCacheGeneration.php:46-62
  • core/web/template/CompileCache.php:107-155

缓存监控与调试工具

  • 缓存命中率统计
    • 在CDN与反向代理层统计命中率,结合应用日志分析缓存效果。
  • 缓存状态检查
    • 通过浏览器开发者工具查看响应头(Cache-Control、ETag、Last-Modified)判断缓存行为。
    • 在服务端记录关键接口的缓存命中情况。
  • 性能分析
    • 使用APM工具分析首字节时间与缓存命中对性能的影响。
    • 对比开启/关闭缓存的性能指标,评估优化效果。

章节来源

  • core/web/http/Response.php:117-136
  • api/controller/bootstrap/LangController.php:44-54

依赖关系分析

  • Response类被所有入口(前台、后台、API)用于发送响应,是缓存头设置的统一出口。
  • 安全中间件在请求处理前后注入安全头,可扩展为缓存相关头。
  • 模板编译缓存与资源版本管理共同作用,确保模板与静态资源的缓存命中与失效。
  • 缓存清理服务提供手动失效能力,配合发布流程使用。
graph LR
Response["Response"] --> Front["前台"]
Response --> Admin["后台"]
Response --> Api["API"]
SecMW["安全中间件"] --> Response
Compile["模板编译缓存"] --> Response
Manifest["资源版本管理"] --> Response
Clear["缓存清理服务"] --> Compile

图表来源

  • core/web/http/Response.php:117-136
  • front/middleware/SecurityHeadersMiddleware.php:23-28
  • core/web/template/CompileCache.php:21-31
  • core/web/manifest/ManifestCacheGeneration.php:21-26
  • admin/service/cache/CacheClearService.php:24-44

章节来源

  • core/web/http/Response.php:117-136
  • front/middleware/SecurityHeadersMiddleware.php:23-28
  • core/web/template/CompileCache.php:21-31
  • core/web/manifest/ManifestCacheGeneration.php:21-26
  • admin/service/cache/CacheClearService.php:24-44

性能考量

  • 合理设置TTL:静态资源使用长TTL,动态内容根据变化频率设置短TTL。
  • 使用ETag与Last-Modified:减少不必要的数据传输,提升带宽利用率。
  • 资源版本化:通过内容哈希与URL参数确保更新时强制回源,避免缓存污染。
  • 缓存预热:对热点资源进行预热,降低首次访问延迟。
  • 监控与分析:持续监控缓存命中率与性能指标,及时调整策略。

故障排查指南

  • 缓存未生效
    • 检查Response是否正确设置Cache-Control与ETag。
    • 确认Web服务器是否对静态资源设置了合适的缓存头。
  • 缓存未更新
    • 检查资源版本是否变化,URL参数是否包含新哈希。
    • 使用缓存清理服务或删除本地编译产物,强制重新生成。
  • 性能下降
    • 分析缓存命中率,调整TTL与策略。
    • 检查是否有过多未命中请求,定位热点资源。

章节来源

  • core/web/http/Response.php:117-136
  • admin/service/cache/CacheClearService.php:41-44
  • core/web/template/CompileCache.php:89-105

结论

通过统一响应头输出、安全中间件、模板编译缓存与资源版本管理,DouPHP提供了完善的HTTP缓存基础设施。结合CDN缓存策略与一致性保证机制,可实现高效稳定的缓存体系。建议在生产环境中持续监控与优化,确保缓存策略与实际业务需求匹配。

附录

  • 配置参考
    • 安全响应头配置位于config/security.php,可在此基础上扩展缓存相关头。
    • 应用配置位于config/config.php,包含数据库与应用密钥等基础设置。
  • 缓存适配器
    • 插件中提供的缓存适配器支持多种后端(如Xcache),可根据需求选择。

章节来源

  • config/security.php:51-87
  • config/config.php:15-52
  • plugin/alipay/sdk/lotusphp_runtime/Cache/Adapter/LtCacheAdapterXcache.php:1-42
添加日期:2026-10-05