frankenphp重载仅热更新caddyfile配置(路由、tls、静态路径等),不重启php运行时和worker实例;重启则彻底终止进程并冷启动,重建php环境与worker。

FrankenPHP 重载(reload)到底做了什么
重载不是重启,它只重新加载 Caddyfile 配置并热更新路由、TLS 证书、静态文件路径等前端能力,PHP 运行时和已启动的 Worker 实例完全不受影响。这意味着你改了 route 规则或加了新域名,执行 caddy reload 后立刻生效,所有正在运行的 Laravel Worker 还在内存里继续处理请求,框架容器、数据库连接、OPcache 编译结果全保留。
常见错误现象:改完 Caddyfile 后 caddy reload 报错“invalid PHP root”,其实是 php 指令里的 root 路径写错了——重载会校验配置语法,但不会销毁 PHP 线程池。
- 适用场景:日常配置微调(如新增 location、调整 gzip、更新证书路径)
- 不触发 PHP 重新初始化,
frankenphp_busy_threads不归零 - Worker 脚本不会重启,
frankenphp_worker_restarts_total计数不变 - 如果启用了 Caddy 的自动 HTTPS,
reload会触发证书续期检查(但仅当证书快过期时才真正拉取)
FrankenPHP 重启(restart)真正干了什么
重启是彻底终止整个进程,包括 Caddy HTTP 服务、PHP 线程池、所有常驻 Worker 实例。下次启动时,会从头读取 Caddyfile、重建 TLS 上下文、重新初始化 PHP 运行时、重新加载扩展、重新执行 OPcache preload(如果配置了)、再按需拉起新的 Worker。这相当于把整个应用服务器“冷启动”一遍。
容易踩的坑:直接 systemctl restart frankenphp 或 kill 后手动 frankenphp server,会导致所有活跃 Worker 立即销毁,Laravel 容器重建、DB 连接断开、缓存失效——用户可能看到短暂 502 或接口延迟突增。
- 适用场景:升级 FrankenPHP 二进制、更换 PHP 版本、修改全局 PHP 配置(如
php.ini路径)、修复 Worker 崩溃后状态不一致 - 必须确保
php指令中指定了worker参数,否则重启后 Worker 不会自动恢复 - 若用
frankenphp.NewPrometheusMetrics注册了指标,重启后所有frankenphp_*指标计数器会重置(Gauge 类除外)
为什么不能靠 reload 解决所有问题
reload 只管配置,不管代码和运行时状态。比如你改了 Laravel 的 config/app.php,或者更新了 Composer 包,reload 完全无感——因为 Worker 还拿着旧的容器实例在跑。只有重启才能让 PHP 运行时重新 require 所有文件、重新注册服务提供者。
- 框架配置变更(如中间件顺序、缓存驱动切换)必须重启
- Worker 脚本本身有语法错误,reload 不报错,但首次请求会 500;重启时会在启动阶段就报错退出
- 某些扩展(如
opcache.enable_cli=1)只在 PHP 初始化时读取,reload 不重读 ini 文件 - 如果你依赖
__destruct或register_shutdown_function做清理,它们只在 Worker 销毁时触发——也就是重启时才发生
生产环境该选 reload 还是 restart
能 reload 就别 restart。reload 是零停机的,restart 必然有连接中断窗口。但别迷信 reload —— 它掩盖不了代码级变更。上线前务必确认:这次改动是否触及 PHP 运行时或 Worker 生命周期?如果是,就得接受那几秒不可用,安排在低峰期 restart。
最常被忽略的一点:FrankenPHP 的 worker 模式默认不支持“平滑替换 Worker 实例”。也就是说,即使你改了 worker.php 文件内容,reload 不会杀掉旧 Worker 并拉起新版本;必须 restart 才能生效。这点和 Swoole 的 hot-reload 或 RoadRunner 的 worker rolling update 有本质区别。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











