# benchmark **Repository Path**: viswoole/benchmark ## Basic Information - **Project Name**: benchmark - **Description**: viswoole + thinkphp8 性能测试仓库 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-18 - **Last Updated**: 2026-09-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PHP 框架压测对比:viswoole vs ThinkPHP8(FPM / Swoole 两形态) vs Hyperf 基于 Docker 的相同 API 场景压测对比环境,共四组: - **viswoole**([packagist](https://packagist.org/packages/viswoole/viswoole)):基于 Swoole 协程的常驻内存框架,PHP 8.3 + Swoole 6.2 - **ThinkPHP8 - FPM**([packagist](https://packagist.org/packages/topthink/think)):传统 PHP-FPM 部署形态,Nginx + FPM - **ThinkPHP8 - Swoole**:同一份 thinkphp-app 代码 + [think-swoole](https://doc.thinkphp.cn/v8_0/think_swoole.html) 常驻内存形态 - **Hyperf**([官网](https://hyperf.io)):基于 Swoole 协程的常驻内存框架,Hyperf 3.2 + PHP 8.3 + Swoole 6.2 ## 一、环境要求 | 依赖 | 版本 | |---|---| | Docker | >= 20.x | | Docker Compose | v2+ | > 无需本地 PHP/Composer,所有构建与依赖安装均在容器内完成。 ## 二、目录结构 ``` 测试PHP/ ├── viswoole-app/ # viswoole 项目 │ ├── app/Controller/Bench.php # 压测控制器 │ ├── config/server.php # worker 数固定为 4(与 FPM 对齐) │ └── .env # 数据库配置,压测关闭 debug ├── thinkphp-app/ # ThinkPHP8 项目(FPM 与 Swoole 两形态共用此代码) │ ├── app/controller/Bench.php # 压测控制器(行为与 viswoole 侧一致) │ ├── config/swoole.php # think-swoole 配置(port=9502, worker_num=4) │ └── .env ├── hyperf-app/ # Hyperf 项目(官方 hyperf-skeleton 裁剪) │ ├── app/Controller/Bench.php # 压测控制器(行为与其余框架一致) │ ├── config/autoload/server.php # port=9503, worker_num=4, max_request=0 │ ├── config/autoload/databases.php # 连接池 max_connections=64(与 think-swoole 对齐) │ └── .env ├── deploy/ │ ├── mysql/init.sql # 建库建表 + 预置 1000 条用户数据 │ ├── nginx/thinkphp.conf # TP8 站点配置(FPM 转发) │ ├── viswoole.dockerfile # swoole 镜像构建 │ ├── thinkphp.dockerfile # php-fpm 镜像构建(pm.max_children=4) │ ├── thinkswoole.dockerfile # think-swoole 镜像构建 │ ├── hyperf.dockerfile # hyperf 镜像构建(关闭 swoole 短名 + pcntl 扩展) │ └── wrk.dockerfile # wrk 压测客户端镜像 ├── docker-compose.yml # 七服务编排 ├── benchmark/ │ └── run.sh # 压测执行脚本(四组框架) └── results/ # 压测结果归档 ``` ## 三、启动测试 ### 1. 启动全部服务 ```bash docker compose up -d --build ``` 首次构建需拉取镜像、编译扩展、安装依赖,耗时较长。服务构成: | 服务 | 说明 | 宿主机端口 | |---|---|---| | mysql | MySQL 8.0,首次启动自动执行 init.sql | 无(仅内网) | | viswoole | viswoole HTTP 服务 | **19510** → 9501 | | thinkphp | ThinkPHP8 PHP-FPM(FPM 形态) | 无(仅内网 9000) | | thinkswoole | ThinkPHP8 + think-swoole(Swoole 形态) | **19520** → 9502 | | hyperf | Hyperf HTTP 服务(Swoole 常驻形态) | **19530** → 9503 | | nginx | TP8 FPM 形态的 HTTP 入口 | **8080** → 80 | | wrk | 压测客户端(常驻等待 exec 调用) | 无 | ### 2. 验证 API 可用性 ```bash # viswoole(三场景均应返回 JSON,code=0) curl http://localhost:19510/api/json curl http://localhost:19510/api/user/1 curl http://localhost:19510/api/users # ThinkPHP8 - FPM 形态(经 nginx) curl http://localhost:8080/api/json curl http://localhost:8080/api/user/1 curl http://localhost:8080/api/users # ThinkPHP8 - Swoole 形态 curl http://localhost:19520/api/json curl http://localhost:19520/api/user/1 curl http://localhost:19520/api/users # Hyperf curl http://localhost:19530/api/json curl http://localhost:19530/api/user/1 curl http://localhost:19530/api/users ``` ### 3. 执行压测 ```bash ./benchmark/run.sh # 默认:30 秒 / 100 连接 / 4 线程 ./benchmark/run.sh 60 200 8 # 自定义:时长s / 连接数 / 线程数 ``` 压测流量走 docker 内网(wrk 容器直连目标服务),排除宿主机网络抖动干扰。 结果实时打印并归档至 `results/bench_<时间戳>.txt`。 ### 4. 停止与清理 ```bash docker compose down # 停止(保留 MySQL 数据卷) docker compose down -v # 停止并删除数据卷(下次启动重新初始化数据) ``` ## 四、压测场景说明 四组实现完全一致的三类只读 API,保证对比公平: | 场景 | 路径 | 说明 | |---|---|---| | 纯 JSON | `GET /api/json` | 不触库,衡量框架自身开销 | | 单条查询 | `GET /api/user/1` | 主键查找 users 表 | | 列表查询 | `GET /api/users` | `status=1` 按 id 升序前 20 条 | 公平性控制:四组均 PHP 8.3、4 个 worker 进程(swoole worker_num = FPM pm.max_children)、关闭 debug、共用同一 MySQL、相同 SQL、响应体等长(hyperf 的 `data.framework` 值为 6 字符,比其余两框架短 2 字节,可忽略)。think-swoole 与 hyperf 均开启协程 + 数据库连接池。 **连接公平性**(关键):三个 Swoole 框架的数据库连接池为**进程级**,统一对齐为 **每进程上限 10 个**(viswoole 默认 `pool_max_size=10`;think-swoole `max_active=10`;hyperf `max_connections=10`),超时统一 5s,均不预填充。同时每个框架压测前由脚本 `reset_connections()` **重启 mysql + 被测框架容器**,清零历史常驻连接,保证四组在零历史连接的同等环境下测试,避免"先测连接少、后测连接多"的偏差。 ## 五、压测结论(30s / 100 连接 / 4 线程,2026-08-18 公平环境) > 压测脚本会在每个框架测试前自动重启 mysql 与对应框架容器,归还全部连接。 | 场景 | viswoole | TP8-FPM | TP8-Swoole | Hyperf | |---|---|---|---|---| | `GET /api/json` | 42,030 | 2,913 | 17,936 | **57,528** | | `GET /api/user/1` | 9,699 | 792 | 7,815 | **11,866** | | `GET /api/users` | 7,788 | 596 | 6,978 | **10,128** | 四组均无 `Non-2xx` 响应。 从结果可见:三个 Swoole 常驻形态(viswoole / TP8-Swoole / Hyperf)相对 PHP-FPM 有巨大提升;本环境条件下 `Hyperf` 单场景吞吐最高,`viswoole` 紧随其后且相对 TP8-Swoole 同样领先(`/api/json` 约 2.3x);完整原始数据见 `results/bench_20260818_153923.txt`。 延迟对比(Avg / P50 / P99): | 场景 | viswoole | TP8-FPM | TP8-Swoole | Hyperf | |---|---|---|---|---| | `/api/json` | 2.79 / 1.91 / 11.91 ms | 34.86 / 31.98 / 79.28 ms | 6.80 / 6.05 / 11.79 ms | 1.81 / 1.73 / 4.86 ms | | `/api/user/1` | 10.34 / 10.05 / 18.09 ms | 125.89 / 118.28 / 176.99 ms | 12.97 / 12.24 / 22.95 ms | 8.80 / 6.98 / 27.55 ms | | `/api/users` | 13.23 / 11.79 / 35.42 ms | 167.03 / 163.62 / 193.21 ms | 14.32 / 13.99 / 24.04 ms | 10.17 / 10.52 / 27.77 ms | **要点**: - think-swoole 让 ThinkPHP8 吞吐提升约 **5~12 倍**(`/api/json` 17,936 vs 2,913,约 6 倍;数据库场景 lift 更大),且数据库场景收益更大(FPM 每请求重建连接/全量初始化,Swoole 复用连接池与常驻内存)。 - 同为 Swoole 常驻形态且**连接池上限一致(每进程 10)**的情况下,viswoole 相对 TP8-Swoole 快约 **1.1~2.3 倍**(`/api/json` 42,030 vs 17,936,约 2.3x;两个 DB 场景约 1.1~1.2x),Hyperf 单场景整体略高于 viswoole——体现各框架在应用引导、路由分发、请求上下文构建、连接池实现上的开销差异。 - 本环境四组所有场景均无 `Non-2xx` 错误;hyperf `/api/json` 有 1 次 connect timeout(172 万请求,可忽略)。 ## 六、常见问题 - **thinkphp 容器重建后 502**:nginx 缓存了旧容器 IP,执行 `docker compose restart nginx` 即可。 - **宿主机 9501 被占用**:compose 已改用 19510 映射;如需改端口,编辑 `docker-compose.yml` 中 viswoole 服务的 `ports`。 - **MySQL 数据需重置**:`docker compose down -v` 删除数据卷后重新 `up -d`,init.sql 会重新建表灌数据。 - **think-swoole 命令不接受 `start` 子命令**:v4.2 的 `php think swoole` 即直接启动(文档描述过时);`stop/restart` 亦不存在,容器内可用 `docker compose restart thinkswoole` 代替。 - **thinkphp-app 含 think-swoole 依赖**:FPM 形态的 `composer install` 加了 `--ignore-platform-req=ext-swoole`(FPM 不运行 swoole);若需删除该依赖,编辑 `thinkphp-app/composer.json` 移除 `topthink/think-swoole` 后 `composer update`。