wrk是压测frankenphp数据库接口的唯一靠谱工具:它复用连接、支持http/2、真实模拟客户端,命令示例为wrk -t4 -c100 -d30s -h "accept: application/json" http://localhost:8000/api/users。

用 wrk 压测数据库查询接口,别用 ab
ab 不支持 HTTP/2+,且连接模型粗暴,容易把 FrankenPHP 的 worker 池打穿,测出来的是连接层瓶颈,不是真实 PHP 查询吞吐。wrk 才是唯一靠谱选择:它复用连接、支持 HTTP/2、能真实模拟客户端行为。
关键命令示例:wrk -t4 -c100 -d30s -H "Accept: application/json" http://localhost:8000/api/users
其中 -t4 是 4 个线程,-c100 是维持 100 个长连接,-d30s 是压测 30 秒——这个组合能避开冷启动偏差,又不会因连接数过高触发 FrankenPHP 内部排队。
- 必须加
-H "Accept: application/json",否则 FrankenPHP 可能误判为静态请求,跳过 PHP 执行逻辑 - 路径必须明确走数据库逻辑,比如
/api/users,而不是/或/index.php(后者可能命中 Caddy 静态服务) - 避免用 HTTPS 压测初期比对:TLS 握手抖动会掩盖 PHP 层真实延迟,先测
http://,再单独验证 HTTPS 开销
确保每次压测前清空 OPcache 和 DB 连接池
FrankenPHP 的 QPS 对状态非常敏感。两次压测结果差 2 倍,90% 是因为没重置底层状态。
- 每次压测前执行:
frankenphp php-cli -r "opcache_reset();",否则第二次请求会因 OPcache 命中虚高 - 如果用了 PDO 或 Laravel 的 DB 连接池,需确认
--max-requests设置合理(建议设为1000);设为0虽短期快,但连接泄漏会让后续请求变慢甚至超时 - 禁用开发模式的文件监听(如
--watch),否则 chokidar 会频繁 reload,worker 状态无法稳定
区分“接口吞吐”和“纯 SQL 吞吐”,别被框架层拖累
你压的是 /api/users,但真正瓶颈可能不在 MySQL,而在 Laravel 的中间件、序列化或响应构造。要定位,得拆开看。
- 写一个最小化脚本(如
bench-db.php)绕过框架:<?php $pdo = new PDO("mysql:host=localhost;dbname=test", "user", "pass"); $stmt = $pdo->query("SELECT id,name FROM users LIMIT 10"); print json_encode($stmt->fetchAll()); ?> - 用相同 wrk 命令压这个脚本,对比框架接口的 QPS。如果差距 >30%,说明框架初始化或中间件是瓶颈,不是数据库本身
- 检查日志里是否有慢查询提示;FrankenPHP 不自带 slow log,需在
php.ini中显式开启slowlog = /var/log/php-slow.log和request_slowlog_timeout = 500ms
注意 FrankenPHP 的上传与内存配置对 DB 接口的影响
FrankenPHP 默认把小文件上传放在内存里,这个机制会影响整个 worker 的内存水位,间接拖慢数据库查询响应。
- 确认
upload_max_filesize和post_max_size在php.ini中设为合理值(如8M),不要留默认的2M—— 小值会导致大请求频繁落盘,抢占 I/O - DB 查询若返回大量数据(如导出接口),需手动调用
gc_collect_cycles()防止内存堆积;FrankenPHP 的 worker 不像 FPM 那样自动 GC - 用
memory_get_peak_usage(true)在脚本末尾打印峰值内存,如果接近memory_limit的 80%,就要考虑分页或流式响应
最常被忽略的一点:FrankenPHP 的 --workers 数量和 CPU 核心数不是线性关系。设为 8 之后再加 worker,QPS 往往不升反降——因为 MySQL 连接池和系统文件描述符开始争抢,而不是 PHP 处理变快了。压测时务必固定这个参数,只调 DB 层配置。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











