Laravel Octane ในปี 2026: Swoole, RoadRunner และการเพิ่มประสิทธิภาพ
เรียนรู้ Laravel Octane 2.19 กับ FrankenPHP, Swoole และ RoadRunner ครบถ้วน ตั้งแต่การเลือก server การป้องกัน memory leak การทำงานแบบ concurrent และรูปแบบการ deploy สำหรับ production

Laravel Octane เปลี่ยนแปลงประสิทธิภาพของแอปพลิเคชัน PHP โดยการเก็บ framework ที่ทำการ bootstrap แล้วไว้ในหน่วยความจำระหว่าง request ต่างๆ เวอร์ชัน 2.19 (สิงหาคม 2026) รองรับ server ที่พร้อมใช้งานใน production สามตัว: FrankenPHP, Swoole และ RoadRunner แต่ละตัวมีข้อกำหนดการใช้งานที่แตกต่างกัน และการเลือกผิดจะส่งผลต่อประสิทธิภาพหรือความเสถียร
FrankenPHP: ติดตั้งง่ายที่สุด, HTTP/3 native, single binary RoadRunner: Go binary ที่ผ่านการทดสอบแล้ว, ไม่ต้องการ PHP extension Swoole: throughput สูงสุดพร้อม coroutine concurrency, ต้องจัดการ PECL extension
วิธีที่ Octane กำจัด Bootstrap Overhead
PHP-FPM แบบดั้งเดิมจะสร้าง process ใหม่สำหรับทุก request Laravel จะ boot service container, โหลด configuration, ลงทะเบียน provider และ resolve middleware ในทุกการเรียก HTTP Octane พลิกโมเดลนี้: แอปพลิเคชัน boot เพียงครั้งเดียวต่อ worker จากนั้น instance เดียวกันจะจัดการ request นับพันตามลำดับ
ประโยชน์ด้านประสิทธิภาพมาจากการลดงานที่ซ้ำซ้อน แอปพลิเคชัน Laravel 12 ทั่วไปใช้เวลา 15 ถึง 40ms สำหรับการ bootstrap ก่อนที่จะรัน business logic ด้วย Octane ค่าใช้จ่ายนี้ลดลงเป็นศูนย์หลังจาก request แรก Benchmark บน hardware เดียวกันแสดงการปรับปรุง throughput 2x ถึง 4x สำหรับ API endpoint โดยช่องว่างจะกว้างขึ้นเมื่อความซับซ้อนของแอปพลิเคชันเพิ่มขึ้น
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,
];การตั้งค่า max_requests ทำหน้าที่เป็นวาล์วนิรภัย แม้แต่โค้ดที่เขียนอย่างดีก็สามารถสะสมหน่วยความจำผ่าน request หลายร้อยครั้ง การตั้งค่านี้เป็น 500 บังคับให้ worker รีสตาร์ทก่อนที่แรงกดดันหน่วยความจำจะกลายเป็นปัญหา
FrankenPHP: ค่าเริ่มต้นปี 2026 สำหรับโปรเจคใหม่
FrankenPHP มาในรูปแบบ single binary ที่สร้างบน Caddy และ PHP มันจัดการใบรับรอง HTTPS โดยอัตโนมัติผ่าน Let's Encrypt, รองรับ HTTP/3 ทันทีที่ใช้งาน และไม่ต้องติดตั้ง PHP extension ใดๆ Installer ของ Laravel และตัวอย่าง production ตอนนี้ใช้ 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สำหรับการ deploy แบบ containerized, FrankenPHP มี Docker image อย่างเป็นทางการ:
# Dockerfile
FROM dunglas/frankenphp
RUN install-php-extensions \
pcntl \
pdo_pgsql \
redis
COPY . /app
ENTRYPOINT ["php", "artisan", "octane:frankenphp"]การกำหนดค่า Docker Compose สำหรับ development เปิดใช้งาน HTTPS และ 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 จัดการการรีสตาร์ท worker อย่างราบรื่นและผสานรวมกับระบบ middleware ของ Caddy สำหรับสถานการณ์ routing ขั้นสูง
RoadRunner: ความเสถียรบน Go โดยไม่ต้องพึ่ง Extension
RoadRunner คอมไพล์เป็น Go binary ที่จัดการ PHP worker process มันสื่อสารกับ PHP ผ่าน binary protocol โดยเก็บการจัดการ worker และการจัดการ HTTP ไว้ใน Go ขณะที่รัน application code ใน PHP สถาปัตยกรรมนี้ให้ process isolation: PHP worker ที่ crash ไม่ส่งผลกระทบต่อ Go parent หรือ sibling worker
# 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=8000การกำหนดค่า RoadRunner อยู่ใน .rr.yaml ที่ root ของโปรเจค:
# .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: 128การตั้งค่า max_worker_memory (หน่วยเป็น MB) ยุติ worker ที่เกินขีดจำกัดหน่วยความจำ โดยให้ตาข่ายนิรภัยเพิ่มเติมนอกเหนือจาก max_requests สำหรับทีมที่มี CI pipeline ที่จัดตั้งแล้วและโครงสร้างพื้นฐาน PHP-FPM ที่มีอยู่ RoadRunner เสนอเส้นทางการย้ายที่ราบรื่นที่สุด
Swoole: Throughput สูงสุดด้วย Coroutine Concurrency
Swoole ทำงานเป็น PHP extension ที่แทนที่วงจรชีวิต request มาตรฐานด้วย event-driven runtime ที่รองรับ coroutine มันมีฟีเจอร์ที่ไม่มีใน server อื่น: การรัน task พร้อมกัน, ticks และ intervals และ in-memory cache ที่มี throughput 2 ล้าน operations ต่อวินาที
# 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=6การรัน task พร้อมกันของ Swoole จัดการ I/O operation แบบขนานภายใน 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'));
}
}หากไม่มี Octane::concurrently() query ทั้งสามนี้จะรันตามลำดับ: 50ms + 30ms + 40ms = รวม 120ms ด้วยการรันพร้อมกัน เวลารวมเท่ากับ query ที่ช้าที่สุด: 50ms Flag --task-workers ควบคุมจำนวน concurrent operation ที่สามารถรันพร้อมกันในทุก request worker
Concurrent tasks, ticks, intervals, Octane cache และ Swoole tables ต้องการ Swoole extension FrankenPHP และ RoadRunner ไม่รองรับฟีเจอร์เหล่านี้ ประเมินว่าแอปพลิเคชันต้องการฟีเจอร์เหล่านี้หรือไม่ก่อนที่จะเลือกความซับซ้อนในการดำเนินงานของ Swoole
การป้องกัน Memory Leak: การเขียนโค้ดแบบ Stateless
ประสิทธิภาพของ Octane มาจาก persistent state ซึ่งสร้างความท้าทายหลัก: โค้ดที่ทำงานได้ดีภายใต้ PHP-FPM สามารถทำให้เกิด memory leak รุนแรงภายใต้ Octane instance ของแอปพลิเคชันยังคงอยู่ระหว่าง request ดังนั้น static property, singleton และ global state จะสะสม
สามรูปแบบที่ทำให้เกิด memory leak ส่วนใหญ่:
Static array ที่เติบโตไม่จำกัด:
// 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 ที่เก็บข้อมูลเฉพาะ 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 และ request ใน 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
}
}Global helper app(), request() และ config() จะคืนค่าปัจจุบันเสมอ การใช้พวกมันแทน constructor injection หลีกเลี่ยง leak ที่เกี่ยวข้องกับ singleton ส่วนใหญ่
รูปแบบการ Deploy สำหรับ Production
Server Octane ต้องการ process supervision เพื่อรีสตาร์ทเมื่อ crash Supervisor จัดการสิ่งนี้ได้อย่างน่าเชื่อถือ:
; /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สำหรับการ deploy, Octane worker ต้อง reload เพื่อรับโค้ดใหม่ คำสั่ง octane:reload จัดการสิ่งนี้อย่างราบรื่น โดยรอให้ request ที่กำลังทำงานเสร็จก่อนที่จะ recycle worker:
# In deployment script (after git pull, composer install, etc.)
php artisan octane:reloadNginx อยู่หน้า Octane เพื่อให้บริการ static asset และยุติ 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 รักษาการเชื่อมต่อแบบ persistent ระหว่าง Nginx และ Octane ลด TCP handshake overhead สำหรับ request ที่ถูก proxy
พร้อมที่จะพิชิตการสัมภาษณ์ Laravel แล้วหรือยังครับ?
ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ
แผนภูมิตัดสินใจเลือก Server
การเลือกระหว่าง FrankenPHP, RoadRunner และ Swoole ขึ้นอยู่กับข้อจำกัดด้านการดำเนินงานและความต้องการของแอปพลิเคชัน:
| ความต้องการ | Server ที่แนะนำ |
|---|---|
| ติดตั้งง่ายที่สุด, deploy แบบ container | FrankenPHP |
| รองรับ HTTP/3 ทันที | FrankenPHP |
| ไม่ต้องพึ่ง PHP extension | FrankenPHP หรือ RoadRunner |
| Process isolation สูงสุด | RoadRunner |
| โครงสร้างพื้นฐาน PHP-FPM ที่มีอยู่ | RoadRunner |
| Concurrent I/O ภายใน request | Swoole |
| In-memory caching (2M ops/วินาที) | Swoole |
| Ticks, intervals, background tasks | Swoole |
| Swoole tables สำหรับ shared state | Swoole |
สำหรับทีมที่เริ่มโปรเจคใหม่ในปี 2026 FrankenPHP ให้ความสมดุลที่ดีที่สุดระหว่างความเรียบง่ายและความสามารถ การย้ายแอปพลิเคชันที่มีอยู่ทำงานได้ดีที่สุดกับ RoadRunner เนื่องจาก process isolation และโมเดลการ deploy ที่คุ้นเคย Swoole เหมาะสำหรับ API ที่มี throughput สูงที่ได้ประโยชน์จาก coroutine concurrency และต้องการฟีเจอร์เฉพาะของ Swoole
คำถามสัมภาษณ์เกี่ยวกับ Laravel Octane
การสัมภาษณ์ทางเทคนิคครอบคลุม Octane มากขึ้นเนื่องจากแอปพลิเคชัน Laravel ที่มี traffic สูงนำไปใช้ คำถามทั่วไปและสิ่งที่ผู้สัมภาษณ์มองหา:
"Octane บรรลุการปรับปรุงประสิทธิภาพได้อย่างไร?"
คำตอบที่คาดหวัง: Octane boot Laravel หนึ่งครั้งต่อ worker และใช้ instance นั้นซ้ำระหว่าง request ซึ่งกำจัดค่าใช้จ่าย bootstrap 15-40ms ในทุก request ผู้สมัครควรกล่าวถึงว่า method register และ boot ของ service provider รันหนึ่งครั้งต่อ worker ไม่ใช่ต่อ request
"อะไรทำให้เกิด memory leak ในแอปพลิเคชัน Octane?"
คำตอบที่ดีระบุสามแหล่ง: static array ที่สะสมข้อมูล, singleton ที่จับ state เฉพาะ request และ constructor injection ของ object container หรือ request ผู้สมัครควรอธิบายว่าการแก้ไขเกี่ยวข้องกับการใช้ closure สำหรับ deferred resolution หรือส่งข้อมูลผ่าน method parameter
"เมื่อไหร่ควรเลือก Swoole แทน RoadRunner?"
ข้อได้เปรียบของ Swoole คือ coroutine concurrency ผ่าน Octane::concurrently(), Octane cache ความเร็วสูง และฟีเจอร์เช่น ticks และ intervals การแลกเปลี่ยนคือความซับซ้อนในการดำเนินงาน: Swoole ต้องการการจัดการ PECL extension ในขณะที่ RoadRunner มาเป็น Go binary สำหรับแอปพลิเคชัน CRUD ที่ไม่ต้องการ concurrent I/O RoadRunner ง่ายกว่าในการดำเนินงาน
"จะจัดการการ deploy กับ Octane อย่างไร?"
ลำดับการ deploy: หยุดรับการเชื่อมต่อใหม่ รอให้ request ที่กำลังทำงานเสร็จ reload worker ด้วยโค้ดใหม่ คำสั่ง php artisan octane:reload จัดการสิ่งนี้ ผู้สมัครควรกล่าวถึง Supervisor หรือ systemd สำหรับ process supervision และ Nginx หรือ Caddy เป็น reverse proxy
การ Monitor และ Profile แอปพลิเคชัน Octane
การ monitor หน่วยความจำกลายเป็นสิ่งสำคัญภายใต้ Octane Worker ยังคงอยู่ ดังนั้นการเติบโตของหน่วยความจำบ่งบอกถึง leak แทนที่จะเป็น request overhead ปกติ Laravel Pulse และ Telescope ทั้งคู่ทำงานกับ Octane และให้ profiling ระดับ 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 นี้บันทึก request ที่เพิ่มหน่วยความจำมากกว่า 1MB ช่วยระบุ endpoint ที่ต้องการการ optimize สำหรับการ monitor production เครื่องมือ APM ภายนอกเช่น Datadog หรือ New Relic ให้ visibility ระดับ worker
การรวม Octane กับ Queue และ Horizon
Octane จัดการ HTTP request; Laravel Horizon จัดการ queue worker ทั้งสองทำงานอิสระและเสริมซึ่งกันและกัน การประมวลผลหนักควรอยู่ใน queued job โดยให้ Octane worker ตอบสนองได้รวดเร็ว
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']);
}
}สิ่งที่ต้องจำเกี่ยวกับ Laravel Octane ในปี 2026
- Octane 2.19 รองรับสาม server: FrankenPHP (ง่ายที่สุด), RoadRunner (เสถียรที่สุด) และ Swoole (ฟีเจอร์มากที่สุด)
- การปรับปรุงประสิทธิภาพมาจากการกำจัด bootstrap ต่อ request; คาดหวังการปรับปรุง throughput 2x ถึง 4x
- Memory leak เกิดขึ้นเพราะ worker state ยังคงอยู่; หลีกเลี่ยง static array, request ที่ถูก inject ใน constructor และ singleton ที่มีข้อมูล request
- ใช้
--max-requests=500เพื่อบังคับการ recycle worker ก่อนที่แรงกดดันหน่วยความจำจะสะสม - ฟีเจอร์เฉพาะ Swoole รวมถึง
Octane::concurrently(), ticks, intervals และ Octane cache - Deploy หลัง Nginx หรือ Caddy ด้วย Supervisor สำหรับการจัดการ process
- Profile การเติบโตของหน่วยความจำต่อ request; delta เกิน 1MB บ่งบอกถึง potential leak
- ส่งงานหนักผ่าน Horizon; ให้ Octane worker จัดการ HTTP response ที่รวดเร็ว
เริ่มฝึกซ้อมเลย!
ทดสอบความรู้ของคุณด้วยตัวจำลองสัมภาษณ์และแบบทดสอบเทคนิคครับ
คุณหาบั๊กใน Laravel เจอไหม
โค้ดจริงหนึ่งชิ้น บั๊กที่ซ่อนอยู่หนึ่งจุด วันละหนึ่งครั้ง ลองได้โดยไม่ต้องมีบัญชี

