Caddy内置HTTP缓存(RFC 7234),不提供PHP应用层缓存;需通过cache指令配置并由PHP主动输出Cache-Control头才能命中,配合APCu/Redis可实现双层减压。

Caddy 本身不提供类似 Redis 或 APCu 那样的 PHP 应用层缓存,它内置的是 HTTP 缓存(RFC 7234),作用在响应头和代理层,用于减少对后端 PHP 的重复请求。FrankenPHP 作为 Caddy 的模块,不额外增加缓存逻辑,所有缓存行为都由 Caddy 的 cache 指令控制——它能有效减轻 PHP 执行压力,但只适用于满足 HTTP 缓存语义的场景。
启用 Caddy 原生 HTTP 缓存
Caddy 的 cache 是一个可选插件,需确认已启用(dunglas/frankenphp 镜像默认包含)。在 Caddyfile 中添加即可:
- 全局启用(推荐放在顶层块):
{<br> cache<br>} - 或在站点块中按需启用:
example.com {<br> cache {<br> default_cache_max_age 5m<br> match {<br> header Accept application/json<br> path /api/products/*<br> }<br> }<br> php_server<br>}
让缓存真正命中 PHP 的前提
不是所有 PHP 响应都能被缓存。Caddy 默认只缓存带明确 Cache-Control 或 Expires 头、且状态码为 200/203/206/300/301/410 的响应。所以 PHP 脚本必须主动输出缓存头:
- 在 Laravel 控制器中:
return response($data)->header('Cache-Control', 'public, max-age=300'); - 在原生 PHP 中:
header('Cache-Control: public, max-age=300');<br>echo json_encode($data); - 避免动态头干扰:禁用
X-Powered-By、不写Cache-Control: no-store等禁止缓存的指令
配合 PHP 应用层缓存更有效
Caddy 的 HTTP 缓存是「边缘缓存」,适合静态化接口或读多写少的 API;但它不能替代应用内缓存。真实减压需要双层协同:
立即学习“PHP免费学习笔记(深入)”;
- 第一层(Caddy):缓存整个 HTTP 响应(含状态码、头、体),避免进入 PHP 进程
- 第二层(PHP):用 APCu(单机)或 Redis(集群)缓存数据库查询、配置等,缩短单次 PHP 执行时间
- 关键点:Caddy 缓存对 POST/PUT/DELETE 请求默认不生效,这类请求仍需靠 PHP 层缓存优化
注意失效与调试
Caddy 缓存不感知 PHP 数据变更,更新数据后需手动清理或依赖 TTL 自动过期:
- 查看是否命中:
响应头出现Age: 120表示命中缓存;Cache-Status: HIT是更明确的标识(需 Caddy v2.8+) - 临时清空:
发送curl -X PURGE https://example.com/api/products/123(需配置cache { policy purge }) - 禁用某路径缓存:
在match中排除,或 PHP 返回Cache-Control: no-cache



















