Laravel Octane: Tăng tốc Hiệu suất với Swoole

· 5 min read

Vòng đời ứng dụng PHP truyền thống khởi động framework cho mỗi request đến. Điều này có nghĩa là load configuration, service providers, và database connections lặp đi lặp lại.

Laravel Octane thay đổi điều này bằng cách giữ ứng dụng của bạn trong bộ nhớ, cho phép thời gian phản hồi cực nhanh.

Octane hoạt động như thế nào

Octane phục vụ ứng dụng của bạn bằng cách sử dụng các application servers hiệu suất cao như Swoole hoặc RoadRunner. Nó khởi động ứng dụng của bạn một lần, giữ nó trong bộ nhớ và chuyển requests cho nó với tốc độ đáng kinh ngạc.

Cài đặt

Cài đặt qua Composer:

composer require laravel/octane

Cài đặt Swoole (qua PECL) hoặc RoadRunner. Trong hướng dẫn này, chúng ta sẽ giả sử Swoole:

php artisan octane:install --server=swoole

Lệnh này publishes file config/octane.php.

Khởi động Server

php artisan octane:start

App của bạn hiện đang chạy tại http://127.0.0.1:8000. Bạn sẽ cảm nhận được tốc độ ngay lập tức.

Xử lý Stateful Logic

Bởi vì ứng dụng được giữ trong bộ nhớ, bạn phải cẩn thận với state (trạng thái).

Dependency Injection (Singletons)

Trong vòng đời request tiêu chuẩn, một singleton bị hủy sau request. Trong Octane, một singleton tồn tại qua các requests.

Vấn đề:

// AppServiceProvider
$this->app->singleton(Service::class, function () {
    return new Service(request()); // Tạo service với request ĐẦU TIÊN
});

Các requests tiếp theo sẽ sử dụng lại instance service này với dữ liệu request CŨ.

Giải pháp:

Inject container, hoặc truyền request vào method call, không phải constructor.

$this->app->bind(Service::class, function ($app) {
    return new Service($app['request']);
});

Static Properties

Static properties tồn tại giữa các requests.

Vấn đề:

class UserContext {
    public static $userId;
}

// Request 1 đặt ID 5
UserContext::$userId = 5;

// Request 2 (user khác) đọc ID 5!

Giải pháp:

Tránh static properties cho request-scope state. Hoặc, reset chúng bằng cách sử dụng các listeners của Octane.

Quản lý Memory Leaks

Octane tự động xử lý một số cleanup, nhưng bạn có thể cấu hình để restart sau một số lượng requests hoặc mức sử dụng bộ nhớ nhất định.

php artisan octane:start --max-requests=1000

Điều này ngăn chặn memory leaks chậm tiêu thụ hết tài nguyên server theo thời gian.

Concurrent Tasks với Swoole

Một trong những tính năng hay nhất của Octane (với Swoole) là thực thi đồng thời (concurrent execution).

use Laravel\Octane\Facades\Octane;

[$users, $posts] = Octane::concurrently([
    fn () => User::all(),
    fn () => Post::all(),
]);

Các database queries này chạy song song, giảm đáng kể tổng thời gian phản hồi.

Tables (Chỉ Swoole)

Octane tables cho phép chia sẻ dữ liệu hiệu suất cao giữa các concurrent workers.

use Laravel\Octane\Facades\Octane;
use Swoole\Table;

// Configuration
Octane::table('cache', [
    'value' => [
        'type' => Table::TYPE_STRING,
        'size' => 1000,
    ],
]);

// Usage
Octane::table('cache')->set('key', ['value' => 'stored_data']);

Cache Driver

Octane cung cấp một in-memory cache driver được hỗ trợ bởi Swoole tables. Nó cung cấp tốc độ đọc/ghi ở mức micro giây.

Cache::store('octane')->put('framework', 'Laravel', 30);

Route Caching

Vì app được boot một lần, route caching ít quan trọng hơn cho boot time nhưng vẫn quan trọng cho tốc độ dispatch.

php artisan route:cache

Production Deployment

Cho production, bạn thường chạy Octane phía sau một reverse proxy như Nginx.

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen 80;
    server_name example.com;
    root /path/to/public;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}

Sử dụng Supervisor để giữ process Octane luôn chạy.

[program:octane]
command=php /path/to/artisan octane:start --server=swoole --max-requests=1000
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/path/to/octane.log

Best Practices checklist

  1. Tránh Global State: Cẩn thận với static properties.
  2. Request Injection: Không inject Request vào Singleton constructors.
  3. Memory Management: Theo dõi memory usage và đặt max-requests.
  4. Listeners: Sử dụng Octane::tick() hoặc listeners để reset state nếu cần thiết.
  5. Concurrency: Sử dụng Octane::concurrently cho các operations nặng độc lập.

Tóm tắt

Laravel Octane cho phép PHP cạnh tranh với Node.js và Go về raw throughput. Mặc dù nó giới thiệu một số phức tạp liên quan đến quản lý state, nhưng lợi ích về hiệu suất cho các ứng dụng high-traffic là không thể phủ nhận.

Bình luận