Message Queue — System Design

Message Queue adalah komponen yang memungkinkan komunikasi asinkron antar service. Producer mengirim pesan ke queue, consumer memproses pesan dari queue. Masala

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)

Kapan pakai message 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:

Message queue memungkinkan sistem kamu tetap responsif dan resilient bahkan saat ada proses berat atau service yang sedang down.

<title>Message Queue Topologies</title> Point-to-Point (Queue) Producer Queue Worker 1 Worker 2 Worker 3 Satu pesan = diproses oleh SATU worker Pub/Sub (Topic Fanout) Publisher Topic Email Analytics Inventory Satu pesan = dikirim ke SEMUA subscriber Point-to-Point: task processing (resize, send email), load balancing antar worker Pub/Sub: broadcast event ke banyak consumer independen (order.created → email + inventory + analytics)
Point-to-point queue mendistribusikan pesan ke worker (satu pesan diproses satu kali). Pub/Sub topic fanout mengirim pesan yang sama ke setiap subscriber.

🎭 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:

🎯 Pilih message broker:

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).