必须在Caddy层统一配置timeout指令(如timeout 45s),FrankenPHP自身无HTTP超时API;需同步设php.ini的max_execution_time为小5秒值,并为cURL、PDO、Redis等外部调用单独配置毫秒级超时,否则worker将被卡死。

在macOS上为FrankenPHP v1.2.1配置请求超时时间,必须绕过PHP层幻想——FrankenPHP自身不提供HTTP请求超时控制API,所有面向客户端的超时都由Caddy强制接管,漏配Caddy层将导致504错误与后台脚本持续运行并锁死worker。
Caddyfile中设置全局HTTP请求超时
打开你的Caddyfile(通常位于项目根目录或/usr/local/etc/caddy/Caddyfile),定位到包含php_server或frankenphp指令的server块内。
在php_server指令下方添加timeout子指令,例如:
php_server {<br> timeout 45s<br>}
立即学习“PHP免费学习笔记(深入)”;
这行必须写在php_server块内部,不能放在reverse_proxy块外或http块顶层;【timeout值必须小于Caddy reverse_proxy的idle超时,且不能设为0】。若你同时用reverse_proxy转发到其他服务,还需单独配其transport timeout,否则FrankenPHP worker会被卡住不释放。
同步调整php.ini中的max_execution_time
执行php --ini确认当前生效的php.ini路径,常见位置为/usr/local/etc/php/8.3/php.ini(版本号依实际安装而定)。
用编辑器打开该文件,搜索max_execution_time,将其值设为比Caddy timeout小5秒左右,例如Caddy设了45s,这里就写max_execution_time = 40。
保存后重启Caddy服务:sudo brew services restart caddy(若用Homebrew安装)或sudo systemctl restart caddy(若用systemd)。不要只改PHP配置却不重启Caddy——Caddy层超时会先于PHP中断连接,改了也没用。
为外部调用显式设超时(cURL、PDO、Redis)
方法一:cURL请求必须手动加毫秒级超时
在PHP代码中,每次初始化cURL句柄后立即设置:
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 3000);<br>curl_setopt($ch, CURLOPT_TIMEOUT_MS, 8000);
方法二:MySQLi连接需在mysqli_init之后、real_connect之前调用options
mysqli_options($mysqli, MYSQLI_OPT_CONNECT_TIMEOUT, 3);<br>mysqli_options($mysqli, MYSQLI_OPT_READ_TIMEOUT, 7);<br>mysqli_options($mysqli, MYSQLI_OPT_WRITE_TIMEOUT, 7);
方法三:Redis客户端(如Predis)构造时传入timeout参数
new Predis\Client([<br> 'scheme' => 'tcp',<br> 'host' => '127.0.0.1',<br> 'port' => 6379,<br> 'timeout' => 2,<br> 'read_write_timeout' => 3<br>]);
【未设超时的cURL或PDO调用会独占worker进程,导致后续请求全部排队积压】。FrankenPHP没有后台GC机制回收卡死连接,这类调用一旦挂住,整个worker就废了。
验证Caddy连接复用与空闲超时行为
第一步:在Caddyfile的全局区(server块外)添加debug日志
log {<br> level debug<br>}
第二步:重启Caddy,用curl -v http://localhost/your-script.php发起请求
第三步:检查Caddy error.log,搜索connection closed或idle timeout字段
第四步:确认响应头含Connection: keep-alive且Server: Caddy——若显示Nginx或envoy,说明你前面还套了反向代理,超时源头不在FrankenPHP或Caddy,而在上游设备。
第五步:在Caddyfile的reverse_proxy块中显式配置transport keepalive(即使你没用reverse_proxy转发,FrankenPHP内部也走此通道):
reverse_proxy http://127.0.0.1:8080 {<br> transport http {<br> keepalive 25s<br> }<br>}



















