# Laravel Octane w 2026: Swoole, RoadRunner i Optymalizacja Wydajności > Kompleksowy przewodnik po Laravel Octane w 2026 roku. Porównanie Swoole i RoadRunner, techniki optymalizacji wydajności, konfiguracja produkcyjna oraz pytania rekrutacyjne. - Published: 2026-09-11 - Updated: 2026-09-11 - Author: Anthony Fillion-Maillet - Tags: laravel, octane, swoole, roadrunner, php, performance - Reading time: 12 min --- Laravel Octane zrewolucjonizował podejście do wydajności aplikacji PHP, oferując wsparcie dla serwerów aplikacyjnych wysokiej wydajności, takich jak Swoole i RoadRunner. W 2026 roku Octane stał się standardowym rozwiązaniem dla aplikacji Laravel wymagających obsługi tysięcy żądań na sekundę przy minimalnym zużyciu zasobów. Ten artykuł analizuje architekturę Octane, porównuje dostępne silniki, omawia techniki optymalizacji oraz prezentuje typowe pytania zadawane podczas rozmów rekrutacyjnych. > **Czym jest Laravel Octane?** > > Laravel Octane to oficjalny pakiet pierwszej strony, który superładuje aplikacje Laravel poprzez uruchomienie ich na wysokowydajnych serwerach aplikacyjnych. Zamiast tradycyjnego modelu PHP-FPM, gdzie każde żądanie uruchamia nowy proces PHP, Octane utrzymuje aplikację w pamięci i przetwarza żądania w ramach trwałych procesów roboczych. Efektem jest drastyczna redukcja opóźnień i znaczny wzrost przepustowości. ## Architektura Laravel Octane: Jak to działa Tradycyjny stos PHP z Nginx i PHP-FPM obsługuje każde żądanie poprzez uruchomienie nowego procesu PHP, załadowanie frameworka, przetworzenie żądania i zakończenie procesu. Ten cykl życia wprowadza znaczny narzut, szczególnie przy złożonych aplikacjach Laravel z wieloma usługodawcami. Octane zmienia ten model fundamentalnie. Aplikacja jest uruchamiana raz, a następnie pozostaje w pamięci, obsługując kolejne żądania bez ponownej inicjalizacji. Framework Laravel, kontener usług, trasy i konfiguracja są ładowane tylko podczas startu serwera. ```php // Tradycyjny cykl PHP-FPM (uproszczony) // Żądanie 1: Załaduj PHP → Załaduj Composer → Uruchom Laravel → Obsłuż → Zakończ // Żądanie 2: Załaduj PHP → Załaduj Composer → Uruchom Laravel → Obsłuż → Zakończ // Żądanie 3: Załaduj PHP → Załaduj Composer → Uruchom Laravel → Obsłuż → Zakończ // Model Octane // Start: Załaduj PHP → Załaduj Composer → Uruchom Laravel // Żądanie 1: Obsłuż // Żądanie 2: Obsłuż // Żądanie 3: Obsłuż ``` Ta zmiana architektury wprowadza pewne wyzwania. Stan aplikacji może wyciekać między żądaniami, jeśli programiści nie zarządzają właściwościami statycznymi i singletonami ostrożnie. Octane dostarcza mechanizmy resetowania stanu, ale deweloperzy muszą rozumieć te ograniczenia. ## Swoole vs RoadRunner: Porównanie silników Laravel Octane obsługuje dwa główne silniki: Swoole i RoadRunner. Każdy ma swoje zalety i przypadki użycia. ### Swoole Swoole jest rozszerzeniem PHP napisanym w C, dostarczającym asynchroniczne I/O i współbieżność opartą na korutynach. Oferuje najwyższą wydajność surową, ale wymaga instalacji rozszerzenia PHP. ```bash # Instalacja Swoole na Ubuntu/Debian pecl install swoole # Dodaj do php.ini extension=swoole.so ``` ```php // config/octane.php return [ 'server' => 'swoole', 'swoole' => [ 'options' => [ 'worker_num' => env('OCTANE_WORKERS', 8), 'task_worker_num' => env('OCTANE_TASK_WORKERS', 4), 'max_request' => env('OCTANE_MAX_REQUESTS', 10000), 'enable_static_handler' => true, 'document_root' => public_path(), ], ], ]; ``` Swoole oferuje unikalne funkcje niedostępne w RoadRunner: - **Tabele Swoole**: Współdzielona pamięć między procesami roboczymi - **Zadania współbieżne**: Natywne wykonywanie asynchroniczne - **Serwer WebSocket**: Wbudowana obsługa połączeń WebSocket - **Korutyny**: Współbieżność bez callbacków ### RoadRunner RoadRunner jest serwerem aplikacyjnym napisanym w Go, komunikującym się z procesami roboczymi PHP przez standardowe wejście/wyjście. Jest łatwiejszy w instalacji, ponieważ nie wymaga rozszerzenia PHP. ```bash # Instalacja RoadRunner composer require spiral/roadrunner-cli ./vendor/bin/rr get-binary ``` ```yaml # .rr.yaml version: '3' server: command: "php artisan octane:start --server=roadrunner --host=0.0.0.0 --port=8000" relay: pipes http: address: 0.0.0.0:8000 pool: num_workers: 8 max_jobs: 10000 supervisor: max_worker_memory: 128 ``` | Cecha | Swoole | RoadRunner | |-------|--------|------------| | Wydajność surowa | Wyższa | Nieco niższa | | Instalacja | Rozszerzenie PECL | Binarka Go | | Obsługa Docker | Złożona | Prosta | | Tabele współdzielone | Natywne | Brak | | WebSockets | Natywne | Przez centrifugo | | Stabilność | Dobra | Bardzo dobra | | Ekosystem wtyczek | Ograniczony | Rozbudowany | ## Instalacja i konfiguracja Octane Konfiguracja Laravel Octane wymaga kilku kroków, niezależnie od wybranego silnika. ```bash # Instalacja pakietu Octane composer require laravel/octane # Publikacja pliku konfiguracyjnego php artisan octane:install # Wybierz silnik podczas instalacji # [0] roadrunner # [1] swoole ``` Po instalacji, uruchomienie serwera deweloperskiego: ```bash # Uruchomienie z hot-reload php artisan octane:start --watch # Uruchomienie produkcyjne php artisan octane:start --host=0.0.0.0 --port=8000 --workers=8 ``` Konfiguracją produkcyjną zarządza się przez zmienne środowiskowe: ```env OCTANE_SERVER=swoole OCTANE_WORKERS=8 OCTANE_TASK_WORKERS=4 OCTANE_MAX_REQUESTS=10000 OCTANE_HTTPS=false ``` ## Zarządzanie stanem i wycieki pamięci Najpoważniejszym wyzwaniem przy pracy z Octane jest zarządzanie stanem aplikacji. Ponieważ aplikacja pozostaje w pamięci, zmienne statyczne i singletony zachowują swoje wartości między żądaniami. ```php // PROBLEM: Wyciek stanu class CartService { private static array $items = []; public function addItem(string $item): void { self::$items[] = $item; // Kumuluje się między żądaniami! } } // ROZWIĄZANIE 1: Użyj właściwości instancji class CartService { private array $items = []; public function addItem(string $item): void { $this->items[] = $item; // Reset z każdą instancją } } // ROZWIĄZANIE 2: Zarejestruj jako flushable Octane::flush(CartService::class); ``` Octane automatycznie resetuje wiele komponentów Laravel, ale niestandardowe usługi wymagają ręcznej konfiguracji: ```php // app/Providers/AppServiceProvider.php use Laravel\Octane\Facades\Octane; public function boot(): void { Octane::flush(function () { // Reset niestandardowego stanu MyStatefulService::reset(); }); } ``` Listenery Octane pozwalają wykonywać kod w określonych punktach cyklu życia: ```php // app/Providers/OctaneServiceProvider.php protected $listen = [ RequestReceived::class => [ EnsureAuthenticationDataIsCleared::class, ], RequestTerminated::class => [ FlushTemporaryData::class, ], TaskReceived::class => [ SetupTaskEnvironment::class, ], WorkerStarting::class => [ WarmUpCaches::class, ], ]; ``` ## Tabele Swoole: Współdzielona pamięć Tabele Swoole zapewniają ultraszybki dostęp do współdzielonej pamięci między procesami roboczymi. Są idealne dla danych odczytywanych często, ale rzadko modyfikowanych. ```php // config/octane.php 'tables' => [ 'rates' => [ 'columns' => [ ['name' => 'currency', 'type' => Table::TYPE_STRING, 'size' => 3], ['name' => 'rate', 'type' => Table::TYPE_FLOAT], ['name' => 'updated_at', 'type' => Table::TYPE_INT], ], 'rows' => 100, ], ], ``` ```php // Zapis do tabeli use Laravel\Octane\Facades\Octane; Octane::table('rates')->set('USD', [ 'currency' => 'USD', 'rate' => 1.0, 'updated_at' => time(), ]); Octane::table('rates')->set('EUR', [ 'currency' => 'EUR', 'rate' => 0.85, 'updated_at' => time(), ]); // Odczyt z tabeli $usdRate = Octane::table('rates')->get('USD'); $allRates = Octane::table('rates')->toArray(); ``` Tabele są znacznie szybsze niż Redis dla prostych operacji klucz-wartość, ponieważ dane znajdują się w pamięci procesu. ## Zadania współbieżne Octane umożliwia wykonywanie wielu operacji równolegle za pomocą zadań współbieżnych: ```php use Laravel\Octane\Facades\Octane; // Wykonanie wielu zadań równolegle [$users, $orders, $stats] = Octane::concurrently([ fn () => User::where('active', true)->get(), fn () => Order::where('status', 'pending')->get(), fn () => DB::table('metrics')->selectRaw('SUM(value) as total')->first(), ]); ``` Zadania współbieżne są szczególnie przydatne dla niezależnych zapytań do bazy danych lub wywołań zewnętrznych API: ```php // Agregacja danych z wielu źródeł public function getDashboardData(int $userId): array { [$profile, $notifications, $recommendations] = Octane::concurrently([ fn () => $this->userService->getProfile($userId), fn () => $this->notificationService->getUnread($userId), fn () => $this->mlService->getRecommendations($userId), ], 5000); // Timeout 5 sekund return compact('profile', 'notifications', 'recommendations'); } ``` ## Optymalizacja wydajności: Najlepsze praktyki Maksymalizacja wydajności z Octane wymaga optymalizacji na wielu poziomach. ### Rozgrzewanie cache Ładowanie często używanych danych podczas startu workerów eliminuje opóźnienia pierwszego żądania: ```php // app/Providers/OctaneServiceProvider.php use Laravel\Octane\Events\WorkerStarting; protected $listen = [ WorkerStarting::class => [ WarmUpApplication::class, ], ]; // app/Listeners/WarmUpApplication.php class WarmUpApplication { public function handle(WorkerStarting $event): void { // Załaduj konfigurację do pamięci config()->all(); // Rozgrzej cache routingu app('router')->getRoutes()->compile(); // Załaduj relacje Eloquent User::query()->with(['profile', 'settings'])->first(); // Zainicjalizuj połączenia cache Cache::get('warmup'); } } ``` ### Optymalizacja OPcache OPcache jest krytyczny dla wydajności Octane. Zalecana konfiguracja: ```ini ; php.ini opcache.enable=1 opcache.enable_cli=1 opcache.memory_consumption=256 opcache.interned_strings_buffer=32 opcache.max_accelerated_files=30000 opcache.validate_timestamps=0 opcache.save_comments=1 opcache.jit_buffer_size=256M opcache.jit=1255 ``` ### Konfiguracja liczby workerów Optymalną liczbę workerów określa wzór: ```php // Dla zadań CPU-bound $workers = CPU_CORES; // Dla zadań I/O-bound (większość aplikacji webowych) $workers = CPU_CORES * 2; // Sprawdzenie wykorzystania php artisan octane:status ``` ### Monitorowanie wycieków pamięci ```php // Automatyczny restart workerów przy przekroczeniu limitu pamięci 'max_requests' => 10000, // Restart po 10k żądań // Monitoring pamięci Octane::tick('memory-monitor', function () { $usage = memory_get_usage(true) / 1024 / 1024; if ($usage > 100) { Log::warning("High memory usage: {$usage}MB"); } })->seconds(30); ``` ## Konfiguracja produkcyjna z Supervisor W środowisku produkcyjnym Octane wymaga nadzorcy procesów: ```ini ; /etc/supervisor/conf.d/octane.conf [program:octane] process_name=%(program_name)s_%(process_num)02d command=php /var/www/html/artisan octane:start --server=swoole --host=0.0.0.0 --port=800%(process_num)d autostart=true autorestart=true stopasgroup=true killasgroup=true user=www-data numprocs=1 redirect_stderr=true stdout_logfile=/var/log/octane.log stopwaitsecs=60 ``` Konfiguracja Nginx jako reverse proxy: ```nginx upstream octane { server 127.0.0.1:8000 weight=5; server 127.0.0.1:8001 weight=5; keepalive 32; } server { listen 80; server_name example.com; location / { proxy_pass http://octane; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Connection ""; proxy_buffering off; } } ``` ## Pytania rekrutacyjne: Laravel Octane **P1: Czym różni się model wykonania Octane od tradycyjnego PHP-FPM?** W PHP-FPM każde żądanie uruchamia nowy proces PHP, który ładuje autoloader Composera, inicjalizuje framework Laravel, przetwarza żądanie i kończy działanie. Octane utrzymuje aplikację w pamięci - framework jest ładowany tylko podczas startu serwera, a kolejne żądania są obsługiwane przez procesy robocze bez reinicjalizacji. Eliminuje to narzut bootstrappingu frameworka, co daje 2-3x wzrost wydajności dla typowych aplikacji Laravel. **P2: Jakie są główne różnice między Swoole a RoadRunner?** Swoole to rozszerzenie PHP napisane w C, oferujące natywną asynchroniczność, korutyny i funkcje takie jak tabele współdzielone. RoadRunner to serwer Go komunikujący się z PHP przez standardowe I/O. Swoole oferuje wyższą wydajność surową i więcej funkcji, ale jest trudniejszy w instalacji (wymaga kompilacji rozszerzenia). RoadRunner jest prostszy w konfiguracji, lepiej integruje się z Dockerem i ma stabilniejszy ekosystem wtyczek. **P3: Jak zapobiegać wyciekom pamięci w aplikacji Octane?** Trzy główne strategie: unikanie właściwości statycznych gromadzących dane, rejestrowanie usług stanowych za pomocą `Octane::flush()` do automatycznego resetowania między żądaniami, oraz konfiguracja `max_requests` do okresowego restartowania workerów. Dodatkowo należy unikać singletonów przechowujących dane specyficzne dla żądania i używać scope bindings w kontenerze usług. **P4: Kiedy używać tabel Swoole zamiast Redis?** Tabele Swoole są idealne dla danych odczytywanych często, ale rzadko modyfikowanych - takich jak kursy walut, konfiguracja lub cache sesji. Są szybsze niż Redis, ponieważ dane znajdują się w pamięci procesu bez overhead sieci. Redis pozostaje lepszym wyborem dla danych współdzielonych między wieloma serwerami, struktur danych złożonych (sorted sets, streams) lub gdy wymagana jest trwałość danych. **P5: Jak skonfigurować Octane do obsługi WebSocket?** Z Swoole, Octane oferuje natywną obsługę WebSocket. Wymaga to konfiguracji listenerów dla zdarzeń `onOpen`, `onMessage` i `onClose`. Alternatywnie można użyć Laravel Reverb lub Pusher. Z RoadRunner, WebSocket wymaga dodatkowego serwera centrifugo lub podobnego rozwiązania, ponieważ RoadRunner nie obsługuje WebSocket natywnie. ## Benchmarki wydajności Porównanie wydajności typowej aplikacji Laravel: | Konfiguracja | Żądania/s | Latencja p99 | Pamięć/worker | |--------------|-----------|--------------|---------------| | PHP-FPM | 850 | 45ms | 35MB | | Octane + RoadRunner | 2,400 | 12ms | 45MB | | Octane + Swoole | 3,100 | 8ms | 55MB | Wyniki mogą się różnić w zależności od specyfiki aplikacji. Aplikacje z dużą liczbą operacji I/O (bazy danych, API) odnoszą większe korzyści niż aplikacje CPU-bound. ## Podsumowanie Laravel Octane w 2026 roku stanowi dojrzałe rozwiązanie do uruchamiania wysokowydajnych aplikacji PHP. Wybór między Swoole a RoadRunner zależy od wymagań projektu - Swoole oferuje maksymalną wydajność i funkcje takie jak tabele współdzielone, podczas gdy RoadRunner zapewnia prostszą konfigurację i lepszą kompatybilność z kontenerami. Kluczowe wnioski: - Octane eliminuje narzut bootstrappingu frameworka, utrzymując aplikację w pamięci - Zarządzanie stanem jest krytyczne - unikaj właściwości statycznych i rejestruj usługi do resetowania - Tabele Swoole oferują ultraszybki dostęp do danych współdzielonych między workerami - Zadania współbieżne przyspieszają operacje I/O-bound poprzez równoległe wykonanie - Konfiguracja produkcyjna wymaga Supervisora, Nginx jako reverse proxy i monitoringu pamięci Znajomość Laravel Octane staje się coraz ważniejsza dla programistów PHP pracujących nad aplikacjami o wysokich wymaganiach wydajnościowych. Opanowanie zarządzania stanem, konfiguracji produkcyjnej i optymalizacji wydajności pozwala budować aplikacje obsługujące tysiące żądań na sekundę. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/pl/blog/laravel/laravel-octane-swoole-roadrunner-performance-optimization