Ketika worker Laravel tersendat, backlog job bertambah sementara cache bisa kehilangan konsistensi dan lock menyumbat proses lain. Artikel ini langsung membahas cara mendiagnosis kasus tersebut, memperbaiki konfigurasi queue/cache, serta menambahkan strategi locking dan observability agar sistem kembali stabil.
Mendiagnosis Worker Tersendat dan Dampaknya
Masalah umum muncul ketika queue worker berhenti, retry tak terkendali terjadi, atau job masuk ke status failed karena timeout. Langkah diagnostik yang praktis adalah:
- Jalankan
php artisan queue:faileduntuk melihat job yang sudah gagal dan isi error message agar tahu apakah timeout atau exception terjadi. - Periksa panjang antrian dengan driver yang digunakan. Untuk Redis, periksa key job dengan
redis-cli LLEN queues:default. - Amati log worker (biasanya lewat Supervisor atau systemd) untuk melihat apakah ada stack trace repetitif atau worker timeout.
- Pastikan tidak ada job yang menunggu lock/koneksi eksternal; job yang memanggil API eksternal panjang tanpa >timeout bisa membuat worker stuck.
Jika retry tak terkendali, cek nilai retry_after dan pastikan job tidak menyala lagi sebelum selesai benar-benar selesai. Untuk driver Redis, block_for juga memengaruhi bagaimana worker memanggil job berikutnya.
Menstabilkan Queue dan Cache
Konfigurasi Queue Driver yang Tahan Gangguan
Gunakan konfigurasi queue di config/queue.php yang menjamin job tidak terlupakan ketika worker mati:
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => 3,
],
Setting retry_after harus lebih besar dari waktu eksekusi job paling lama. block_for membantu worker menunggu job baru sebelum polling lagi, mengurangi tekanan pada Redis saat tidak ada job.
Cache Store yang Konsisten
Pilih cache store yang mendukung atomic operations, seperti Redis atau Memcached. Di config/cache.php, pastikan koneksi diarahkan ke instance yang sama dengan queue:
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
],
Gunakan cache untuk menyimpan status job penting (misal: flag bahwa suatu batch sudah berjalan) dan bersihkan flag itu di akhir job atau saat terjadi exception. Pastikan job selalu menghapus flag di blok finally untuk mencegah deadlock cache.
Strategi Lock dan Pencegahan Deadlock
Pada job yang harus berjalan satu-satu (misal migrasi data), manfaatkan Redis lock dari Cache::lock. Contohnya:
use Illuminate\Support\Facades\Cache;
$lock = Cache::lock('process-batch', 120);
if ($lock->get()) {
try {
// jalankan job kritikal
} finally {
$lock->release();
}
} else {
// log atau requeue karena lock sedang digunakan
}
Durasi lock harus cukup untuk menyelesaikan job. Jika job bisa gagal dan butuh retry, gunakan block(10) untuk menunggu lock sebelum memutuskan fail. Hindari mengunci terlalu lama agar worker lain tidak menunggu selamanya.
Untuk job yang mengandalkan cache store biasa, implementasikan retry dengan backoff kecil dan pastikan cache store mendukung operasi atomic seperti add atau setnx.
Observability dan Alert Dasar
Observability sederhana sudah cukup untuk mencegah backlog makin parah. Terapkan:
- Metrics Queue Length: Kirim nilai dari Redis LLEN ke dashboard Prometheus/Grafana atau cukup catat dengan
php artisan queue:work --tries=1dan parsing log. - Alert Failed Job: Tambah listener pada
Illuminate\Queue\Events\JobFaileduntuk mengirim notifikasi Slack/Email ketika job penting gagal. - Supervisor Restart: Gunakan Supervisor dengan konfigurasi seperti ini untuk otomatis restart worker jika berhenti:
[program:laravel-worker] command=php /var/www/artisan queue:work redis --sleep=3 --tries=3 numprocs=1 autostart=true autorestart=true redirect_stderr=true stdout_logfile=/var/www/storage/logs/worker.log
Untuk tambahan, buat endpoint health check yang memeriksa koneksi Redis dan database. Monitoring sederhana ini memungkinkan deteksi dini saat worker sudah tertinggal job.
Ringkasan dan Tindakan Cepat
Ketika worker tersendat, diagnosis awal melalui log, job failed, dan status Redis adalah langkah paling cepat. Setelah itu, stabilkan konfigurasi queue/cache, pastikan job kritikal dilindungi lock, serta tambahkan observability sederhana agar tim bisa bereaksi sebelum backlog menjadi kritis. Implementasi praktis yang konsisten mampu menjaga sistem queue Laravel tetap handal meskipun beban tinggi.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!