Consumer #
Jika producer adalah titik awal sistem messaging, maka consumer adalah tempat nilai bisnis benar-benar diciptakan.
Di sinilah:
- Logic dijalankan
- Database diubah
- Email dikirim
- Transaksi diproses
Namun consumer bukan sekadar “pembaca queue”.
Cara consumer dirancang menentukan:
- Apakah message hilang atau tidak
- Apakah duplicate terjadi
- Apakah sistem overload
- Apakah ordering tetap terjaga
Artikel ini membahas consumer dalam konteks RabbitMQ production system secara mendalam.
“Mengirim pesan itu mudah. Memprosesnya dengan benar, aman, dan konsisten — itu yang sulit.”
Apa Itu Consumer? #
Consumer adalah aplikasi atau komponen yang:
- Berlangganan (subscribe) ke queue
- Menerima message dari broker
- Memproses message
- Memberikan acknowledgement (ack)
Berbeda dengan producer yang publish ke exchange, consumer membaca langsung dari queue.
Model Delivery pada RabbitMQ #
RabbitMQ menggunakan model push-based.
Artinya:
- Broker mendorong message ke consumer
- Consumer tidak perlu polling terus-menerus
1. Diagram Delivery ke Consumer #
Producer → Exchange → Queue → Consumer
|
v
Ack / Nack
Consumer menerima message dan harus menentukan nasibnya.
Acknowledgement (Ack) #
Secara default, RabbitMQ menggunakan at-least-once delivery.
Artinya:
- Message dianggap selesai hanya setelah consumer mengirim ack
Flow sederhananya:
- Broker kirim message
- Consumer proses
- Consumer kirim ack
- Broker hapus message dari queue
Jika consumer tidak mengirim ack:
- Message tetap dianggap belum selesai
- Bisa di-requeue jika connection terputus
Manual Ack vs Auto Ack #
Auto Ack #
- Message dianggap selesai saat dikirim
- Risiko kehilangan message jika consumer crash
Manual Ack (Direkomendasikan) #
- Consumer mengirim ack setelah sukses memproses
- Lebih aman untuk sistem production
Auto ack hanya cocok untuk:
- Proses ringan
- Sistem non-critical
Nack dan Requeue #
Consumer bisa mengirim:
- nack (negative acknowledgement)
Dengan opsi:
- requeue = true → message dikembalikan ke queue
- requeue = false → message dibuang atau masuk DLQ
Ini penting untuk error handling dan retry strategy.
Prefetch dan Backpressure #
RabbitMQ memungkinkan pengaturan prefetch.
Prefetch menentukan:
- Berapa banyak unacked message yang boleh diterima consumer sekaligus
Contoh:
prefetch = 10
Artinya consumer hanya menerima maksimal 10 message yang belum di-ack.
Ini mencegah:
- Overload memory
- Message menumpuk di satu consumer
Prefetch adalah mekanisme backpressure di sisi consumer.
Parallel Consumer dan Ordering #
Jika ada banyak consumer pada satu queue:
- Message didistribusikan secara round-robin
- Ordering global tidak dijamin
Ordering hanya terjaga jika:
- Single consumer
- Tidak ada requeue
Desain harus mempertimbangkan apakah ordering penting atau tidak.
Idempotency: Kewajiban Consumer #
Karena RabbitMQ adalah at-least-once:
- Duplicate message bisa terjadi
Consumer harus idempotent.
Artinya:
- Jika message diproses dua kali, hasil tetap konsisten
Strategi umum:
- Gunakan message_id unik
- Simpan log pemrosesan
- Gunakan unique constraint di database
Mengabaikan idempotency adalah kesalahan fatal dalam sistem asynchronous.
Error Handling Strategy #
Consumer harus memiliki strategi jelas:
Retry Langsung #
- nack dengan requeue = true
Risiko:
- Infinite retry
Dead Letter Exchange (DLX) #
- Message gagal diarahkan ke DLQ
- Diproses terpisah
Retry dengan Delay (TTL + DLX) #
- Message dikirim ke retry queue
- Kembali setelah delay
Desain retry harus disengaja.
Consumer Crash Scenario #
Jika consumer crash sebelum ack:
- Broker mendeteksi connection closed
- Message unacked di-requeue
- Dikirim ke consumer lain
Ini bagian dari fault tolerance RabbitMQ.
Namun bisa menyebabkan duplicate processing.
Scaling Consumer #
Untuk meningkatkan throughput:
- Tambahkan instance consumer
- Gunakan container orchestration (misalnya Kubernetes)
RabbitMQ otomatis mendistribusikan message.
Namun perlu mempertimbangkan:
- Database contention
- Resource limit
- Ordering requirement
Kesalahan Umum pada Consumer #
Tidak Menggunakan Manual Ack #
Risiko kehilangan message.
Tidak Mengatur Prefetch #
Consumer bisa menerima terlalu banyak message.
Tidak Idempotent #
Duplicate menyebabkan inkonsistensi data.
Retry Tanpa Batas #
Queue bisa tersumbat oleh poison message.
Ringkasan #
| Aspek | Peran Consumer |
|---|---|
| Ack | Menentukan message selesai |
| Prefetch | Kontrol backpressure |
| Nack | Error handling |
| Idempotency | Hindari duplicate impact |
| Scaling | Horizontal dengan multiple instance |
Penutup #
Consumer adalah tempat sistem asynchronous benar-benar diuji.
RabbitMQ menyediakan mekanisme:
- Ack
- Requeue
- DLX
- Prefetch
Namun tanggung jawab utama tetap pada desain consumer.
Dalam sistem messaging, producer bisa ceroboh dan sistem masih bertahan.
Tetapi jika consumer salah desain, konsekuensinya bisa berupa:
- Duplicate transaksi
- Data inkonsisten
- Queue menumpuk
- Sistem lumpuh
Karena pada akhirnya, nilai bisnis tidak tercipta saat pesan dikirim — tetapi saat pesan diproses dengan benar.