Laravel Octane trong 2026: Swoole, RoadRunner và Tối ưu Hiệu năng
Làm chủ Laravel Octane 2.19 với FrankenPHP, Swoole và RoadRunner. Tìm hiểu cách chọn server, phòng tránh memory leak, concurrent tasks và các pattern deployment production cho ứng dụng PHP hiệu năng cao.

Laravel Octane biến đổi hiệu năng ứng dụng PHP bằng cách giữ framework đã bootstrap trong bộ nhớ giữa các request. Phiên bản 2.19 (tháng 8 năm 2026) hỗ trợ ba server sẵn sàng cho production: FrankenPHP, Swoole và RoadRunner. Mỗi server phục vụ các yêu cầu vận hành khác nhau, và việc chọn sai sẽ ảnh hưởng đến hiệu năng hoặc độ ổn định.
FrankenPHP: cài đặt đơn giản nhất, HTTP/3 native, single binary. RoadRunner: binary Go đã được thử nghiệm thực tế, không yêu cầu extension PHP. Swoole: throughput tối đa với coroutine concurrency, cần quản lý PECL extension.
Cách Octane Loại Bỏ Chi Phí Bootstrap
PHP-FPM truyền thống khởi tạo một process mới cho mỗi request. Laravel boot service container, load cấu hình, đăng ký provider và resolve middleware trên mỗi lần gọi HTTP. Octane đảo ngược mô hình này: ứng dụng boot một lần cho mỗi worker, sau đó cùng một instance xử lý hàng nghìn request liên tiếp.
Lợi ích hiệu năng đến từ việc loại bỏ công việc lặp lại. Một ứng dụng Laravel 12 điển hình mất 15 đến 40ms để bootstrap trước khi thực thi logic nghiệp vụ. Với Octane, chi phí đó giảm về không sau request đầu tiên. Các benchmark trên phần cứng giống nhau cho thấy cải thiện throughput 2x đến 4x cho các endpoint API, với khoảng cách tăng lên khi độ phức tạp ứng dụng tăng.
return [
'server' => env('OCTANE_SERVER', 'frankenphp'),
// Workers handle HTTP requests
'workers' => env('OCTANE_WORKERS', 8),
// Gracefully restart workers after N requests to prevent memory bloat
'max_requests' => env('OCTANE_MAX_REQUESTS', 500),
// Task workers for Swoole concurrent operations
'task_workers' => env('OCTANE_TASK_WORKERS', 6),
// Maximum execution time per request in seconds
'max_execution_time' => 30,
];Cấu hình max_requests hoạt động như một van an toàn. Ngay cả code được viết tốt cũng có thể tích lũy bộ nhớ qua hàng trăm request. Đặt giá trị này thành 500 buộc worker phải restart trước khi áp lực bộ nhớ trở nên nghiêm trọng.
FrankenPHP: Mặc Định 2026 Cho Dự Án Mới
FrankenPHP được phân phối dưới dạng single binary được xây dựng trên Caddy và PHP. Server này tự động xử lý chứng chỉ HTTPS thông qua Let's Encrypt, hỗ trợ HTTP/3 ngay lập tức và không yêu cầu cài đặt extension PHP. Installer của Laravel và các ví dụ production hiện mặc định sử dụng FrankenPHP.
# Install Octane with FrankenPHP
composer require laravel/octane
php artisan octane:install --server=frankenphp
# Start the server
php artisan octane:start --server=frankenphp --host=0.0.0.0 --port=8000Đối với deployment được container hóa, FrankenPHP cung cấp các image Docker chính thức:
# Dockerfile
FROM dunglas/frankenphp
RUN install-php-extensions \
pcntl \
pdo_pgsql \
redis
COPY . /app
ENTRYPOINT ["php", "artisan", "octane:frankenphp"]Cấu hình Docker Compose cho development kích hoạt HTTPS và HTTP/3:
# compose.yaml
services:
frankenphp:
build:
context: .
entrypoint: php artisan octane:frankenphp --workers=1 --max-requests=1
ports:
- "443:443"
- "443:443/udp"
volumes:
- .:/appFrankenPHP xử lý việc restart worker một cách graceful và tích hợp trực tiếp với hệ thống middleware của Caddy cho các tình huống routing nâng cao.
RoadRunner: Độ Ổn Định Dựa Trên Go Không Phụ Thuộc Extension
RoadRunner được compile thành binary Go quản lý các process worker PHP. Server này giao tiếp với PHP qua giao thức binary, giữ việc quản lý worker và xử lý HTTP trong Go trong khi thực thi code ứng dụng trong PHP. Kiến trúc này cung cấp process isolation: một worker PHP bị crash không ảnh hưởng đến Go parent hoặc các worker sibling.
# Install Octane with RoadRunner
composer require laravel/octane spiral/roadrunner-cli spiral/roadrunner-http
php artisan octane:install --server=roadrunner
# Download the RoadRunner binary
./vendor/bin/rr get-binary
# Start the server
php artisan octane:start --server=roadrunner --host=0.0.0.0 --port=8000Cấu hình RoadRunner nằm trong .rr.yaml tại thư mục gốc của dự án:
# .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
middleware: ["headers", "gzip"]
pool:
num_workers: 8
max_jobs: 500
supervisor:
max_worker_memory: 128Cấu hình max_worker_memory (tính bằng MB) terminate các worker vượt quá giới hạn bộ nhớ, cung cấp lớp bảo vệ bổ sung ngoài max_requests. Đối với các team có CI pipeline đã thiết lập và cơ sở hạ tầng PHP-FPM sẵn có, RoadRunner cung cấp lộ trình migration mượt mà nhất.
Swoole: Throughput Tối Đa Với Coroutine Concurrency
Swoole hoạt động như một PHP extension thay thế vòng đời request tiêu chuẩn bằng runtime event-driven có khả năng coroutine. Swoole cung cấp các tính năng không có sẵn ở các server khác: thực thi task đồng thời, ticks và intervals, cùng với in-memory cache có throughput 2 triệu operations mỗi giây.
# Install Swoole via PECL
pecl install swoole
# Add to php.ini
echo "extension=swoole.so" >> $(php --ini | grep "Loaded Configuration" | cut -d: -f2 | xargs)/php.ini
# Install Octane with Swoole
composer require laravel/octane
php artisan octane:install --server=swoole
# Start with task workers for concurrent operations
php artisan octane:start --server=swoole --workers=8 --task-workers=6Thực thi task đồng thời của Swoole xử lý các I/O operation song song trong một request:
use App\Models\User;
use App\Models\Order;
use App\Models\Analytics;
use Laravel\Octane\Facades\Octane;
class DashboardController extends Controller
{
public function index()
{
// Execute three queries concurrently instead of sequentially
[$users, $orders, $analytics] = Octane::concurrently([
fn () => User::active()->count(),
fn () => Order::today()->sum('total'),
fn () => Analytics::hourly()->get(),
]);
return view('dashboard', compact('users', 'orders', 'analytics'));
}
}Không có Octane::concurrently(), ba query này thực thi tuần tự: 50ms + 30ms + 40ms = tổng 120ms. Với thực thi đồng thời, tổng thời gian bằng query chậm nhất: 50ms. Flag --task-workers kiểm soát số lượng concurrent operation có thể chạy đồng thời trên tất cả các request worker.
Concurrent tasks, ticks, intervals, Octane cache và Swoole tables yêu cầu extension Swoole. FrankenPHP và RoadRunner không hỗ trợ các tính năng này. Đánh giá xem ứng dụng có cần các tính năng này không trước khi chọn độ phức tạp vận hành của Swoole.
Phòng Tránh Memory Leak: Viết Code Stateless
Hiệu năng của Octane đến từ persistent state, điều này tạo ra thách thức chính: code hoạt động tốt dưới PHP-FPM có thể gây memory leak nghiêm trọng dưới Octane. Instance ứng dụng tồn tại giữa các request, vì vậy static property, singleton và global state sẽ tích lũy.
Ba pattern gây ra phần lớn memory leak:
Mảng static tăng không giới hạn:
// WRONG: Memory leak - array grows with every request
class MetricsCollector
{
public static array $data = [];
public static function record(string $metric): void
{
self::$data[] = $metric; // Never cleared between requests
}
}
// CORRECT: Use request-scoped storage or external systems
class MetricsCollector
{
public function record(string $metric): void
{
Redis::lpush('metrics', $metric); // External storage
}
}Singleton giữ dữ liệu cụ thể theo request:
// WRONG: First request's user leaks into subsequent requests
$this->app->singleton(UserContext::class, function ($app) {
return new UserContext($app['request']->user());
});
// CORRECT: Use closures for deferred resolution
$this->app->singleton(UserContext::class, function ($app) {
return new UserContext(fn () => $app['request']->user());
});Inject container và request trong constructor:
// WRONG: Captures stale container/request
class PaymentService
{
public function __construct(
private Application $app,
private Request $request
) {}
}
// CORRECT: Inject via method parameters or use helpers
class PaymentService
{
public function processPayment(Request $request): void
{
$user = $request->user();
$config = config('services.stripe.key'); // Global helper, always fresh
}
}Các global helper app(), request() và config() luôn trả về giá trị hiện tại. Sử dụng chúng thay vì constructor injection tránh được phần lớn các leak liên quan đến singleton.
Pattern Deployment Production
Các server Octane cần process supervision để restart khi crash. Supervisor xử lý việc này một cách đáng tin cậy:
; /etc/supervisor/conf.d/octane.conf
[program:octane]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/app/artisan octane:start --server=frankenphp --host=127.0.0.1 --port=8000
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/var/www/app/storage/logs/octane.log
stopwaitsecs=3600Đối với deployment, các worker Octane phải reload để nhận code mới. Lệnh octane:reload xử lý việc này một cách graceful, chờ các request đang xử lý hoàn thành trước khi tái chế worker:
# In deployment script (after git pull, composer install, etc.)
php artisan octane:reloadNginx đứng trước Octane để phục vụ static assets và terminate SSL:
# /etc/nginx/sites-available/app.conf
upstream octane {
server 127.0.0.1:8000;
keepalive 32;
}
server {
listen 443 ssl http2;
server_name example.com;
root /var/www/app/public;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
try_files $uri $uri/ @octane;
}
location @octane {
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";
proxy_pass http://octane;
}
}Directive keepalive duy trì các kết nối persistent giữa Nginx và Octane, giảm chi phí TCP handshake cho các request được proxy.
Sẵn sàng chinh phục phỏng vấn Laravel?
Luyện tập với mô phỏng tương tác, flashcards và bài kiểm tra kỹ thuật.
Cây Quyết Định Chọn Server
Việc chọn giữa FrankenPHP, RoadRunner và Swoole phụ thuộc vào các ràng buộc vận hành và yêu cầu ứng dụng:
| Yêu Cầu | Server Được Khuyến Nghị |
|---|---|
| Cài đặt đơn giản nhất, deployment container hóa | FrankenPHP |
| Hỗ trợ HTTP/3 ngay lập tức | FrankenPHP |
| Không phụ thuộc PHP extension | FrankenPHP hoặc RoadRunner |
| Process isolation tối đa | RoadRunner |
| Cơ sở hạ tầng PHP-FPM đã có | RoadRunner |
| I/O đồng thời trong request | Swoole |
| In-memory caching (2M ops/giây) | Swoole |
| Ticks, intervals, background tasks | Swoole |
| Swoole tables cho shared state | Swoole |
Đối với các team bắt đầu dự án mới trong năm 2026, FrankenPHP cung cấp sự cân bằng tốt nhất giữa đơn giản và khả năng. Migration ứng dụng hiện có hoạt động tốt nhất với RoadRunner do process isolation và mô hình deployment quen thuộc. Swoole phù hợp với các API throughput cao cần tận dụng coroutine concurrency và yêu cầu các tính năng đặc thù của Swoole.
Câu Hỏi Phỏng Vấn Về Laravel Octane
Các buổi phỏng vấn kỹ thuật ngày càng đề cập đến Octane khi các ứng dụng Laravel lưu lượng cao áp dụng nó. Các câu hỏi phổ biến và điều người phỏng vấn tìm kiếm:
"Octane đạt được cải thiện hiệu năng như thế nào?"
Câu trả lời mong đợi: Octane boot Laravel một lần cho mỗi worker và tái sử dụng instance đó giữa các request, loại bỏ chi phí bootstrap 15-40ms trên mỗi request. Ứng viên nên đề cập rằng các method register và boot của service provider chạy một lần cho mỗi worker, không phải mỗi request.
"Điều gì gây ra memory leak trong ứng dụng Octane?"
Câu trả lời mạnh mẽ xác định ba nguồn: mảng static tích lũy dữ liệu, singleton capture state cụ thể theo request, và constructor injection các object container hoặc request. Ứng viên nên giải thích rằng cách khắc phục liên quan đến việc sử dụng closure cho deferred resolution hoặc truyền dữ liệu qua tham số method.
"Khi nào nên chọn Swoole thay vì RoadRunner?"
Ưu điểm của Swoole là coroutine concurrency qua Octane::concurrently(), Octane cache tốc độ cao, và các tính năng như ticks và intervals. Đánh đổi là độ phức tạp vận hành: Swoole yêu cầu quản lý PECL extension, trong khi RoadRunner được phân phối dưới dạng binary Go. Đối với ứng dụng CRUD không cần concurrent I/O, RoadRunner đơn giản hơn để vận hành.
"Làm thế nào để xử lý deployment với Octane?"
Trình tự deployment: ngừng nhận kết nối mới, chờ các request đang xử lý hoàn thành, reload worker với code mới. Lệnh php artisan octane:reload xử lý việc này. Ứng viên nên đề cập Supervisor hoặc systemd cho process supervision và Nginx hoặc Caddy làm reverse proxy.
Monitoring và Profiling Ứng Dụng Octane
Việc monitoring bộ nhớ trở nên quan trọng dưới Octane. Worker tồn tại, vì vậy sự tăng trưởng bộ nhớ chỉ ra leak thay vì overhead request bình thường. Laravel Pulse và Telescope đều hoạt động với Octane và cung cấp profiling ở cấp request.
use Laravel\Octane\Events\RequestReceived;
use Laravel\Octane\Events\RequestTerminated;
public function boot(): void
{
Event::listen(RequestReceived::class, function ($event) {
$event->sandbox->instance('request.memory.start', memory_get_usage());
});
Event::listen(RequestTerminated::class, function ($event) {
$start = $event->sandbox->make('request.memory.start');
$delta = memory_get_usage() - $start;
if ($delta > 1024 * 1024) { // More than 1MB growth
Log::warning('High memory delta', [
'path' => $event->request->path(),
'delta_mb' => round($delta / 1024 / 1024, 2),
]);
}
});
}Event listener này ghi lại các request tăng bộ nhớ hơn 1MB, giúp xác định các endpoint cần tối ưu. Đối với monitoring production, các công cụ APM bên ngoài như Datadog hoặc New Relic cung cấp khả năng hiển thị ở cấp worker.
Tích Hợp Octane Với Queue và Horizon
Octane xử lý HTTP request; Laravel Horizon quản lý queue worker. Cả hai hoạt động độc lập và bổ sung cho nhau. Xử lý nặng nên được đặt trong queued job, giữ cho worker Octane luôn responsive.
use App\Jobs\GenerateReport;
class ReportController extends Controller
{
public function generate(Request $request)
{
// Dispatch to queue instead of blocking the Octane worker
GenerateReport::dispatch($request->user(), $request->input('parameters'));
return response()->json(['status' => 'processing']);
}
}Những Điều Cần Nhớ Về Laravel Octane trong 2026
- Octane 2.19 hỗ trợ ba server: FrankenPHP (đơn giản nhất), RoadRunner (ổn định nhất) và Swoole (nhiều tính năng nhất)
- Cải thiện hiệu năng đến từ việc loại bỏ bootstrap mỗi request; kỳ vọng cải thiện throughput 2x đến 4x
- Memory leak xảy ra vì worker state tồn tại; tránh mảng static, request được inject trong constructor, và singleton với dữ liệu request
- Sử dụng
--max-requests=500để buộc tái chế worker trước khi áp lực bộ nhớ tăng - Các tính năng chỉ có ở Swoole bao gồm
Octane::concurrently(), ticks, intervals và Octane cache - Deploy phía sau Nginx hoặc Caddy với Supervisor để quản lý process
- Profiling sự tăng trưởng bộ nhớ mỗi request; delta trên 1MB chỉ ra potential leak
- Queue công việc nặng qua Horizon; để worker Octane xử lý các HTTP response nhanh
Bắt đầu luyện tập!
Kiểm tra kiến thức với mô phỏng phỏng vấn và bài kiểm tra kỹ thuật.
Bạn có tìm ra lỗi trong Laravel không?
Một đoạn mã thật, một lỗi ẩn, mỗi ngày một lượt. Không cần tài khoản để thử.

