Laravel Octane
Octane menangani bagian tersulit dari worker mode: menjaga agar state framework direset dengan benar antar permintaan. Ia bukan server; ia adalah lapisan yang membuat server mana pun bisa dipakai tanpa mengubah kodemu.
Intisari
composer require laravel/octane, laluphp artisan octane:install --server=โฆ.- Perintahnya sama untuk semua server; yang berubah hanya satu opsi.
- Octane otomatis mereset state milik framework antar permintaan. State buatanmu sendiri tetap tanggung jawabmu.
--max-requests=500(default) me-restart worker berkala sebagai jaring pengaman kebocoran memori.octane:reloadwajib dijalankan setiap deploy โ tanpa itu, kode lama tetap melayani permintaan.
Memasang
composer require laravel/octane
php artisan octane:install --server=frankenphp
# atau
php artisan octane:install --server=roadrunner
# atau
php artisan octane:install --server=swoole
php artisan octane:start
php artisan octane:start --server=frankenphp --host=0.0.0.0 --port=8000
php artisan octane:start --workers=8 --max-requests=500
php artisan octane:start --watch # pengembangan: muat ulang saat berkas berubah
| Opsi | Default | Gunanya |
|---|---|---|
--workers | Jumlah inti CPU | Berapa permintaan bisa diproses bersamaan |
--max-requests | 500 | Restart worker berkala โ penawar kebocoran memori |
--host / --port | 127.0.0.1:8000 | Di kontainer wajib 0.0.0.0 |
--watch | Mati | Hanya untuk lokal; butuh Node dan Chokidar |
Perintah operasional
php artisan octane:status
php artisan octane:reload # muat ulang worker dengan rapi โ JALANKAN SETIAP DEPLOY
php artisan octane:stop
octane:reload adalah langkah deploy yang paling sering terlupa. Aplikasi ada di memori;
mengganti berkas di disk tidak mengubah apa pun sampai worker dimuat ulang. Gejalanya sangat membingungkan:
perbaikan yang sudah di-deploy "kadang muncul, kadang tidak" โ tergantung worker mana yang kebetulan melayani
permintaanmu. Di deploy berbasis kontainer masalah ini hilang dengan sendirinya, karena task baru berarti
proses baru.
Apa yang direset Octane, dan apa yang tidak
| Hal | Direset otomatis? |
|---|---|
Objek Request | Ya |
| Session dan pengguna yang terautentikasi | Ya |
| Repositori konfigurasi | Ya |
Binding scoped di container | Ya |
| Instance model Eloquent | Ya (tidak dibawa antar permintaan) |
| Properti statis di kelasmu | Tidak |
| Singleton buatanmu yang menyimpan data permintaan | Tidak |
| Variabel global | Tidak |
| State di dalam paket pihak ketiga | Tergantung paketnya |
Baris-baris tebal itu adalah seluruh isi materi berikutnya. Octane menutup bagian framework; sisanya adalah tanggung jawab kode aplikasimu, dan di situlah bug worker mode hidup.
Batas waktu eksekusi
// config/octane.php
'max_execution_time' => 30, // detik; 0 = tanpa batas
Ubah nilainya, dan servernya harus di-restart supaya berlaku. Batas ini penting di worker mode: permintaan yang menggantung tidak sekadar lambat, ia menahan satu worker sehingga kapasitas total aplikasi berkurang. Sepuluh permintaan menggantung pada server dengan sepuluh worker berarti aplikasi berhenti merespons sama sekali.
Fitur khusus Octane
// Cache dalam memori proses โ sangat cepat, tapi TIDAK dibagi antar worker
Cache::store('octane')->put('kurs', 16250, 60);
// Dijalankan berkala di dalam proses server
Octane::tick('bersihkan', fn () => Metrik::flush())->seconds(10);
// Sekali saat worker menyala โ tempat menaruh persiapan yang mahal
Octane::prepareApplicationForNextOperation();
Cache octane punya jebakan yang khas. Dengan delapan worker, ada delapan salinan cache
yang berbeda; forget() hanya menghapus salinan di worker yang kebetulan melayani permintaan itu.
Ia tepat untuk data yang boleh sedikit berbeda antar worker dan sangat sering dibaca โ misalnya tabel
pemetaan yang jarang berubah. Untuk apa pun yang harus konsisten, tetap Redis.
Menjalankan di produksi
[program:octane]
process_name=%(program_name)s_%(process_num)02d
command=php /app/artisan octane:start --server=frankenphp --host=0.0.0.0 --port=8000
autostart=true
autorestart=true
stopwaitsecs=3600
Di server tradisional, Supervisor yang menjaga prosesnya tetap hidup. Di kontainer, tugas itu diambil alih oleh ECS atau Kubernetes: proses Octane menjadi PID 1, dan orkestratornya yang me-restart saat gagal. Kita kembali ke sana di Fase 9.
Di belakang web server
upstream octane { server 127.0.0.1:8000; }
server {
location /build/ { root /app/public; } # aset dilayani Nginx
location / {
proxy_pass http://octane;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Untuk RoadRunner dan Swoole, pola ini lazim. Untuk FrankenPHP, ia justru berlebihan: FrankenPHP adalah web server (Caddy) yang sudah menangani TLS dan berkas statis. Perbedaan ini adalah salah satu pembeda utama keduanya, dan dibahas di materi perbandingan.
Latihan: pasang Octane dengan FrankenPHP, jalankan octane:start, lalu buka rute
/ukur dari materi sebelumnya sepuluh kali. Bandingkan bootstrap_ms-nya dengan angka
yang kamu catat tadi โ dan perhatikan bahwa permintaan pertama tetap mahal.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.