Laravel Queue Job: Cara Membuat dan Menjalankan Background Job
Apa Itu Laravel Queue?
Laravel Queue adalah fitur Laravel yang digunakan untuk menjalankan pekerjaan atau task secara asynchronous di background.
Tanpa Queue, misalnya user melakukan request untuk mengirim 100 email:
User
↓
Laravel
↓
Kirim 100 Email
↓
Response
User harus menunggu seluruh proses selesai.
Dengan Queue:
User
↓
Laravel
↓
Masukkan Job ke Queue
↓
Response Cepat
│
↓
Queue Worker
↓
Proses Job
Dengan pendekatan ini, task yang membutuhkan waktu lama dapat dipindahkan dari request utama ke background.
Contoh pekerjaan yang cocok menggunakan Queue:
- Mengirim email
- Memproses gambar
- Membuat laporan
- Mengirim notifikasi
- Memanggil API eksternal
- Import data
- Export data
- Memproses file
- Menjalankan proses yang membutuhkan waktu lama
Kenapa Laravel Queue Dibutuhkan?
Bayangkan sebuah halaman checkout melakukan beberapa proses:
Checkout
↓
Simpan Order
↓
Kirim Email
↓
Generate Invoice
↓
Kirim Notifikasi
↓
Update Statistik
↓
Response
Jika semua proses dilakukan dalam satu HTTP request, response dapat menjadi lambat.
Dengan Queue, prosesnya dapat dipisahkan:
Checkout
↓
Simpan Order
↓
Dispatch Jobs
↓
Response
Kemudian:
Queue Worker
├── SendOrderEmail
├── GenerateInvoice
├── SendNotification
└── UpdateStatistics
User tidak perlu menunggu semua pekerjaan tersebut selesai.
Bagaimana Laravel Queue Bekerja?
Laravel Queue menggunakan beberapa komponen utama:
Laravel Application
↓
Dispatch Job
↓
Queue Backend
↓
Queue Worker
↓
Handle Job
Ada tiga bagian penting:
- Job — mendefinisikan pekerjaan yang harus dilakukan.
- Queue backend — tempat job menunggu untuk diproses.
- Queue Worker — proses yang mengambil job dan menjalankannya.
Queue backend dapat menggunakan beberapa driver, seperti database, Redis, Amazon SQS, dan driver lain yang tersedia sesuai versi Laravel.
Apa Itu Laravel Job?
Job adalah class yang berisi pekerjaan yang ingin diproses oleh Queue.
Contohnya kita ingin mengirim email setelah user melakukan registrasi.
Kita dapat membuat Job:
php artisan make:job SendWelcomeEmail
Laravel akan membuat file Job, biasanya di:
app/Jobs/SendWelcomeEmail.php
Struktur sederhananya:
<?php
namespace App\Jobs;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class SendWelcomeEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle(): void
{
// Proses job
}
}
Struktur trait atau namespace dapat sedikit berbeda tergantung versi Laravel.
Hal yang paling penting adalah Job mengimplementasikan:
ShouldQueue
Dengan begitu Laravel mengetahui bahwa Job tersebut memang dimaksudkan untuk diproses melalui Queue.
Membuat Laravel Queue Job dari Nol
Sebagai contoh, kita akan membuat Job untuk memproses pesanan.
Jalankan:
php artisan make:job ProcessOrder
Kemudian edit:
app/Jobs/ProcessOrder.php
Contoh sederhana:
<?php
namespace App\Jobs;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
class ProcessOrder implements ShouldQueue
{
use Queueable;
public function handle(): void
{
// Proses order
}
}
Sekarang kita memiliki Job yang siap dimasukkan ke Queue.
Menambahkan Data ke dalam Job
Biasanya Job membutuhkan data.
Misalnya kita ingin mengirim Order ke Job.
<?php
namespace App\Jobs;
use App\Models\Order;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
class ProcessOrder implements ShouldQueue
{
use Queueable;
public function __construct(
public Order $order
) {}
public function handle(): void
{
// Proses order
}
}
Kemudian Job dapat di-dispatch dengan:
ProcessOrder::dispatch($order);
Laravel akan menyimpan informasi yang diperlukan untuk Job tersebut ke queue.
Laravel juga menangani serialisasi model yang diberikan kepada Job.
Namun, hindari memasukkan data yang sangat besar ke dalam Job.
Lebih baik membawa identifier yang diperlukan dan mengambil data kembali ketika Job dijalankan jika memang sesuai dengan kebutuhan aplikasi.
Apa Itu handle() pada Laravel Job?
Method:
public function handle(): void
adalah tempat utama pekerjaan Job dilakukan.
Contohnya:
public function handle(): void
{
$order = $this->order;
// Proses order
}
Ketika Queue Worker mengambil Job tersebut, Laravel akan menjalankan handle().
Secara sederhana:
Queue
↓
ProcessOrder
↓
handle()
↓
Selesai
Menjalankan Job dengan dispatch()
Setelah Job dibuat, kita perlu memasukkannya ke Queue.
Contohnya:
ProcessOrder::dispatch($order);
Laravel kemudian memasukkan Job tersebut ke queue backend.
Jika Worker sedang berjalan, Job akan diambil dan diproses.
Dispatch Job dari Controller
Misalnya:
use App\Jobs\ProcessOrder;
public function store()
{
$order = Order::create([
// data order
]);
ProcessOrder::dispatch($order);
return redirect()
->route('orders.show', $order)
->with('success', 'Order berhasil dibuat.');
}
Dengan Queue, controller tidak perlu menjalankan seluruh proses berat secara langsung.
Contoh Job Mengirim Email
Misalnya kita memiliki Job:
<?php
namespace App\Jobs;
use App\Mail\WelcomeMail;
use App\Models\User;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Mail;
class SendWelcomeEmail implements ShouldQueue
{
use Queueable;
public function __construct(
public User $user
) {}
public function handle(): void
{
Mail::to($this->user->email)
->send(new WelcomeMail($this->user));
}
}
Kemudian dispatch:
SendWelcomeEmail::dispatch($user);
User tidak perlu menunggu proses pengiriman email selesai sebelum mendapatkan response.
Queue Driver Laravel
Laravel membutuhkan queue backend untuk menyimpan Job sebelum diproses Worker.
Beberapa driver yang umum digunakan:
| Driver | Cocok Untuk |
|---|---|
sync | Development atau testing sederhana |
database | Aplikasi sederhana |
redis | Aplikasi yang membutuhkan Queue cepat |
sqs | Infrastruktur cloud |
beanstalkd | Kebutuhan Queue tertentu |
Pilihan driver tergantung kebutuhan aplikasi dan infrastruktur.
Untuk aplikasi Laravel yang sudah menggunakan Redis, Redis Queue sering menjadi pilihan yang praktis.
Queue Driver sync
Driver sync menjalankan Job secara langsung dalam request yang sama.
Contohnya:
QUEUE_CONNECTION=sync
Walaupun kita menggunakan:
ProcessOrder::dispatch($order);
Job tetap akan diproses langsung.
Artinya:
Request
↓
Dispatch Job
↓
handle()
↓
Response
Bukan:
Request
↓
Dispatch Job
↓
Response
↓
Worker
Karena itu, sync tidak memberikan keuntungan background processing.
Driver ini berguna untuk development atau testing sederhana.
Queue dengan Database
Laravel dapat menggunakan database sebagai queue backend.
Contohnya:
QUEUE_CONNECTION=database
Laravel kemudian menyimpan Job ke tabel queue.
Jika tabel queue belum tersedia, migration queue dapat dibuat sesuai versi Laravel yang digunakan.
Pada versi Laravel tertentu, command yang tersedia adalah:
php artisan make:queue-table
Kemudian jalankan:
php artisan migrate
Setelah itu database memiliki tabel untuk menyimpan Job yang menunggu diproses.
Strukturnya secara konsep:
Laravel
↓
jobs table
↓
Queue Worker
↓
handle()
Queue dengan Redis
Jika Redis sudah digunakan dalam aplikasi Laravel, Redis juga dapat digunakan sebagai Queue backend.
.env dapat menggunakan:
QUEUE_CONNECTION=redis
Redis kemudian menjadi tempat Laravel menyimpan Job yang menunggu diproses.
Arsitekturnya:
Laravel
│
├── Cache ──→ Redis
│
├── Session → Redis
│
└── Queue ──→ Redis
Penggunaan Redis untuk Queue akan sangat membantu ketika aplikasi memiliki banyak background job.
Namun, cache, session, dan queue memiliki workload berbeda. Untuk aplikasi production yang besar, perhatikan memory, throughput, monitoring, dan isolasi workload Redis.
Menggunakan Redis sebagai Queue Backend
Jika Redis sudah terpasang, konfigurasi sederhana dapat berupa:
QUEUE_CONNECTION=redis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
Pastikan Redis berjalan:
redis-cli ping
Hasil yang diharapkan:
PONG
Kemudian bersihkan konfigurasi Laravel jika diperlukan:
php artisan config:clear
Menjalankan Queue Worker
Job tidak akan diproses hanya dengan melakukan dispatch.
Kita membutuhkan Queue Worker.
Untuk menjalankan Worker:
php artisan queue:work
Worker akan terus berjalan dan mengambil Job dari Queue.
Secara sederhana:
Queue
│
├── Job A
├── Job B
└── Job C
↓
queue:work
↓
handle()
Ketika Job selesai, Worker akan mengambil Job berikutnya.
Menguji Queue Worker
Misalnya kita memiliki:
ProcessOrder::dispatch($order);
Kemudian jalankan:
php artisan queue:work
Jika Job berhasil diproses, Worker akan menampilkan informasi pada terminal.
Untuk development, kita dapat membiarkan terminal tersebut tetap terbuka.
Jika terminal ditutup, Worker juga berhenti.
Pada production, kita membutuhkan process manager seperti Supervisor atau systemd agar Worker tetap berjalan.
queue:work vs queue:listen
Laravel memiliki beberapa command terkait Worker.
Yang umum digunakan untuk production adalah:
php artisan queue:work
queue:work menjalankan Worker sebagai proses yang terus bekerja.
Untuk development, terdapat command lain yang mungkin ditemui:
php artisan queue:listen
Namun queue:listen memiliki overhead lebih besar karena framework dapat di-boot ulang untuk setiap Job.
Untuk production, queue:work umumnya lebih sesuai karena Worker dirancang untuk berjalan terus.
Menjalankan Worker untuk Queue Tertentu
Jika aplikasi memiliki beberapa queue:
high
default
low
Kita dapat menentukan queue yang ingin diproses:
php artisan queue:work --queue=high
Untuk beberapa queue:
php artisan queue:work --queue=high,default
Urutan tersebut dapat membantu memprioritaskan Job tertentu.
Memberikan Nama Queue pada Job
Kita dapat menentukan queue:
ProcessOrder::dispatch($order)
->onQueue('orders');
Kemudian Worker:
php artisan queue:work --queue=orders
Contoh lainnya:
SendWelcomeEmail::dispatch($user)
->onQueue('emails');
Kemudian Worker khusus:
php artisan queue:work --queue=emails
Pemisahan queue dapat membantu ketika aplikasi memiliki jenis Job dengan prioritas berbeda.
Queue Priority
Misalnya aplikasi memiliki:
high
default
low
Kita dapat menjalankan:
php artisan queue:work --queue=high,default,low
Worker akan memprioritaskan queue sesuai urutan yang diberikan.
Contohnya:
high
↓
default
↓
low
Job penting dapat diproses lebih dahulu daripada Job dengan prioritas rendah.
Menentukan Delay pada Job
Tidak semua Job harus langsung diproses.
Kita dapat memberikan delay:
SendWelcomeEmail::dispatch($user)
->delay(now()->addMinutes(5));
Artinya Job baru tersedia untuk diproses setelah waktu tersebut.
Contoh penggunaan:
- Reminder email
- Notifikasi tertunda
- Follow-up
- Scheduled processing
Membatasi Percobaan Job dengan $tries
Job dapat gagal karena berbagai alasan.
Misalnya API eksternal sedang down.
Kita dapat menentukan jumlah percobaan:
class ProcessOrder implements ShouldQueue
{
public $tries = 3;
public function handle(): void
{
// proses job
}
}
Artinya Laravel dapat mencoba Job tersebut sampai tiga kali sesuai mekanisme Queue.
Menentukan Timeout Job
Job yang berjalan terlalu lama dapat menyebabkan Worker menunggu terlalu lama.
Kita dapat menentukan timeout:
public $timeout = 120;
Artinya Job memiliki batas waktu sekitar 120 detik.
Nilai yang digunakan harus disesuaikan dengan jenis pekerjaan.
Job mengirim email mungkin hanya membutuhkan beberapa detik.
Job yang melakukan export data besar mungkin membutuhkan waktu lebih lama.
Menangani Job yang Gagal
Tidak semua Job akan berhasil.
Misalnya:
Laravel
↓
Job
↓
API eksternal
↓
Connection Timeout
Laravel memiliki mekanisme untuk menangani failed jobs.
Kita dapat melihat failed jobs menggunakan:
php artisan queue:failed
Kemudian melakukan retry:
php artisan queue:retry <id>
ID tersebut berasal dari daftar failed jobs.
Membuat Failed Jobs
Konfigurasi failed jobs bergantung pada versi Laravel dan queue setup.
Jika migration failed jobs belum tersedia, Laravel menyediakan command yang sesuai dengan versi framework yang digunakan.
Pada versi Laravel tertentu:
php artisan make:queue-failed-table
Kemudian:
php artisan migrate
Pastikan selalu memeriksa command yang tersedia pada versi Laravel project:
php artisan list
Karena command queue dapat berbeda antarversi Laravel.
Method failed()
Kita juga dapat mendefinisikan method:
public function failed(?Throwable $exception): void
{
// Proses ketika Job benar-benar gagal
}
Contohnya:
public function failed(?Throwable $exception): void
{
Log::error('ProcessOrder gagal', [
'order_id' => $this->order->id,
'error' => $exception?->getMessage(),
]);
}
Method ini berguna untuk:
- Logging
- Mengirim notifikasi
- Mengubah status data
- Menandai proses sebagai gagal
Job Retry dan Idempotency
Salah satu konsep penting dalam Queue adalah idempotency.
Bayangkan Job:
Process Payment
Job gagal setelah payment sebenarnya sudah berhasil diproses, tetapi response dari payment gateway timeout.
Worker kemudian melakukan retry.
Jika Job tidak dirancang dengan baik, pembayaran dapat diproses dua kali.
Karena itu, Job yang memiliki efek samping penting harus dirancang agar aman ketika dijalankan kembali.
Contohnya gunakan unique transaction ID atau payment reference.
Konsepnya:
Job pertama
↓
Payment berhasil
↓
Response timeout
Retry
↓
Cek transaction ID
↓
Sudah diproses?
↓
Ya → Jangan proses lagi
Ini sangat penting untuk Job seperti:
- Payment
- Order
- Pengiriman email tertentu
- Sinkronisasi data
- API integration
Jangan Memasukkan Data Terlalu Besar ke Job
Hindari memasukkan collection besar:
ProcessOrders::dispatch($thousandsOfOrders);
Lebih baik pecah menjadi Job yang lebih kecil.
Contoh:
100.000 Order
↓
Batch
↓
1.000 Job
↓
Queue Worker
Pendekatan ini lebih mudah di-retry dan dimonitor.
Job Batching
Laravel juga menyediakan mekanisme batch untuk menjalankan banyak Job sebagai satu kelompok.
Konsepnya:
Batch
├── Job 1
├── Job 2
├── Job 3
└── Job 4
Batch berguna untuk proses seperti:
- Import data
- Export data
- Pemrosesan file
- Sinkronisasi banyak record
Implementasinya tergantung kebutuhan aplikasi dan versi Laravel.
Queue Middleware
Laravel menyediakan Queue middleware untuk kebutuhan tertentu.
Middleware dapat digunakan untuk:
- Rate limiting
- Prevent overlapping
- Kontrol concurrency
- Logic tertentu sebelum Job diproses
Contohnya berguna ketika API eksternal memiliki rate limit.
Daripada mengirim request terlalu cepat:
Worker
↓
API
↓
Rate Limit
kita dapat menerapkan kontrol pada Job.
Job yang Membutuhkan Dependency Injection
Laravel dapat melakukan dependency injection pada method handle().
Contohnya:
public function handle(OrderService $orderService): void
{
$orderService->process($this->order);
}
Laravel akan melakukan resolve dependency tersebut ketika Job dijalankan.
Ini membantu menjaga Job tetap fokus pada pekerjaan yang harus dilakukan.
Contoh Job yang Lebih Realistis
Misalnya kita ingin memproses order:
<?php
namespace App\Jobs;
use App\Models\Order;
use App\Services\OrderService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
class ProcessOrder implements ShouldQueue
{
use Queueable;
public $tries = 3;
public $timeout = 120;
public function __construct(
public Order $order
) {}
public function handle(OrderService $orderService): void
{
$orderService->process($this->order);
}
}
Kemudian:
ProcessOrder::dispatch($order);
Worker:
php artisan queue:work
Alurnya:
Controller
↓
dispatch()
↓
Redis
↓
Queue Worker
↓
ProcessOrder
↓
OrderService
↓
Selesai
Queue untuk Mengirim Email
Email merupakan salah satu use case Queue yang paling umum.
Contohnya:
Mail::to($user->email)
->queue(new WelcomeMail($user));
Laravel dapat memasukkan email ke queue tanpa perlu membuat Job secara manual untuk setiap kebutuhan.
Namun, pastikan konfigurasi mail dan queue sudah benar.
Jika menggunakan Queue:
Request
↓
Queue Email
↓
Response
↓
Worker
↓
Mail Server
Ini membuat request utama tidak perlu menunggu proses komunikasi dengan mail server.
Queue untuk Import Data
Misalnya user mengupload file CSV dengan 50.000 data.
Jangan memproses semuanya dalam satu HTTP request:
Upload CSV
↓
Proses 50.000 row
↓
Response
Request dapat timeout.
Lebih baik:
Upload CSV
↓
Simpan File
↓
Dispatch Import Job
↓
Response
↓
Worker
↓
Proses Data
Data dapat dipecah menjadi chunk agar memory dan waktu proses lebih terkontrol.
Queue untuk API Eksternal
Misalnya aplikasi perlu mengirim 10.000 data ke API eksternal.
Tanpa Queue:
HTTP Request
↓
10.000 API Calls
↓
Response
Ini sangat tidak ideal.
Dengan Queue:
Application
↓
10.000 Jobs
↓
Queue
↓
Workers
↓
API
Worker dapat memprosesnya secara bertahap.
Jika API memiliki rate limit, concurrency dan delay juga dapat dikontrol.
Queue Worker di Production
Di development:
php artisan queue:work
sudah cukup untuk testing.
Tetapi jangan menjalankan Worker production dengan mengandalkan terminal SSH.
Jika terminal ditutup:
SSH Disconnect
↓
Worker Stop
↓
Queue Tidak Diproses
Untuk production, Worker sebaiknya dikelola oleh process manager seperti Supervisor atau systemd.
Laravel Queue dengan Supervisor
Contoh konfigurasi Supervisor secara sederhana:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/example.com/artisan queue:work redis --sleep=3 --tries=3 --timeout=120
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/example.com/storage/logs/worker.log
stopwaitsecs=3600
Path, user, queue connection, timeout, dan jumlah Worker harus disesuaikan dengan server.
Setelah konfigurasi berubah, Supervisor perlu membaca konfigurasi terbaru.
Contohnya:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl restart laravel-worker:*
Queue Worker dan Deployment
Ada satu hal penting ketika melakukan deployment Laravel.
Queue Worker adalah proses jangka panjang.
Jika kode aplikasi berubah, Worker yang sudah berjalan dapat masih menggunakan kode yang sudah dimuat sebelumnya.
Karena itu setelah deployment, Worker perlu direstart secara graceful.
Laravel menyediakan:
php artisan queue:restart
Command tersebut memberi sinyal kepada Worker agar menyelesaikan Job yang sedang berjalan kemudian berhenti.
Process manager seperti Supervisor kemudian dapat menjalankan Worker kembali.
Alurnya:
Deploy
↓
Update Code
↓
queue:restart
↓
Worker Lama Selesai
↓
Worker Berhenti
↓
Supervisor
↓
Worker Baru
Ini merupakan bagian penting dari deployment Laravel yang menggunakan Queue.
Monitoring Queue
Jangan hanya menjalankan Queue tanpa monitoring.
Pada aplikasi Laravel, kita perlu mengetahui:
- Apakah Worker berjalan?
- Berapa banyak Job menunggu?
- Berapa banyak Job gagal?
- Apakah Job terlalu lama?
- Apakah Worker sering restart?
- Apakah Redis kehabisan memory?
- Apakah API eksternal sering timeout?
Jika menggunakan Redis, Laravel Horizon dapat digunakan untuk monitoring Queue berbasis Redis.
Horizon memberikan informasi seperti:
- Job diproses
- Job gagal
- Throughput
- Runtime
- Queue workload
Ini sangat membantu ketika aplikasi sudah menggunakan banyak background Job.
Queue Worker Tidak Berjalan?
Jika Job sudah di-dispatch tetapi tidak diproses, lakukan pengecekan berikut.
Pertama:
php artisan queue:work
Jika Job langsung diproses, berarti sebelumnya Worker belum berjalan.
Jika menggunakan Redis:
redis-cli ping
Pastikan:
PONG
Kemudian periksa konfigurasi:
QUEUE_CONNECTION=redis
Setelah perubahan .env:
php artisan config:clear
Jika menggunakan Supervisor, cek:
sudo supervisorctl status
Pastikan Worker berstatus RUNNING.
Job Berhenti atau Crash
Jika Worker berhenti tiba-tiba, periksa:
storage/logs/laravel.log
Periksa juga log Supervisor jika digunakan.
Beberapa penyebab umum:
- Memory terlalu kecil
- Job membutuhkan waktu terlalu lama
- Timeout
- Dependency error
- Redis bermasalah
- API eksternal timeout
- Bug pada kode Job
Queue Job Terlalu Lama
Jika Job membutuhkan waktu lama, jangan langsung menaikkan timeout setinggi mungkin.
Cari tahu penyebabnya.
Misalnya Job:
Process 100.000 records
mungkin lebih baik dipecah:
Process 1.000 records
Process 1.000 records
Process 1.000 records
...
Daripada satu Job yang berjalan puluhan menit.
Job yang lebih kecil biasanya lebih mudah:
- Di-retry
- Dimonitor
- Di-scale
- Di-debug
Kapan Menggunakan Laravel Queue?
Gunakan Queue jika task:
- Tidak harus selesai sebelum response
- Membutuhkan waktu lama
- Melakukan operasi eksternal
- Mengirim email
- Mengolah file
- Memproses banyak data
- Membutuhkan retry
- Dapat dijalankan asynchronous
Contoh sederhana:
User Request
↓
Simpan Data
↓
Dispatch Job
↓
Response
Kemudian:
Queue Worker
↓
Proses Background Task
Kapan Tidak Perlu Menggunakan Queue?
Tidak semua proses harus masuk Queue.
Misalnya:
$user = User::find($id);
Jika proses hanya membutuhkan beberapa milidetik, memasukkannya ke Queue justru menambah kompleksitas.
Queue cocok ketika ada alasan nyata untuk melakukan asynchronous processing.
Pertimbangkan:
- Lama proses
- Dampak terhadap response time
- Apakah task bisa dijalankan asynchronous
- Apakah task membutuhkan retry
- Apakah task memiliki efek samping penting
Best Practice Laravel Queue Job
Beberapa praktik yang sebaiknya diterapkan:
Buat Job dengan Tanggung Jawab yang Jelas
Hindari Job yang melakukan terlalu banyak hal.
Lebih baik:
SendWelcomeEmail
GenerateInvoice
ProcessOrder
SyncProduct
daripada:
DoEverythingJob
Buat Job Idempotent
Job sebaiknya aman ketika dijalankan kembali.
Terutama untuk:
- Payment
- Order
- API synchronization
- Notification
Gunakan Retry Secara Bijak
Contoh:
public $tries = 3;
Jangan memberikan retry tanpa batas untuk semua jenis error.
Tentukan Timeout
public $timeout = 120;
Sesuaikan dengan pekerjaan.
Pecah Job Besar
Gunakan chunk atau beberapa Job kecil daripada satu Job yang sangat besar.
Monitor Failed Jobs
Gunakan:
php artisan queue:failed
dan lakukan retry setelah penyebab masalah diperbaiki.
Gunakan Process Manager di Production
Jangan mengandalkan:
php artisan queue:work
dari terminal SSH untuk production.
Gunakan Supervisor atau systemd.
Contoh Arsitektur Laravel Queue dengan Redis
Untuk aplikasi Laravel yang menggunakan Redis:
User
│
↓
Laravel App
│
┌────────┴────────┐
│ │
↓ ↓
Database Redis
│
┌──────────┴──────────┐
↓ ↓
Cache Queue
│
↓
Queue Worker
│
┌───────────┼───────────┐
↓ ↓ ↓
Email API Processing
Redis dapat menangani beberapa kebutuhan sekaligus.
Tetapi semakin besar aplikasi, semakin penting untuk memperhatikan kapasitas dan workload Redis.
Kesimpulan
Laravel Queue Job memungkinkan aplikasi menjalankan pekerjaan berat atau tidak mendesak di background sehingga response kepada user dapat menjadi lebih cepat.
Konsep dasarnya sederhana:
Dispatch Job
↓
Queue Backend
↓
Queue Worker
↓
handle()
↓
Job Selesai
Contoh paling sederhana:
ProcessOrder::dispatch($order);
Kemudian Worker menjalankan:
php artisan queue:work
Untuk aplikasi yang menggunakan Redis, Queue dapat dikonfigurasi dengan:
QUEUE_CONNECTION=redis
Beberapa hal penting yang perlu diingat:
- Job harus memiliki tanggung jawab yang jelas.
- Gunakan Queue untuk pekerjaan yang memang cocok diproses asynchronous.
- Gunakan retry dan timeout dengan tepat.
- Rancang Job agar aman ketika diulang.
- Jangan memasukkan data terlalu besar ke Job.
- Monitor failed jobs.
- Gunakan Supervisor atau systemd untuk Worker production.
- Restart Worker setelah deployment.
- Jika menggunakan Redis secara intensif, pantau kapasitas dan workload-nya.
Setelah memahami dasar Laravel Queue Job, langkah berikutnya adalah memahami Laravel Queue Failed Jobs, Queue Worker dengan Supervisor, dan Laravel Horizon untuk monitoring Queue berbasis Redis.
