Memproses tugas-tugas berat di aplikasi web, seperti mengirim ribuan email, mengelola notifikasi real-time, atau melakukan komputasi kompleks, seringkali menjadi bottleneck. Jika tugas-tugas ini dieksekusi secara langsung, pengguna akan merasakan respons aplikasi yang lambat, bahkan timeout. Di sinilah antrean (queue) berperan penting, dan Laravel Horizon adalah solusi elegan untuk mengelola antrean di ekosistem Laravel.
Sebagai seorang developer yang sering berurusan dengan aplikasi skala produksi, saya paham betul betapa krusialnya memiliki sistem antrean yang robust dan mudah dimonitor. Tanpa Horizon, mengelola queue worker bisa jadi mimpi buruk, apalagi saat menghadapi lonjakan traffic atau kegagalan tak terduga. Artikel ini akan memandu Anda secara mendalam tentang cara menggunakan Horizon, mulai dari instalasi hingga optimasi, lengkap dengan insight praktis dan solusi untuk masalah yang sering terjadi.
Apa itu Laravel Horizon dan Kenapa Anda Membutuhkannya?
Laravel Horizon adalah dashboard dan sistem konfigurasi canggih untuk antrean Redis yang ada di Laravel. Secara sederhana, Horizon memberikan Anda visibilitas penuh dan kontrol granular terhadap semua proses antrean di aplikasi Laravel Anda. Bayangkan Anda memiliki puluhan, bahkan ratusan, background jobs yang berjalan simultan. Tanpa Horizon, melacak status, kinerja, atau kegagalan job-job tersebut akan sangat sulit.
Horizon dibangun di atas Redis, sebuah key-value store in-memory yang sangat cepat, menjadikannya pilihan ideal untuk backend antrean. Dengan Horizon, Anda tidak hanya dapat menjalankan dan memonitor worker, tetapi juga mengelola retry, failed jobs, metrik kinerja, dan bahkan mendapatkan notifikasi jika ada masalah.
Kenapa Anda membutuhkannya? Karena ini bukan hanya tentang memindahkan tugas ke latar belakang. Ini tentang:
- Skalabilitas: Mudah menambah atau mengurangi jumlah worker untuk menangani beban kerja yang bervariasi.
- Reliabilitas: Fitur retry otomatis untuk failed jobs dan visibilitas ke dalam kegagalan.
- Observability: Dashboard real-time yang menunjukkan throughput, waktu eksekusi, dan status worker.
- Kemudahan Manajemen: Konfigurasi worker melalui file PHP, bukan lagi mengandalkan banyak perintah
php artisan queue:workatau konfigurasi Supervisor yang rumit secara manual.
Jika aplikasi Anda mulai melibatkan tugas-tugas non-real-time yang bisa dieksekusi di latar belakang—seperti integrasi API pihak ketiga, pemrosesan data, atau pengiriman email massal—maka Horizon adalah investasi waktu yang sangat berharga.
Prasyarat Sebelum Menginstal Laravel Horizon
Sebelum kita mulai menginstal dan mengkonfigurasi Laravel Horizon, ada beberapa prasyarat yang perlu Anda siapkan:
- Proyek Laravel: Tentu saja, Anda memerlukan instalasi proyek Laravel yang sudah berjalan.
- PHP 8.0+ : Pastikan versi PHP Anda kompatibel dengan Laravel Horizon.
- Composer: Untuk mengelola dependensi PHP.
- Redis Server: Horizon menggunakan Redis sebagai driver antrean utamanya. Anda harus menginstal dan menjalankan Redis server di mesin Anda (lokal atau di server produksi).
- Konfigurasi Redis di Laravel: Pastikan Anda telah mengkonfigurasi koneksi Redis di file
.envdanconfig/database.phpLaravel Anda. Contoh konfigurasi di.env:REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379 - Konfigurasi Queue Driver: Pastikan
QUEUE_CONNECTIONdi file.envAnda diatur keredis:QUEUE_CONNECTION=redis
Langkah Demi Langkah Instalasi Laravel Horizon
Mari kita mulai dengan proses instalasi dan konfigurasi Horizon.
1. Instalasi Redis Server
Jika Anda belum memiliki Redis, Anda bisa menginstalnya. Di Ubuntu, perintahnya adalah:
sudo apt update
sudo apt install redis-server
Setelah instalasi, pastikan Redis berjalan:
sudo systemctl status redis-server
2. Instalasi dan Konfigurasi Laravel Horizon
Pertama, instal paket Horizon melalui Composer:
composer require laravel/horizon
Setelah itu, publish aset Horizon:
php artisan horizon:install
Perintah ini akan membuat file konfigurasi config/horizon.php dan aset lainnya yang diperlukan.
Di file .env Anda, pastikan Anda telah mengatur lingkungan untuk Horizon. Secara default, Horizon hanya aktif di lingkungan local. Untuk produksi, Anda mungkin perlu mengubahnya:
HORIZON_ENV=production (atau biarkan kosong jika Anda ingin Horizon aktif di semua lingkungan)
Mari kita buat job sederhana untuk menguji Horizon. Gunakan Artisan:
php artisan make:job SendWelcomeEmail
Buka file app/Jobs/SendWelcomeEmail.php dan tambahkan logika sederhana:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
class SendWelcomeEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $userEmail;
/
* Create a new job instance.
*/
public function __construct($userEmail)
{
$this->userEmail = $userEmail;
}
/
* Execute the job.
*/
public function handle(): void
{
// Simulasi pengiriman email
sleep(5); // Anggap ini proses yang butuh 5 detik
Log::info("Sending welcome email to: " . $this->userEmail);
// Di sini Anda bisa memanggil Mail::to($this->userEmail)->send(new WelcomeEmail());
}
}
Untuk men-dispatch job ini, Anda bisa memanggilnya dari controller atau bagian lain di aplikasi Anda:
<?php
namespace App\Http\Controllers;
use App\Jobs\SendWelcomeEmail;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function register(Request $request)
{
// Logika registrasi user...
// Dispatch job setelah user terdaftar
SendWelcomeEmail::dispatch($request->email);
return response()->json(['message' => 'User registered and welcome email queued!']);
}
}
4. Menjalankan Worker Horizon
Untuk menjalankan Horizon, Anda bisa menggunakan perintah Artisan:
php artisan horizon
Perintah ini akan memulai Horizon dan worker-worker Anda akan mulai memproses jobs dari antrean Redis. Namun, untuk lingkungan produksi, Anda tidak boleh menjalankan perintah ini secara langsung. Anda harus menggunakan proses manajer seperti Supervisor untuk memastikan Horizon terus berjalan dan me-restart otomatis jika terjadi kegagalan.
Konfigurasi Supervisor untuk Horizon:
Instal Supervisor jika belum ada:
sudo apt install supervisor
Buat file konfigurasi Supervisor untuk Horizon, misalnya /etc/supervisor/conf.d/horizon.conf:
[program:horizon]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/your-project/artisan horizon
autostart=true
autorestart=true
user=www-data ; Ganti dengan user web server Anda
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/html/your-project/storage/logs/horizon.log
stopwaitsecs=3600
Pastikan untuk mengganti /var/www/html/your-project dengan path root proyek Laravel Anda dan www-data dengan user yang benar (biasanya user web server seperti nginx atau apache).
Setelah membuat file konfigurasi, muat ulang Supervisor:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start horizon:*
5. Mengakses Dashboard Horizon
Setelah Horizon berjalan, Anda bisa mengakses dashboard-nya melalui URL:
http://your-app-domain.com/horizon
Secara default, Horizon hanya bisa diakses di lingkungan local atau jika Anda sedang login sebagai user yang diperbolehkan di konfigurasi config/horizon.php. Untuk produksi, Anda perlu melindungi akses ke dashboard Horizon, misalnya dengan otentikasi. Anda bisa mengkonfigurasi gate otentikasi di app/Providers/HorizonServiceProvider.php:
/
* Register the Horizon gate.
*
* This gate determines who can access Horizon in non-local environments.
*/
protected function gate(): void
{
Gate::define('viewHorizon', function ($user) {
return in_array($user->email, [
'admin@example.com',
]);
});
}
Ganti 'admin@example.com' dengan email user admin Anda.
Fitur Unggulan Laravel Horizon untuk Monitoring Queue
Dashboard Horizon bukan sekadar tampilan statis; ini adalah pusat komando real-time untuk antrean Anda.
- Real-time Monitoring: Lihat job yang sedang berjalan, job yang menunggu, job yang gagal, dan throughput secara instan.
- Metrik dan Throughput: Horizon menampilkan metrik penting seperti rata-rata waktu eksekusi job, jumlah job per menit, dan penggunaan memori worker. Ini sangat berguna untuk mengidentifikasi bottleneck.
- Retry dan Failed Jobs: Mudah melihat detail failed jobs, termasuk exception stack trace, dan me-retry job tersebut secara manual.
- Batches: Jika Anda menggunakan job batching di Laravel (memproses sekelompok job secara bersamaan dan mendapatkan notifikasi saat semua job selesai), Horizon menyediakan tampilan khusus untuk memonitor status batch.
- Notifikasi: Konfigurasi Horizon untuk mengirim notifikasi ke Slack atau email saat queue dalam kondisi kritis (misalnya, terlalu banyak failed jobs).
Fitur-fitur ini sangat membantu dalam menjaga kesehatan aplikasi, terutama saat aplikasi tumbuh dan beban kerja antrean meningkat.
Konfigurasi Lanjut dan Optimasi Laravel Horizon
File config/horizon.php adalah tempat Anda mengkonfigurasi semua aspek Horizon. Beberapa pengaturan penting yang sering dioptimasi:
1. Strategi Balance Worker
Horizon memiliki tiga strategi balancing:
simple: Mendistribusikan job secara merata ke semua worker.auto: Horizon akan mencoba menyeimbangkan jumlah worker berdasarkan beban antrean. Ini adalah opsi yang paling umum dan direkomendasikan.false: Menonaktifkan fitur balancing, Anda harus mengelola jumlah worker secara manual.
Anda bisa mengatur ini di config/horizon.php:
'defaults' => [
'supervisor-name' => [
'connection' => 'redis',
'queue' => ['default'],
'balance' => 'auto', // Pilihan: auto, simple, false
'min_processes' => 1,
'max_processes' => 10,
'tries' => 3,
],
],
2. Membuat Supervisor Kustom
Anda bisa mendefinisikan beberapa “supervisor” di Horizon, masing-masing dengan konfigurasi worker yang berbeda. Misalnya, Anda ingin worker untuk antrean emails memiliki prioritas lebih tinggi atau resource lebih besar daripada antrean default.
'supervisors' => [
'default' => [
'connection' => 'redis',
'queue' => ['default', 'reports'], // Antrean untuk supervisor ini
'balance' => 'auto',
'min_processes' => 1,
'max_processes' => 5,
'tries' => 3,
'timeout' => 120, // Timeout per job dalam detik
],
'email_processor' => [
'connection' => 'redis',
'queue' => ['emails'], // Hanya memproses antrean 'emails'
'balance' => 'auto',
'min_processes' => 2,
'max_processes' => 10,
'tries' => 5,
'timeout' => 300,
'memory' => 512, // Batas memori per worker dalam MB
],
],
Dengan konfigurasi ini, Anda bisa memiliki worker yang didedikasikan untuk tugas-tugas tertentu, memberikan fleksibilitas dan kontrol yang lebih baik atas prioritas dan resource.
3. Menggunakan Multiple Queue Connections
Meskipun Horizon utamanya menggunakan Redis, Anda masih bisa memiliki koneksi antrean lain yang didefinisikan di config/queue.php. Horizon akan fokus pada koneksi yang Anda tetapkan di konfigurasinya.
4. Limitasi Resource Worker
Setiap worker Horizon adalah proses PHP terpisah. Penting untuk membatasi resource yang bisa mereka gunakan untuk mencegah satu worker memonopoli semua resource server. Pengaturan memory di konfigurasi supervisor sangat membantu. Horizon juga memiliki fitur max_time dan max_jobs untuk me-restart worker setelah periode waktu atau jumlah job tertentu, mencegah kebocoran memori.
Pengalaman dan Pertimbangan Praktis Saat Menggunakan Horizon
Sebagai praktisi yang sering mengimplementasikan Horizon di berbagai proyek, ada beberapa pengalaman dan pertimbangan yang ingin saya bagikan:
- Kapan Horizon Menjadi Sangat Berharga?
Di project skala kecil dengan hanya beberapa job per hari, Horizon mungkin terasa overkill. Anda bisa bertahan dengan
php artisan queue:workdan Supervisor manual. Namun, begitu Anda mulai melihat puluhan atau ratusan job per jam, atau Anda memiliki kebutuhan untuk melacak metrik kinerja antrean, itulah saat Horizon benar-benar bersinar. Dashboard-nya sangat membantu saat debugging masalah antrean atau memonitor kinerja di produksi. - Tantangan Implementasi di Produksi
Salah satu tantangan umum adalah memastikan Supervisor dikonfigurasi dengan benar, terutama terkait user permission dan path proyek. Seringkali, Horizon tidak bisa menulis log atau memulai worker karena masalah izin file. Pastikan user yang menjalankan Supervisor memiliki izin yang cukup untuk mengakses folder proyek Laravel Anda, terutama
storagedanbootstrap/cache.Selain itu, memonitor penggunaan Redis juga penting. Jika antrean Anda sangat padat, Redis bisa menjadi bottleneck. Pastikan Redis server Anda memiliki cukup RAM dan CPU, atau pertimbangkan untuk meng-cluster Redis jika beban sangat tinggi.
- Biaya Redis dan Skalabilitas
Menggunakan Redis sebagai backend antrean memang cepat, tetapi juga berarti Anda perlu mengalokasikan resource untuk Redis. Untuk aplikasi skala besar, Anda mungkin perlu mempertimbangkan managed Redis service seperti Amazon ElastiCache atau Redis Enterprise, yang tentu memiliki biaya tambahan. Horizon sendiri tidak memakan banyak resource, tetapi worker-worker PHP di baliknya yang akan mengkonsumsi memori dan CPU tergantung kompleksitas job Anda.
- Alternatif Jika Horizon Terlalu Overkill
Jika kebutuhan antrean Anda sangat sederhana dan Anda ingin menghindari dependensi Redis atau Horizon, Anda bisa menggunakan database queue driver Laravel. Ini lebih lambat dan tidak seefisien Redis, tetapi lebih mudah di-setup untuk kasus penggunaan dasar. Namun, Anda akan kehilangan semua fitur monitoring dan manajemen canggih yang ditawarkan Horizon.
Masalah yang Sering Terjadi Saat Menggunakan Laravel Horizon
Meskipun Horizon sangat membantu, ada beberapa masalah umum yang sering saya temui (dan mungkin Anda juga) saat mengimplementasikannya:
1. Job Tidak Dieksekusi
- Gejala: Anda men-dispatch job, tetapi tidak muncul di dashboard Horizon atau tidak pernah dieksekusi.
- Penyebab:
- Worker Horizon belum berjalan (
php artisan horizonatau Supervisor tidak aktif). QUEUE_CONNECTIONdi.envtidak diatur keredis.- Redis server tidak berjalan atau tidak dapat diakses dari aplikasi Laravel.
- Antrean (queue) yang Anda dispatch tidak diproses oleh supervisor Horizon. (e.g., job
MyJob::dispatch()->onQueue('high_priority');tapi supervisor Horizon tidak mengawasi antreanhigh_priority).
- Worker Horizon belum berjalan (
- Solusi:
- Pastikan Horizon berjalan dengan
php artisan horizonatau cek status Supervisor (sudo supervisorctl status). - Periksa file
.envdanconfig/queue.php. - Cek koneksi ke Redis menggunakan
redis-cli pingatau coba flush Redis cache jika ada masalah. - Pastikan konfigurasi
supervisorsdiconfig/horizon.phpmencakup semua nama antrean (queue) yang Anda gunakan.
- Pastikan Horizon berjalan dengan
2. Dashboard Horizon Tidak Muncul atau Error 403
- Gejala: Saat mengakses
/horizon, Anda mendapatkan 404 (Not Found) atau 403 (Forbidden). - Penyebab:
- Aset Horizon belum di-publish atau ada masalah routing.
- Anda tidak berada di lingkungan
local, dan Anda belum mengkonfigurasi gate otentikasi diHorizonServiceProvider.
- Solusi:
- Jalankan ulang
php artisan horizon:installdanphp artisan config:clear, lalu pastikan web server Anda (Nginx/Apache) dikonfigurasi dengan benar untuk Laravel (misalnya, semua permintaan diarahkan kepublic/index.php). - Konfigurasi gate otentikasi di
app/Providers/HorizonServiceProvider.phpseperti yang dijelaskan di atas.
- Jalankan ulang
3. Out of Memory atau Resource Terbatas
- Gejala: Job gagal dengan pesan “Allowed memory size of X bytes exhausted” atau server menjadi sangat lambat.
- Penyebab:
- Job Anda mengkonsumsi terlalu banyak memori (misalnya, memproses file besar atau mengambil data dalam jumlah masif).
- Jumlah worker terlalu banyak untuk resource server yang tersedia.
- Memory leak di salah satu job atau dependensinya.
- Solusi:
- Optimasi job Anda agar lebih efisien dalam penggunaan memori. Pecah job besar menjadi job-job yang lebih kecil jika memungkinkan.
- Kurangi jumlah
max_processesatau tingkatkan nilaimemorydi konfigurasi supervisor Horizon (config/horizon.php). - Aktifkan
max_jobsataumax_timedi konfigurasi Horizon untuk me-restart worker secara berkala, membantu membersihkan memori yang mungkin bocor. - Upgrade resource server (RAM, CPU).
4. Horizon Terhenti Mendadak
- Gejala: Horizon worker berhenti memproses job, dan dashboard menunjukkan worker tidak aktif.
- Penyebab:
- Tidak menggunakan Supervisor di produksi, sehingga proses
php artisan horizonterhenti (misalnya, karena sesi SSH putus). - Ada exception yang tidak tertangani di salah satu job, menyebabkan worker mati.
- Server kehabisan resource (RAM/CPU) dan sistem membunuh proses Horizon.
- Tidak menggunakan Supervisor di produksi, sehingga proses
- Solusi:
- Selalu gunakan Supervisor di lingkungan produksi. Ini adalah solusi paling penting untuk masalah ini.
- Pastikan semua job Anda memiliki penanganan exception yang tepat. Gunakan
try-catchdi dalam metodehandle()job. - Periksa log Horizon (
storage/logs/horizon.log) dan log aplikasi Laravel Anda (storage/logs/laravel.log) untuk melihat error yang mungkin terjadi. - Memonitor resource server secara berkala.
FAQ
Apa perbedaan Horizon dengan php artisan queue:work biasa?
php artisan queue:work adalah perintah dasar untuk menjalankan satu proses worker. Horizon adalah lapisan di atasnya yang menyediakan dashboard monitoring real-time, manajemen worker yang canggih (balancing, scaling), fitur retry/fail otomatis, dan konfigurasi yang lebih mudah melalui file PHP daripada pengaturan Supervisor manual.
Apakah Horizon memerlukan Redis?
Ya, secara fundamental Laravel Horizon dirancang untuk bekerja dengan Redis sebagai driver antrean. Anda harus menginstal dan menjalankan Redis server untuk menggunakan Horizon.
Bisakah saya menggunakan Horizon tanpa Supervisor?
Secara teknis bisa untuk development (dengan menjalankan php artisan horizon), tetapi sangat tidak disarankan untuk lingkungan produksi. Supervisor memastikan proses Horizon tetap berjalan di latar belakang, me-restart otomatis jika terjadi kegagalan, dan mengelola worker dengan andal, yang krusial untuk aplikasi produksi.
Bagaimana cara menghentikan Horizon?
Jika Anda menjalankan Horizon secara manual, tekan Ctrl+C. Jika menggunakan Supervisor, gunakan perintah sudo supervisorctl stop horizon:*.
Kesimpulan
Mengelola background jobs adalah aspek penting dalam pengembangan aplikasi modern, terutama saat aplikasi tumbuh dan memerlukan skalabilitas serta efisiensi. Laravel Horizon menawarkan solusi yang powerful dan elegan untuk tantangan ini, mengubah manajemen antrean dari tugas yang membosankan menjadi proses yang transparan dan terkontrol. Dengan Horizon, Anda tidak hanya dapat memproses job di latar belakang, tetapi juga memiliki pandangan mata burung (bird’s eye view) ke seluruh sistem antrean Anda, memastikan aplikasi tetap responsif dan andal.
Dari instalasi dasar hingga optimasi lanjutan dan penanganan masalah umum, semoga panduan ini memberikan Anda kepercayaan diri untuk mengimplementasikan Laravel Horizon di proyek-proyek Anda. Mulailah memanfaatkan kekuatan queueing dengan Horizon dan rasakan perbedaannya dalam performa dan manajemen aplikasi Anda!
TAGS: Laravel Horizon, Queue, Redis, Background Jobs, PHP, Developer Tools, Laravel, Worker, Supervisor, Monitoring

