Queue & Job: Pekerjaan di Latar Belakang
Memindahkan tugas lambat ke antrian: job, dispatch, worker, atribut #[Tries]/#[Timeout], dan Queue::route() di Laravel 13.
Masalah: pengguna menunggu
Mengirim email, memproses gambar, membuat laporan PDF, atau memanggil API pihak ketiga bisa memakan beberapa detik. Jika dikerjakan di dalam request, pengguna menunggu dan server tertahan. Queue memindahkan pekerjaan itu ke latar belakang: request langsung selesai, dan proses lain (worker) mengerjakan job belakangan.
Alur queue
- Aplikasi dispatch job → disimpan di queue (database, Redis, SQS...).
- Worker (
php artisan queue:work) mengambil job satu per satu dan menjalankanhandle(). - Gagal? Dicoba ulang sesuai aturan; bila tetap gagal masuk tabel
failed_jobs.
Driver bawaan proyek baru: database (paling mudah, tanpa instal apa pun); untuk skala besar pakai Redis + Horizon (dashboard & pemantauan) atau Amazon SQS.
Membuat job
php artisan make:job ProsesGambarProduk
<?php
namespace App\Jobs;
use App\Models\Produk;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Queue\Attributes\Timeout;
use Illuminate\Queue\Attributes\Tries;
#[Tries(3)] // maksimal 3 percobaan
#[Timeout(120)] // dibatalkan jika lebih dari 120 detik
class ProsesGambarProduk implements ShouldQueue
{
use Queueable;
public function __construct(public Produk $produk)
{
}
public function handle(): void
{
// buat thumbnail, kompres, dst.
}
}
implements ShouldQueue+ traitQueueablemenandai class sebagai job yang diantrikan.- Model yang dipasang di konstruktor diserialisasi sebagai ID lalu diambil ulang dari database saat job berjalan (trait
SerializesModelssudah termasuk). Kirim data kecil, bukan objek besar.
Atribut job di Laravel 13
Konfigurasi perilaku job kini bisa dengan atribut: #[Tries(5)], #[Timeout(120)], #[FailOnTimeout], #[MaxExceptions(3)], #[Backoff(...)] (jeda antar percobaan), #[DeleteWhenMissingModels] (buang job bila modelnya sudah dihapus), #[UniqueFor(3600)]. Cara lama (properti public $tries = 3;) tetap bekerja.
Mengirim (dispatch) job
ProsesGambarProduk::dispatch($produk); // standar
ProsesGambarProduk::dispatch($produk)->onQueue('gambar'); // antrian bernama
ProsesGambarProduk::dispatch($produk)->delay(now()->addMinutes(5)); // tunda
ProsesGambarProduk::dispatchSync($produk); // jalankan SEKARANG (tanpa antrian)
ProsesGambarProduk::dispatch($produk)->afterCommit(); // tunggu transaksi DB selesai
Bus::chain([new ProsesGambarProduk($produk), new KirimNotifikasi($produk)])->dispatch(); // berurutan
Queue::route() — Laravel 13
Alih-alih menulis onQueue() di setiap pemanggilan, tentukan aturan routing antrian per class di satu tempat (biasanya AppServiceProvider::boot()):
use Illuminate\Support\Facades\Queue;
Queue::route(ProsesGambarProduk::class, connection: 'redis', queue: 'gambar');
Menjalankan worker
php artisan queue:work # proses job terus-menerus
php artisan queue:work --queue=gambar,default
php artisan queue:listen # development: memuat ulang kode otomatis
php artisan queue:failed # daftar job gagal
php artisan queue:retry all # coba ulang yang gagal
php artisan queue:restart # setelah deploy kode baru
Di produksi, jaga worker tetap hidup dengan Supervisor (atau layanan terkelola seperti Laravel Cloud/Forge): worker adalah proses jangka panjang yang tidak otomatis memuat kode baru, sehingga queue:restart wajib saat deploy.
Menangani kegagalan
public function failed(\Throwable $exception): void
{
// beri tahu admin, catat log, kembalikan status data
}
Kapan memakai queue?
- Email & notifikasi, pemrosesan gambar/video, ekspor/impor besar, webhook keluar, pembuatan laporan.
- Pekerjaan harus idempoten (aman dijalankan dua kali), karena job bisa terulang.