今天做一篇 laravel-octane 以 frankenphp 作为服务引擎的体验及性能压测。硬件配置与前2篇的相同,环境为 php8.3 + laraval12 + mysql8.4(版本不必太在意,>=php8, >=laravel8, >=mysql7 区别都不大)。
测试基础硬件
先说结果,非常ok:cpu 密集型
场景最优 3.5k 的qps;io 密集型
场景最优 2k 的 qps。能抗 c10k
。
FrankenPHP
FrankenPHP 是一个基于 Go 语言和 Caddy Web 服务器的现代 PHP 应用服务器,旨在通过优化架构显著提升 PHP 应用的性能、简化部署流程,并支持 HTTP/3 等前沿特性。其核心功能包括高性能的 Worker 模式、自动 HTTPS、兼容主流框架(如 Symfony 和 Laravel),以及通过 PHP 基金会支持的持续生态发展(现在得到了 PHP 基金会的官方支持)。
个人简单理解:frankphp 使用 go 的 协程池 作为代替 fpm 的 fast-cgi 进程池,协程的轻量级和高性能无需多言,每个请求都交由携带 php 解释器的 常驻协程 去执行,代码块首次载入请求预热后,后续的执行就是常驻内存模式的速度了。
laravel 集成 FrankenPHP 的方式有多种,可参见官方文档,这里我们选择最 laravel 生态的方式 octane-frankenphp。
创建 laravel & 安装 octane
composer create-project laravel/laravel --prefer-dist -vvv laravel_octane
cd laravel_octane
# 安装 octane
composer require laravel/octane
# 安装 octane 的 frankenphp 引擎
php artisan octane:install --server=frankenphp
# .env
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=laravel_octane
DB_USERNAME=root
DB_PASSWORD=123456
...
OCTANE_SERVER=frankenphp
OCTANE_HTTPS=false
启动服务
# php artisan octane:start
php artisan octane:frankenphp
访问测试
curl -XGET http://127.0.0.1:8000/
压测代码
诸位自取
routes/api.php
<?php
use App\Http\Controllers\TestController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
Route::group(['prefix' => 'v1'], function () {
Route::get('/clock', fn() => [
'err' => 0,
'msg' => 'server time',
'data' => [
'clock' => now()
]
]);
Route::any('/db', [TestController::class, 'db']);
});
app/Http/Controllers/TestController.php
<?php
namespace App\Http\Controllers;
use App\Models\Test;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function db()
{
$nameList = ['james', 'lucy', 'jack', 'jessica', 'lily'];
$hobbyList = ['football', 'basketball', 'swimming'];
$name = $nameList[array_rand($nameList)];
$hobby = $hobbyList[array_rand($hobbyList)];
if (mt_rand(0, 5) >= 2) {// 0-1读 2-5写
$test = new Test();
$test->name = $name;
$test->age = 18;
$test->sex = 1;
$test->hobby = $hobby;
$test->save();
$data = ['id' => $test->id];
} else {
$data = Test::query()->where('hobby', $hobby)->first();;
}
return $data;
}
}
app/Models/Test.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
/**
* Class Test
*
* @package App\Models
* @property int id
* @property string name
* @property int age
* @property string sex
* @property string hobby
*/
class Test extends Model
{
use HasFactory;
/**
* @var string
*/
protected $table = 'test';
const CREATED_AT = null;
const UPDATED_AT = null;
}
sql
CREATE TABLE `test` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
`age` int NOT NULL,
`sex` char(1) COLLATE utf8mb4_general_ci NOT NULL,
`hobby` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_hobby` (`hobby`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
注意:laravel APP_ENV 要设置为 production,local 下 frankenphp 性能会折半
。
hello world 场景
c500 1w次
cpu 密集型的 3.5kqps
c1k 1w次
相比 c500 的 qps 还高了一些,说明还没到并发极限。
c5k 5w次
qps 来到了 3.5k。
c10k来咯 10w次
依然游刃有余,qps 虽然有所下降,但仍保持在了 3k 以上,抗并发的能力很稳。c10k 已经是我机器 ab 的上限。
db 场景
c500 1w次
io 密集型的 2k qps。
c1k 1w次
上升到 c1k, qps 没掉,依然小 2k。
c5k 5w次
qps 有所下降, 1.6k。
c10k来咯 10w次
c10k 下依然有着 1.4k 的 qps。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。