Memahami task queue (Bull/Beanstalkd), message broker (RabbitMQ), event streaming (Apache Kafka), dead-letter queue, retry strategy, serta kapan menggunakan async processing untuk decouple services dan buffer burst traffic

Setelah di episode 5 kita memahami database indexing dan query optimization, pada episode ini kita masuk ke komponen infrastruktur yang mengubah synchronous systems menjadi asynchronous: message queue dan event streaming. Dua konsep ini adalah jantung dari microservices, event-driven architecture, dan hampir semua sistem yang perlu handle traffic burst atau decouple services.
Bayangkan sistem e-commerce: saat user checkout, order harus disimpan, inventory dikurangi, email dikirim, dan analytics dicatat. Jika semua dilakukan synchronous (satu per satu), checkout menjadi lambat dan semua layanan tightly coupled. Dengan message queue, checkout hanya menyimpan order lalu emit event — layanan lain memproses async. Inilah yang membuat sistem bisa scale dan resilient.
Task queue menyimpan tugas-tugas yang harus diproses oleh worker secara async.
Producer → Queue → Worker → Process task
↓
Failed → Retry (max 3x) → Dead Letter QueueSimple, cepat, dan lightweight. Interface: put, reserve, delete. Cocok untuk job queue yang tidak butuh fitur kompleks.
RabbitMQ adalah message broker yang mendukung berbagai model routing.
| Model | Cara Kerja | Contoh |
|---|---|---|
| Direct | Routing key exact match | order.created → notification worker |
| Fanout | Broadcast ke semua queue | Log event → semua consumer |
| Topic | Wildcard routing (*, #) | order.* → semua event order |
| Headers | Berdasarkan message headers | Priority queue |
Pesan yang gagal diproses (retry habis) dikirim ke DLQ untuk investigasi manual.
Queue → Worker → Gagal 3x → DLQ → Alert → Developer investigasi| Strategy | Penjelasan | Kapan Pakai |
|---|---|---|
| Fixed interval | Retry tiap N detik | Simple tasks |
| Exponential backoff | Retry dengan interval meningkat | Network-dependent tasks |
| Exponential + jitter | Backoff + randomness | Mengurangi thundering herd |
Kafka bukan sekadar message queue — ia adalah distributed event streaming platform yang menyimpan events secara persisten.
Producer → Topic (Partition 0, 1, 2) → Consumer Group
↓
Partition → log append-only (persistent)| Konsep | Penjelasan |
|---|---|
| Topic | Kategori events (contoh: order-events) |
| Partition | Sub-divisi topic untuk parallelism |
| Consumer Group | Sekumpulan consumer yang share beban |
| Offset | Posisi consumer dalam partition |
| Aspek | Kafka | RabbitMQ |
|---|---|---|
| Model | Event streaming (persistent log) | Message broker (queue) |
| Retention | Long-term (days/years) | Hingga consumed |
| Replay | Bisa replay dari offset tertentu | Tidak bisa |
| Throughput | Sangat tinggi (jutaan msg/detik) | Tinggi (ratusan ribu msg/detik) |
| Use case | Event sourcing, log aggregation, real-time analytics | Task queues, RPC, simple messaging |
Topic: orders (4 partitions)
Consumer Group A:
Consumer 1 → Partition 0, 1
Consumer 2 → Partition 2, 3Jika consumer crash, partition dialihkan ke consumer lain dalam group yang sama. Offset disimpan untuk melanjutkan dari terakhir diproses.
Kafka mendukung exactly-once semantics lewat:
| Skenario | Rekomendasi |
|---|---|
| Job processing (email, image resize) | Queue (Bull/RabbitMQ) |
| Inter-service communication | Queue atau streaming |
| Event sourcing (audit trail) | Kafka (persistent, replayable) |
| Real-time analytics | Kafka (high throughput) |
| Simple async task | Queue (RabbitMQ/Bull) |
| Log aggregation | Kafka (persistent, scalable) |
1. User POST /orders → API save order ke DB → emit "order.created" ke Kafka
2. Inventory Worker: kurangi stock → emit "inventory.reserved"
3. Payment Worker: proses pembayaran → emit "payment.processed"
4. Notification Worker: kirim email "order confirmed"Setiap worker berjalan async dan independently — jika notification service down, order tetap diproses. Worker lain memproses event saat service recovery.
Note
Dalam production, selalu set timeout pada consumer dan retry limit. Consumer yang memproses terlalu lama (stuck) akan memblok queue. Gunakan visibility timeout untuk memastikan message yang gagal diproses kembali ke queue.
Inti yang harus dibawa pulang:
Di episode 7 selanjutnya kita akan membahas API design & best practices — REST, GraphQL, gRPC, rate limiting, dan kapan menggunakan masing-masing. API adalah kontrak antara frontend dan backend — desain yang baik mengurangi friction dan mempercepat development!