2
今天做一篇 laravel-octane 以 frankenphp 作为服务引擎的体验及性能压测。硬件配置与前2篇的相同,环境为 php8.3 + laraval12 + mysql8.4(版本不必太在意,>=php8, >=laravel8, >=mysql7 区别都不大)。

测试基础硬件
image.png

先说结果,非常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次

image.png

cpu 密集型的 3.5kqps

c1k 1w次

image.png

相比 c500 的 qps 还高了一些,说明还没到并发极限。

c5k 5w次

image.png
qps 来到了 3.5k。

c10k来咯 10w次

image.png

依然游刃有余,qps 虽然有所下降,但仍保持在了 3k 以上,抗并发的能力很稳。c10k 已经是我机器 ab 的上限。

db 场景

c500 1w次

image.png

io 密集型的 2k qps。

c1k 1w次

image.png

上升到 c1k, qps 没掉,依然小 2k。

c5k 5w次

image.png

qps 有所下降, 1.6k。

c10k来咯 10w次

image.png

c10k 下依然有着 1.4k 的 qps。

往期参考

  1. webman 体验及性能压测
  2. laravel-octane(swoole) 体验及压测

big_cat
1.7k 声望131 粉丝

规范至上