Message Queue adalah komponen yang memungkinkan komunikasi asinkron antar service. Producer mengirim pesan ke queue, consumer memproses pesan dari queue.
Masalah tanpa queue:
User upload foto → Server resize → Server simpan → Response ke user
(3 detik) (1 detik)
Total: 4 detik menunggu! User frustrasi.
Dengan queue:
User upload foto → Server terima → Kirim ke queue → Response: "Processing!"
↓ (instant!)
Worker resize
Worker simpan
Notifikasi: "Foto siap!"
Konsep dasar:
Producer ──→ Queue ──→ Consumer
(pengirim) (antrian) (pemroses)
- Producer — mengirim pesan ke queue
- Queue — menyimpan pesan sampai diproses
- Consumer — mengambil dan memproses pesan
- Message — data yang dikirim (biasanya JSON)
Kapan pakai message queue:
- Task yang lama — resize gambar, kirim email, generate PDF
- Spike handling — traffic tiba-tiba tinggi, queue menyerap burst
- Komunikasi antar service — decoupling microservices
- Scheduled tasks — job yang harus dijalankan nanti
- Retry logic — jika gagal, masukkan kembali ke queue
Implementasi dengan Bull (Node.js + Redis):
const Queue = require("bull");
// Buat queue
const emailQueue = new Queue("emails", "redis://localhost:6379");
// Producer: tambah job ke queue
app.post("/register", async (req, res) => {
const user = await createUser(req.body);
// Kirim email secara asinkron
await emailQueue.add("welcome-email", {
to: user.email,
name: user.name
}, {
attempts: 3, // retry 3x jika gagal
backoff: { type: "exponential", delay: 5000 }
});
res.json({ message: "Registrasi berhasil!" }); // response instant!
});
// Consumer: proses job dari queue
emailQueue.process("welcome-email", async (job) => {
const { to, name } = job.data;
await sendEmail(to, "Selamat datang, " + name + "!");
console.log("Email terkirim ke", to);
});
// Event handlers
emailQueue.on("completed", (job) => {
console.log("Job selesai:", job.id);
});
emailQueue.on("failed", (job, err) => {
console.error("Job gagal:", job.id, err.message);
});
Pola messaging:
1. Point-to-Point (Queue) Satu pesan diproses oleh satu consumer. Cocok untuk task processing.
2. Pub/Sub (Topic) Satu pesan dikirim ke semua subscriber. Cocok untuk event broadcasting.
Order Service → "order.created" → Email Service (kirim konfirmasi)
→ Inventory Service (kurangi stok)
→ Analytics Service (catat penjualan)
Dead Letter Queue (DLQ): Pesan yang gagal diproses setelah beberapa kali retry dipindahkan ke DLQ untuk investigasi manual.
Tools:
- Redis + Bull/BullMQ — sederhana, cocok untuk Node.js
- RabbitMQ — message broker yang mature dan flexible
- Apache Kafka — event streaming, throughput sangat tinggi
- AWS SQS — managed queue service dari AWS
Message queue memungkinkan sistem kamu tetap responsif dan resilient bahkan saat ada proses berat atau service yang sedang down.
🎭 Analogi sehari-hari: Restoran punya kasir (producer), buku pesanan (queue), koki (consumer). Pelanggan order ke kasir, kasir tulis di buku, koki ambil pesanan dari buku dan masak. Kasir gak nunggu koki selesai — langsung layani pelanggan berikutnya. Decoupling.
💡 Idempotency = wajib di consumer: Pesan bisa di-deliver 2x (network glitch, retry). Consumer harus pastikan proses pesan yang sama berkali-kali = sama hasilnya. Pakai unique ID, dedupe di DB, atau "idempotency key". Kalau gak, double charge / double email = bencana.
⚠️ Jebakan klasik:
- No retry strategy = job gagal sekali = data hilang. Wajib retry + DLQ
- Tidak idempotent = retry = double charge / double processing
- Pesan terlalu besar (>1MB) = queue lambat. Simpan di S3, kirim reference saja
- Consumer lambat = queue backup, latency naik. Scale consumer sebelum bottleneck
- Lupa monitoring queue depth = queue meledak diam-diam, app responsive tapi worker stuck
🎯 Pilih message broker:
- Simple task queue + Redis ada → Bull/BullMQ
- Banyak topology + reliability → RabbitMQ
- Event streaming + replay + analytics → Kafka
- Cloud + managed (no ops) → SQS / Pub/Sub / Service Bus
- Real-time pub/sub UI → Redis Pub/Sub atau WebSocket
TL;DR: Message Queue = decouple producer & consumer + buffer untuk burst + retry resilience. Wajib idempotent consumer + DLQ + monitoring. P2P = task processing. Pub/Sub = event broadcast. Default Bull (simple) atau Kafka (event-streaming).