直接用k6测试frankenphp并发处理能力需直连其监听端口(如http://127.0.0.1:8000),绕过caddy等反向代理,并结合prometheus指标(frankenphp_queue_depth、frankenphp_threads_busy)定位瓶颈,避免opcache预热、缓存及外部干扰影响结果。

直接用 k6 测试 FrankenPHP 并发处理能力
FrankenPHP 本身不内置压测工具,但和 k6 兼容性极好——只要它能响应 HTTP 请求,k6 就能压。关键不是“能不能跑”,而是确保测试流量真正打到 FrankenPHP 实例,且指标可归因。
k6 脚本必须绕过反向代理直连 FrankenPHP
如果你用 Caddy 做前置代理(常见于生产部署),k6 默认测的是 Caddy,不是 FrankenPHP。而 FrankenPHP 的线程池、队列深度等瓶颈只在它自己进程里暴露。所以测试时必须直连:
- 确认 FrankenPHP 启动时监听的是明确端口(如
--addr :8000),且未被防火墙拦截 - k6 脚本中 URL 写成
http://127.0.0.1:8000/,不要用域名或 HTTPS(除非你已配好本地证书+HTTP/3) - Docker 场景下,确保容器端口映射正确:
-p 8000:8000,并在 k6 脚本中访问宿主机 IP(http://host.docker.internal:8000/) - 用
curl -v http://127.0.0.1:8000/health先验证通路,响应头里要有Server: FrankenPHP
关注 frankenphp_queue_depth 和 threads_busy 率
k6 报的 “95th percentile” 或 “avg duration” 只是表象。FrankenPHP 响应变慢但 CPU 不高,大概率是请求在队列里排队,而非 PHP 执行慢。必须配合 Prometheus 指标看:
- 启动 Caddy 时启用
prometheus指令,并确保/metrics可公开访问(开发环境可临时放开) - 在 k6 脚本中加
setup()和teardown(),分别采集frankenphp_queue_depth和frankenphp_threads_busy初始值与终值 - 若
frankenphp_queue_depth持续 > 0,说明线程池已满,新请求进不来;此时再提高 k6 并发数只会拉长排队时间,不是提升吞吐 - 计算
frankenphp_threads_busy / frankenphp_threads_total比值:超过 0.8 就该调大线程池(通过--num-workers或 Caddyfile 中num_workers)
worker 模式下避免脚本级阻塞拖垮全局
如果你用的是 worker 模式(如 frankenphp php-server --worker ws.php),k6 测的是整个 Worker 进程的吞吐能力。一个慢请求(比如没设超时的 curl_exec() 或未释放的 PDO 连接)会卡住整个线程,导致所有后续请求排队。
- 在 worker 脚本里对所有外部调用加硬超时:
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 2000),禁用CURLOPT_RETURNTRANSFER以外的阻塞行为 - 避免在 worker 全局作用域做耗时初始化(如读大文件、建长连接),应移到每个请求处理块内,或用懒加载
- k6 测试时用
stages渐进加压(如 10→50→100→200 VU),观察frankenphp_queue_depth是否在某一点陡升——那就是你的 worker 容量拐点 - 别依赖
memory_get_usage()看单次请求,worker 进程内存是累积的;要查VmRSS(cat /proc/$(pgrep -f frankenphp)/status | grep VmRSS)判断是否泄漏
最常被忽略的点:k6 测试结果不准,往往不是脚本写得不对,而是没关掉 OPcache 预热干扰、没清空 Caddy 缓存、或者压测期间同时开着浏览器标签页抢 EventSource 连接数。真实压测前,先停掉所有非必要服务,只留 FrankenPHP 和 k6。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











