workers.count是FrankenPHP启动时预分配的PHP线程总数,即底层能同时处理请求的执行单元上限;它不是Laravel Octane的--workers参数,也不是Caddy并发连接数或PHP应用实例数,仅控制可调度执行PHP代码的线程数量。

workers.count 是什么,不是什么
workers.count 是 FrankenPHP 启动时预分配的 PHP 线程总数,也就是底层能同时处理请求的执行单元上限。它不是 Laravel Octane 的 --workers 参数,也不是 Caddy 的并发连接数,更不是你服务器上能跑几个 PHP 应用——它只管“有多少个线程可被调度来执行 PHP 代码”。
怎么设才不爆内存也不浪费
核心约束只有一条:workers.count × memory_limit 必须小于服务器可用内存(不含 swap)。比如 2G 内存的机器,memory_limit 设为 128M,那 workers.count 最多只能是 15,但实际建议压得更低。
- 1 核 CPU:设
workers.count 1或2,再多会因上下文切换拖慢响应 - 4 核服务器:从
6起步,不要直接用默认的8(CPU×2) - 8 核及以上:可试
12~16,但必须配合压测看frankenphp_busy_threads是否长期接近frankenphp_total_threads - 如果应用大量依赖 MySQL/Redis 等外部 I/O,可适当加 1–2 个线程;纯 CPU 密集型则应减少
Octane 场景下怎么配才不报 resource temporarily unavailable
当 Laravel Octane 和 FrankenPHP 一起用时,--workers=4 这类参数必须 ≤ workers.count,否则 Octane 想拉 worker 却分不到线程,就会报 failed to spawn worker: resource temporarily unavailable。
- Octane 启动命令必须带
--server=frankenphp,否则它走自己的 Swoole/RoadRunner,完全无视workers.count - Caddyfile 中不能用
reverse_proxy转发到 Octane 的 HTTP 端口,必须用php_server直接执行index.php - 推荐起步值:
--workers=min(4, workers.count),再根据frankenphp_busy_threads / frankenphp_total_threads比值调优 - 比值长期 >0.9 且 QPS 上不去 → 加
workers.count;比值长期 --workers
怎么验证当前配置是否合理
别只看平均延迟或 RPS,重点盯长尾和进程稳定性:
立即学习“PHP免费学习笔记(深入)”;
- 用
watch -n 1 'ps aux | grep frankenphp-worker | wc -l'看 worker 数量是否稳定(波动 ±1 正常,持续增减说明配置冲突) - 压测时观察
frankenphp_queue_depth是否持续上涨:涨了说明线程不够,请求在排队 - 查日志里
Worker #X restarted after max_requests出现频率:每分钟都重启,说明max_requests太小或内存限制太紧 - 在控制器里打点:
error_log('mem: ' . memory_get_peak_usage(true));,连续请求看内存峰值是否阶梯式上升(泄漏)或周期性回落(健康)
线程数不是越大越好,也不是越小越省;它是个需要对齐应用行为、I/O 特征和硬件资源的平衡点,调完不验证等于没调。



















