Laravel المتقدم

Laravel Octane والأداء العالي

18 دقيقة الدرس 27 من 40

Laravel Octane والأداء العالي

Laravel Octane يعزز أداء تطبيقك بشكل كبير من خلال تقديمه باستخدام خوادم تطبيقات عالية الأداء مثل Swoole و RoadRunner. تحتفظ هذه الخوادم بتطبيقك محملاً في الذاكرة، مما يقلل بشكل كبير من أوقات الاستجابة ويزيد من الإنتاجية.

مكاسب الأداء: يمكن لـ Octane التعامل مع 2-10 أضعاف عدد الطلبات في الثانية مقارنة بنشر PHP-FPM التقليدي، مع تقليل أوقات الاستجابة بنسبة 50-80٪ في كثير من الحالات.

فهم Swoole مقابل RoadRunner

Swoole: إطار برمجة غير متزامن على مستوى الإنتاج لـ PHP مع coroutines وحلقات الأحداث ودعم الألياف.

RoadRunner: خادم تطبيقات PHP عالي الأداء مكتوب بلغة Go، يستخدم العمال لخدمة الطلبات.

<?php // التثبيت - Swoole // composer require laravel/octane // php artisan octane:install --server=swoole // التثبيت - RoadRunner // composer require laravel/octane // php artisan octane:install --server=roadrunner // بدء خادم Octane // php artisan octane:start // البدء بمنفذ مخصص وعمال // php artisan octane:start --port=8000 --workers=4 // وضع الإنتاج مع عدد أعلى من العمال // php artisan octane:start --workers=8 --task-workers=6 --max-requests=500
اختيار الخادم: استخدم Swoole إذا كنت بحاجة إلى ميزات متقدمة مثل coroutines و WebSockets والعمليات غير المتزامنة. استخدم RoadRunner لعمليات النشر الأبسط مع أداء ممتاز قائم على Go وتصحيح أخطاء أسهل.

إعداد وتكوين Octane

<?php // config/octane.php return [ 'server' => env('OCTANE_SERVER', 'swoole'), 'https' => env('OCTANE_HTTPS', false), 'listeners' => [ WorkerStarting::class => [ EnsureUploadedFilesAreValid::class, EnsureUploadedFilesCanBeMoved::class, ], RequestReceived::class => [ ...Octane::prepareApplicationForNextOperation(), ...Octane::prepareApplicationForNextRequest(), ], RequestHandled::class => [], RequestTerminated::class => [ FlushUploadedFiles::class, ], TaskReceived::class => [ ...Octane::prepareApplicationForNextOperation(), ], TaskTerminated::class => [], TickReceived::class => [], TickTerminated::class => [], OperationTerminated::class => [ FlushTemporaryContainerInstances::class, ], WorkerErrorOccurred::class => [ ReportException::class, StopWorkerIfNecessary::class, ], WorkerStopping::class => [], ], 'warm' => [ // الفئات التي يجب تسخينها عند تشغيل العامل ...Octane::defaultServicesToWarm(), ], 'cache' => [ 'driver' => env('OCTANE_CACHE_DRIVER', 'array'), ], 'tables' => [ 'example' => [ 'size' => 1000, 'columns' => [ ['name' => 'id', 'type' => Table::TYPE_INT], ['name' => 'name', 'type' => Table::TYPE_STRING, 'size' => 1000], ], ], ], ];

إدارة الذاكرة في Octane

نظرًا لأن تطبيقك يبقى في الذاكرة، يجب أن تكون حذرًا من تسرب الذاكرة وتلوث الحالة:

<?php // خطأ - الخصائص الثابتة تستمر عبر الطلبات class UserController extends Controller { protected static $users = []; public function index() { // هذا سوف يتراكم البيانات عبر الطلبات! self::$users[] = User::all(); return view('users.index', ['users' => self::$users]); } } // صحيح - استخدم البيانات محددة النطاق للطلب class UserController extends Controller { public function index() { $users = User::all(); return view('users.index', ['users' => $users]); } } // أنماط آمنة لـ Octane class CacheService { protected $cache; public function __construct() { // التبعيات المحقونة آمنة $this->cache = app('cache'); } public function remember($key, $value) { // استخدم جداول Octane للتخزين المؤقت للحالة المشتركة return Cache::store('octane')->remember($key, 3600, function () use ($value) { return $value(); }); } }
تحذير من تسرب الذاكرة: تجنب الخصائص الثابتة والحالة العامة وخدمات Singleton التي تتراكم البيانات. قم دائمًا بإعادة تعيين أو مسح الحالة بين الطلبات. استخدم جداول التخزين المؤقت لـ Octane للبيانات المشتركة عبر العمال.

المهام المتزامنة مع Octane