เขียนโดย
Anthony Fillion-Mailletผู้ก่อตั้ง SharpSkill
เป็นนักพัฒนาฟูลสแตกมากว่า 10 ปี ดูแล SharpSkill และรับผิดชอบทุกสิ่งที่เผยแพร่ที่นี่
อัปเดตเมื่อ 11 กันยายน 2569
แท็ก
แชร์
บทความที่เกี่ยวข้อง

คำถามสัมภาษณ์ PHP Laravel Developer 2026: คู่มือเตรียมตัวฉบับสมบูรณ์
คู่มือครอบคลุมสำหรับการเตรียมตัวสัมภาษณ์ PHP Laravel developer ปี 2026 ครอบคลุมคำถามเทคนิคเกี่ยวกับ Eloquent ORM, Service Container, authentication, queue และ testing

Laravel 12 ในปี 2026: ฟีเจอร์ใหม่ Starter Kit และคำถามสัมภาษณ์
Laravel 12 นำ starter kit ที่ออกแบบใหม่มาพร้อม React 19, Vue 3, Livewire 4 และ WorkOS AuthKit คู่มือฉบับสมบูรณ์ครอบคลุมฟีเจอร์ใหม่ เส้นทางการอัปเกรด และคำถามสัมภาษณ์สำคัญสำหรับปี 2026

Laravel Middleware เจาะลึก: Authentication, Rate Limiting และ Custom Middleware ฉบับสมบูรณ์
คู่มือเจาะลึก Laravel Middleware ครอบคลุมการทำงานของ Authentication Middleware, Rate Limiting ด้วย Throttle, การสร้าง Custom Middleware และการลงทะเบียน Middleware ใน Laravel 12 พร้อมตัวอย่างโค้ดที่ใช้งานได้จริงในโปรดักชัน