PHP项目Laravel基准性能测试工具

wen PHP项目 3

本文目录导读:

PHP项目Laravel基准性能测试工具

  1. Laravel内置性能工具
  2. 基准测试工具
  3. PHP性能分析工具
  4. 创建自定义基准测试
  5. 前端性能监控
  6. 完整基准测试脚本
  7. 使用方法
  8. Docker环境监测

我来为您介绍PHP Laravel项目的基准性能测试工具和方法。

Laravel内置性能工具

Laravel Telescope

# 安装
composer require laravel/telescope
# 发布资源
php artisan telescope:install
php artisan migrate

Laravel Debugbar

# 安装
composer require barryvdh/laravel-debugbar
# 发布配置(开发环境)
php artisan vendor:publish --provider="Barryvdh\Debugbar\ServiceProvider"

基准测试工具

ApacheBench (ab)

# 基本用法
ab -n 1000 -c 100 http://your-app.test/api/users
# 带认证
ab -n 1000 -c 100 -H "Authorization: Bearer TOKEN" http://your-app.test/api/users
# POST请求
ab -n 100 -c 10 -p post_data.json -T application/json http://your-app.test/api/users

Siege

# 安装
apt-get install siege
# 基准测试
siege -c 100 -r 10 -f urls.txt
# 并发100,持续60秒
siege -c 100 -t 60S http://your-app.test/api/users

PHP性能分析工具

Xdebug Profiler

; php.ini配置
xdebug.mode = profile
xdebug.output_dir = /tmp/profiler

Blackfire.io

# 安装Blackfire CLI
curl -s https://blackfire.io/install | sh
# 配置环境变量
export BLACKFIRE_CLIENT_ID=xxx
export BLACKFIRE_CLIENT_TOKEN=xxx
# 性能分析
blackfire run php artisan serve

创建自定义基准测试

创建基准测试类

<?php
// app/Console/Commands/BenchmarkCommand.php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
class BenchmarkCommand extends Command
{
    protected $signature = 'benchmark:run {--requests=100 : 请求次数} {--concurrency=10 : 并发数}';
    public function handle()
    {
        $requests = $this->option('requests');
        $concurrency = $this->option('concurrency');
        $this->info('开始基准测试...');
        $results = [
            'database' => $this->benchmarkDatabase(),
            'cache' => $this->benchmarkCache(),
            'api' => $this->benchmarkApi($requests, $concurrency),
            'view' => $this->benchmarkView(),
        ];
        $this->outputResults($results);
    }
    protected function benchmarkDatabase()
    {
        $times = [];
        for ($i = 0; $i < 100; $i++) {
            $start = microtime(true);
            DB::table('users')->take(10)->get();
            $times[] = (microtime(true) - $start) * 1000;
        }
        return $this->calculateStats($times);
    }
    protected function benchmarkCache()
    {
        $times = [];
        for ($i = 0; $i < 100; $i++) {
            $key = "benchmark_key_{$i}";
            $start = microtime(true);
            Cache::put($key, 'value', 60);
            Cache::get($key);
            $times[] = (microtime(true) - $start) * 1000;
        }
        Cache::flush();
        return $this->calculateStats($times);
    }
    protected function benchmarkApi($requests, $concurrency)
    {
        // 使用Guzzle进行并发请求
        $client = new \GuzzleHttp\Client();
        $times = [];
        $promises = [];
        for ($i = 0; $i < $requests; $i++) {
            $start = microtime(true);
            $promises[] = $client->getAsync('http://localhost:8000/api/test')
                ->then(function () use (&$times, $start) {
                    $times[] = (microtime(true) - $start) * 1000;
                });
        }
        \Illuminate\Support\Facades\Promise\Utils::settle($promises)->wait();
        return $this->calculateStats($times);
    }
    protected function benchmarkView()
    {
        $times = [];
        for ($i = 0; $i < 50; $i++) {
            $start = microtime(true);
            view('welcome')->render();
            $times[] = (microtime(true) - $start) * 1000;
        }
        return $this->calculateStats($times);
    }
    protected function calculateStats($times)
    {
        sort($times);
        $count = count($times);
        return [
            'count' => $count,
            'min' => round(min($times), 2),
            'max' => round(max($times), 2),
            'avg' => round(array_sum($times) / $count, 2),
            'median' => round($times[$count / 2], 2),
            'p95' => round($times[intval($count * 0.95)], 2),
            'p99' => round($times[intval($count * 0.99)], 2),
            'throughput' => round(1000 / (array_sum($times) / $count), 2) . ' req/s',
        ];
    }
    protected function outputResults($results)
    {
        $this->table(
            ['指标', '最小值(ms)', '最大值(ms)', '平均(ms)', '中位数(ms)', 'P95(ms)', 'P99(ms)', '吞吐量'],
            collect($results)->map(function ($data, $name) {
                return [
                    $name,
                    $data['min'],
                    $data['max'],
                    $data['avg'],
                    $data['median'],
                    $data['p95'],
                    $data['p99'],
                    $data['throughput']
                ];
            })
        );
    }
}

