1 Queue for All Events #
Jika overqueue adalah terlalu banyak queue tanpa alasan yang jelas, maka kebalikannya juga bisa menjadi masalah:
Menggunakan satu queue untuk semua event dalam sistem.
Secara kasat mata, pendekatan ini terlihat bersih:
- Hanya satu queue
- Mudah dipantau
- Tidak perlu banyak konfigurasi
Namun dalam sistem yang berkembang, pola ini dapat menjadi bottleneck arsitektural yang serius.
Artikel ini membahas mengapa “one queue for all events” adalah anti-pattern dalam banyak konteks production.
“Menyederhanakan arsitektur itu baik — sampai kesederhanaan itu menghilangkan kontrol.”
Apa Itu One Queue for All Events? #
Semua event dari berbagai domain dikirim ke satu queue, misalnya:
app.events
Event yang masuk bisa berupa:
- order.created
- order.cancelled
- payment.success
- payment.failed
- user.registered
- notification.sent
Semua ditangani oleh satu atau beberapa consumer dari queue yang sama.
Mengapa Pola Ini Terlihat Menarik? #
Beberapa alasan umum:
- Sederhana
- Tidak perlu memikirkan partitioning
- Tidak perlu mendesain banyak queue
- Mudah saat sistem masih kecil
Untuk prototipe atau MVP kecil, ini mungkin cukup.
Namun pada skala menengah-besar, masalah mulai muncul.
Masalah Utama: Coupling yang Tinggi #
Jika semua event berada di satu queue:
- Semua consumer berbagi backlog yang sama
- SLA antar event menjadi bercampur
- Error satu jenis event dapat memengaruhi yang lain
Contoh:
Jika event payment mengalami retry loop, maka event order bisa ikut tertunda.
Ini disebut cross-domain interference.
SLA Tidak Bisa Dipisahkan #
Setiap jenis event bisa memiliki karakteristik berbeda:
- order.created → harus cepat
- email.notification → boleh lambat
- audit.log → boleh asynchronous
Jika semua dalam satu queue:
- Tidak bisa mengatur prefetch berbeda
- Tidak bisa mengatur retry policy berbeda
- Tidak bisa memisahkan scaling
Semua tunduk pada satu konfigurasi.
Bottleneck Skalabilitas #
Satu queue berarti:
- Satu logical bottleneck
- Scaling hanya dengan menambah consumer pada queue tersebut
Jika beban meningkat dari satu domain saja:
- Seluruh queue terdampak
Scaling granular menjadi sulit.
Risiko Poison Message Lebih Besar #
Jika satu jenis event menghasilkan poison message:
- Retry loop bisa menghambat event lain
- Queue starvation bisa terjadi
Semakin banyak domain dalam satu queue, semakin tinggi dampak kegagalan lokal.
Monitoring Menjadi Tidak Granular #
Metric seperti:
- Queue depth
- Retry rate
- DLQ rate
Tidak bisa dibedakan per domain.
Sulit menjawab pertanyaan:
“Apakah payment sedang bermasalah atau order yang bermasalah?”
Observability menjadi kabur.
Kapan Satu Queue Masih Masuk Akal? #
Tidak semua kasus satu queue adalah anti-pattern.
Masuk akal jika:
- Semua event memiliki SLA sama
- Semua event diproses dengan logic seragam
- Volume kecil
- Tidak ada kebutuhan isolasi
Namun ini jarang terjadi dalam sistem yang berkembang.
Alternatif yang Lebih Sehat #
1️⃣ Pisahkan Berdasarkan Domain #
Contoh:
- order.events
- payment.events
- notification.tasks
2️⃣ Pisahkan Berdasarkan SLA #
Contoh:
- critical.tasks
- background.tasks
3️⃣ Gunakan Topic Exchange dengan Beberapa Queue #
Gunakan routing key untuk fleksibilitas, tetapi tetap batasi jumlah queue berdasarkan kebutuhan nyata.
Perbandingan Singkat #
| Pendekatan | Kelebihan | Kekurangan |
|---|---|---|
| 1 Queue untuk Semua | Sederhana | Coupling tinggi |
| Queue per Domain | Isolasi baik | Perlu desain |
| Queue per SLA | Kontrol performa | Perlu analisis beban |
Satu queue memang sederhana, tetapi kesederhanaan yang salah bisa mahal di kemudian hari.
Prinsip Arsitektural #
Queue adalah boundary isolasi.
Jika boundary terlalu lebar:
- Gangguan menyebar
- Scaling sulit
- Monitoring tidak jelas
Jika boundary terlalu sempit:
- Overqueue terjadi
Desain yang matang berada di tengah.
Ringkasan #
“One queue for all events” menjadi anti-pattern ketika:
- Domain berbeda dicampur tanpa alasan
- SLA berbeda tidak dipisahkan
- Retry policy tidak bisa diisolasi
- Skalabilitas menjadi bottleneck
Solusi:
- Pisahkan berdasarkan domain atau SLA
- Gunakan routing dengan bijak
- Evaluasi kebutuhan isolasi secara eksplisit
Penutup #
Satu queue untuk semua event terlihat elegan dalam diagram.
Namun dalam sistem nyata yang kompleks, ia sering menjadi titik kemacetan tersembunyi.
Arsitektur yang baik bukan tentang membuat semuanya sesederhana mungkin.
Tetapi tentang membuat batas yang tepat agar kegagalan, beban, dan kompleksitas tidak menyebar tanpa kontrol.
Dalam RabbitMQ, queue adalah alat isolasi.
Menggunakannya terlalu sedikit sama berbahayanya dengan menggunakannya terlalu banyak.
Dan kebijaksanaan arsitektur sering kali terletak di antara dua ekstrem tersebut.