今天做一篇 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。
往期參考
- webman 體驗及性能壓測
- laravel-octane(swoole) 體驗及壓測