Viết bởi
Anthony Fillion-MailletNgười sáng lập SharpSkill
Lập trình viên fullstack hơn 10 năm. Anh điều hành SharpSkill và chịu trách nhiệm về mọi nội dung đăng tại đây.
Cập nhật ngày 11 tháng 9, 2026
Thẻ
Chia sẻ
Bài viết liên quan

Câu Hỏi Phỏng Vấn PHP Laravel Developer 2026: Hướng Dẫn Chuẩn Bị Toàn Diện
Hướng dẫn toàn diện để chuẩn bị cho buổi phỏng vấn PHP Laravel developer năm 2026. Bao gồm các câu hỏi kỹ thuật về Eloquent ORM, Service Container, authentication, queue và testing.

Laravel 12 năm 2026: Tính năng mới, Starter Kit và Câu hỏi phỏng vấn
Laravel 12 mang đến các starter kit được thiết kế lại với React 19, Vue 3, Livewire 4 và WorkOS AuthKit. Hướng dẫn đầy đủ về tính năng mới, lộ trình nâng cấp và các câu hỏi phỏng vấn trọng tâm cho năm 2026.

Laravel Middleware Chi Tiet: Xac Thuc, Rate Limiting va Custom Middleware
Huong dan toan dien ve Laravel Middleware voi cac vi du thuc te ve xac thuc nguoi dung, rate limiting, tao middleware tuy chinh va cac pattern san xuat nang cao trong ung dung PHP.