前端性能监控

安装性能监控中间件

// app/Http/Middleware/PerformanceMonitor.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Log;
class PerformanceMonitor
{
    public function handle($request, Closure $next)
    {
        $start = microtime(true);
        $response = $next($request);
        $duration = (microtime(true) - $start) * 1000;
        if ($duration > 500) { // 超过500ms
            Log::warning('慢请求', [
                'url' => $request->fullUrl(),
                'method' => $request->method(),
                'duration' => round($duration, 2) . 'ms',
                'memory' => memory_get_peak_usage(true) / 1024 / 1024 . 'MB'
            ]);
        }
        return $response;
    }
}

完整基准测试脚本

<?php
// scripts/benchmark.php
require __DIR__ . '/vendor/autoload.php';
$app = require_once __DIR__ . '/bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$kernel->bootstrap();
class DumpPerformance
{
    private $configs = [
        'queries' => 1000,
        'users' => 100,
        'concurrent' => 50
    ];
    public function run()
    {
        echo "=== Laravel 基准测试 ===\n\n";
        $results = [];
        // 数据库性能
        $results['查询性能 (1000条记录读取)'] = $this->testQueries();
        // 路由性能
        $results['路由解析性能 (100次)'] = $this->testRouting();
        // 视图渲染
        $results['视图渲染性能 (100次)'] = $this->testViews();
        // 缓存性能
        $results['缓存读写性能 (1000次)'] = $this->testCache();
        // 内存使用
        $results['内存使用'] = $this->testMemory();
        foreach ($results as $name => $data) {
            echo "{$name}:\n";
            if (is_array($data)) {
                foreach ($data as $key => $value) {
                    echo "  {$key}: {$value}\n";
                }
            } else {
                echo "  {$data}\n";
            }
            echo "\n";
        }
    }
    private function testQueries() 
    {
        DB::enableQueryLog();
        $start = microtime(true);
        for ($i = 0; $i < $this->configs['queries']; $i++) {
            DB::table('users')->take(5)->get();
        }
        $duration = microtime(true) - $start;
        return [
            '耗时' => round($duration * 1000, 2) . ' ms',
            '平均查询时间' => round(($duration / $this->configs['queries']) * 1000, 4) . ' ms',
            '查询次数' => count(DB::getQueryLog())
        ];
    }
    private function testRouting()
    {
        $start = microtime(true);
        for ($i = 0; $i < 100; $i++) {
            Route::get('/test-route', function() { return 'ok'; });
            $request = Request::create('/test-route', 'GET');
            app()->handle($request);
        }
        $duration = microtime(true) - $start;
        return [
            '耗时' => round($duration * 1000, 2) . ' ms',
            '平均路由时间' => round(($duration / 100) * 1000, 2) . ' ms'
        ];
    }
    private function testViews()
    {
        $start = microtime(true);
        for ($i = 0; $i < 100; $i++) {
            $view = view('welcome')->render();
        }
        $duration = microtime(true) - $start;
        return [
            '耗时' => round($duration * 1000, 2) . ' ms',
            '平均视图渲染时间' => round(($duration / 100) * 1000, 2) . ' ms',
            '视图大小' => strlen($view) . ' bytes'
        ];
    }
    private function testCache()
    {
        Cache::flush();
        $start = microtime(true);
        for ($i = 0; $i < $this->configs['queries']; $i++) {
            $key = "benchmark_{$i}";
            Cache::put($key, 'value', 60);
            Cache::get($key);
            Cache::forget($key);
        }
        $duration = microtime(true) - $start;
        return [
            '耗时' => round($duration * 1000, 2) . ' ms',
            '平均操作时间' => round(($duration / ($this->configs['queries'] * 3)) * 1000, 4) . ' ms'
        ];
    }
    private function testMemory()
    {
        $startMemory = memory_get_usage();
        // 模拟数据处理
        $data = range(1, 10000);
        $processed = array_map(function($item) {
            return $item * 2;
        }, $data);
        $endMemory = memory_get_usage();
        return [
            '开始内存' => round($startMemory / 1024 / 1024, 2) . ' MB',
            '结束内存' => round($endMemory / 1024 / 1024, 2) . ' MB',
            '内存增量' => round(($endMemory - $startMemory) / 1024 / 1024, 2) . ' MB'
        ];
    }
}
$perf = new DumpPerformance();
$perf->run();

使用方法

# 运行自定义基准测试
php artisan benchmark:run --requests=100 --concurrency=10
# 运行完整测试脚本
php scripts/benchmark.php
# ApacheBench 测试
ab -n 1000 -c 100 -H "Accept: application/json" http://localhost:8000/api/users
# 使用Tinker进行快速测试
php artisan tinker
> $start = microtime(true);
> User::all();
> echo (microtime(true) - $start) * 1000 . 'ms';

Docker环境监测

# docker-compose.yml 添加监控服务
  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"

这些工具能帮助您全面评估Laravel应用的性能,建议在生产环境前进行充分的基准测试,并根据结果优化代码。

抱歉,评论功能暂时关闭!