LaravelSeniorSystem design

Что такое Laravel Octane и каковы его преимущества для производительности?

Laravel Octane запускает приложение в постоянном процессе (Swoole или RoadRunner), устраняя накладные расходы на bootstrap при каждом запросе. Даёт 5–10x прирост RPS, но требует осторожности со статическим состоянием.

Что такое Laravel Octane

Laravel Octane — официальный пакет (laravel/octane), который загружает фреймворк один раз при старте сервера и обрабатывает последующие запросы в уже прогретом состоянии. Поддерживает два сервера: Swoole (C-расширение, корутины) и RoadRunner (Go-бинарник). На PHP-FPM каждый запрос запускает bootstrap заново — Octane этого не делает.

Установка и запуск

composer require laravel/octane
php artisan octane:install   # выбрать swoole или roadrunner

# RoadRunner: скачивает бинарник rr автоматически
./vendor/bin/rr get-binary

# Запуск
php artisan octane:start --server=swoole --host=0.0.0.0 --port=8000 --workers=4
php artisan octane:start --server=roadrunner --workers=4

# Горячая перезагрузка при изменении файлов
php artisan octane:start --watch

Как это работает под капотом

  1. Octane запускает N worker-процессов.
  2. Каждый воркер загружает приложение один раз: autoload, Service Providers, конфигурация — всё это выполняется при старте.
  3. Входящий HTTP-запрос клонирует application-контейнер и передаёт его в pipeline.
  4. После ответа контейнер сбрасывается до клона базового состояния (не перезагружается с нуля).

Производительность

Бенчмарк на стандартном Laravel hello-world запросе:

  • PHP-FPM: ~500–800 RPS
  • Octane + RoadRunner: ~3000–5000 RPS
  • Octane + Swoole: ~5000–10000 RPS

Реальный прирост зависит от доли bootstrap в общем времени запроса — чем тяжелее приложение (больше Providers), тем заметнее эффект.

Конфигурация сброса состояния

<?php
// config/octane.php
return [
    'server' => env('OCTANE_SERVER', 'swoole'),
    'workers' => env('OCTANE_WORKERS', 4),
    'task_workers' => env('OCTANE_TASK_WORKERS', 2),

    // Сервисы, которые нужно пересоздавать на каждом запросе
    'flush' => [
        // По умолчанию Octane сбрасывает Auth, Session, Cookie, DB
    ],

    // Bindings, которые не должны быть singleton в worker
    'warm' => [
        ...Octane::defaultServicesToWarm(),
    ],
];

Устранение утечек состояния

<?php

use Laravel\Octane\Facades\Octane;

// Регистрация колбэков на события жизненного цикла
Octane::tick('heartbeat', function () {
    // Выполняется каждые N секунд в Swoole
})->seconds(15);

// В ServiceProvider: не кешируйте request-специфичные данные в singleton
public function register(): void
{
    // Плохо: request кешируется между запросами
    $this->app->singleton('current_user', fn () => auth()->user());

    // Хорошо: scoped — живёт только в рамках одного запроса
    $this->app->scoped('current_user', fn () => auth()->user());
}

Задачи (Concurrent Tasks) в Swoole

<?php

use Laravel\Octane\Facades\Octane;

// Параллельное выполнение нескольких замыканий
[$users, $orders] = Octane::concurrently([
    fn () => User::count(),
    fn () => Order::whereStatus('pending')->count(),
]);

Подводные камни

  • Статические свойства не сбрасываютсяstatic $instance в классах живёт весь lifetime воркера. Используйте IoC-контейнер вместо статиков.
  • Singleton с request-данными — если зарегистрировать auth()->user() как singleton, первый пользователь «застрянет» во всех последующих запросах воркера. Используйте scoped().
  • Пакеты, не совместимые с Octane — ряд пакетов хранит состояние в статических свойствах. Проверяйте совместимость через php artisan octane:check.
  • Swoole требует PHP-расширения — не работает в стандартном PHP-FPM окружении. В Docker нужен отдельный образ с ext-swoole.
  • Memory leaks в долгоживущих воркерах — без правильного сброса состояния потребление памяти растёт. Настройте --max-requests=500 для автоперезапуска воркера после N запросов.
  • Graceful reload при деплоеphp artisan octane:reload плавно перезапускает воркеры без downtime; простой kill процесса обрывает активные соединения.
  • Swoole и pcntl_fork — нельзя использовать pcntl_fork() внутри Swoole-корутины; это приведёт к непредсказуемому поведению.

Common mistakes

  • Сводить octane к названию метода без lifecycle и failure path.
  • Игнорировать модель runtime: Laravel 13 поверх PHP: request проходит через HTTP kernel, middleware, routing, controller/action и response pipeline.
  • Не отделять validation, authorization, transaction boundary и business logic.
  • Не обсуждать idempotency, retries, shutdown и observability.

What the interviewer is testing

  • Объясняет octane через конкретную точку lifecycle в Laravel.
  • Приводит корректный минимальный пример без вымышленных методов или callbacks.
  • Называет edge cases: пустые значения, ошибки, транзакции, безопасность или concurrency.
  • Связывает решение с метриками, backpressure, retry policy и graceful shutdown.

Sources

Related topics