<?php use Laravel\Octane\Facades\Octane; // التنفيذ المتسلسل (بطيء) public function dashboard() { $users = User::count(); $posts = Post::count(); $comments = Comment::count(); return view('dashboard', compact('users', 'posts', 'comments')); } // التنفيذ المتزامن مع Octane (سريع!) public function dashboard() { [$users, $posts, $comments] = Octane::concurrently([ fn () => User::count(), fn () => Post::count(), fn () => Comment::count(), ]); return view('dashboard', compact('users', 'posts', 'comments')); } // استدعاءات API المتزامنة public function aggregateData() { [$github, $twitter, $analytics] = Octane::concurrently([ fn () => Http::get('https://api.github.com/user/repos')->json(), fn () => Http::get('https://api.twitter.com/tweets')->json(), fn () => Http::get('https://analytics.example.com/stats')->json(), ], 5000); // مهلة 5 ثوانٍ return response()->json([ 'github' => $github, 'twitter' => $twitter, 'analytics' => $analytics, ]); }

استراتيجيات التخزين المؤقت في Octane

<?php // استخدم جداول التخزين المؤقت لـ Octane للتخزين المؤقت عالي الأداء use Laravel\Octane\Facades\Octane; // تحديد جدول التخزين المؤقت في config/octane.php 'tables' => [ 'users' => [ 'size' => 10000, 'columns' => [ ['name' => 'id', 'type' => Table::TYPE_INT], ['name' => 'name', 'type' => Table::TYPE_STRING, 'size' => 255], ['name' => 'email', 'type' => Table::TYPE_STRING, 'size' => 255], ['name' => 'created_at', 'type' => Table::TYPE_INT], ], ], ], // الوصول إلى جداول Swoole $table = Octane::table('users'); // تعيين البيانات $table->set('user:1', [ 'id' => 1, 'name' => 'John Doe', 'email' => 'john@example.com', 'created_at' => time(), ]); // الحصول على البيانات $user = $table->get('user:1'); // التحقق من الوجود if ($table->exists('user:1')) { // المستخدم موجود } // الحذف $table->del('user:1'); // استخدام مهام الفترة لتسخين التخزين المؤقت Octane::tick('warm-cache', function () { $popularPosts = Post::popular()->limit(10)->get(); $table = Octane::table('posts'); foreach ($popularPosts as $post) { $table->set('post:' . $post->id, [ 'id' => $post->id, 'title' => $post->title, 'views' => $post->views, ]); } })->seconds(60); // التشغيل كل 60 ثانية

قياس الأداء والمراقبة

<?php // اختبار الحمل الأساسي مع Apache Bench // ab -n 10000 -c 100 http://localhost:8000/ // أكثر تقدمًا مع wrk // wrk -t12 -c400 -d30s http://localhost:8000/ // مراقبة مقاييس Octane public function metrics() { return response()->json([ 'memory_usage' => memory_get_usage(true), 'peak_memory' => memory_get_peak_usage(true), 'uptime' => $this->getUptime(), 'requests_handled' => $this->getRequestCount(), ]); } // Middleware لتوقيت الطلبات class PerformanceMonitor { public function handle($request, Closure $next) { $start = microtime(true); $response = $next($request); $duration = (microtime(true) - $start) * 1000; Log::info('Request completed', [ 'url' => $request->fullUrl(), 'method' => $request->method(), 'duration_ms' => round($duration, 2), 'memory_mb' => round(memory_get_peak_usage(true) / 1024 / 1024, 2), ]); return $response; } }
تحسين الإنتاج: استخدم `--max-requests=500` لإعادة تشغيل العمال تلقائيًا بعد عدد محدد من الطلبات، مما يمنع تسرب الذاكرة. راقب استخدام الذاكرة واضبط عدد العمال بناءً على ذاكرة الوصول العشوائي لخادمك.
تمرين 1: قم بتحويل تطبيق Laravel موجود لاستخدام Octane. قم بقياس فرق الأداء بين PHP-FPM و Octane تحت الحمل. وثق أوقات الاستجابة والطلبات في الثانية واستخدام الذاكرة.
تمرين 2: أنشئ لوحة تحكم تجري أكثر من 10 استدعاءات API لخدمات خارجية. نفذ كلاً من الأساليب المتسلسلة والمتزامنة باستخدام Octane::concurrently(). قس وقارن فرق الأداء.
تمرين 3: ابنِ نظام تحليلات في الوقت الفعلي باستخدام جداول التخزين المؤقت لـ Octane وفترات tick. قم بتخزين وتحديث المقاييس مثل المستخدمين النشطين وعدد الطلبات ومعدلات الأخطاء في جداول Swoole، يمكن الوصول إليها عبر جميع العمال.