Design First #
RabbitMQ sangat mudah digunakan.
Kita bisa:
- Membuat queue dalam hitungan detik
- Publish message dalam beberapa baris kode
- Menghubungkan producer dan consumer dengan cepat
Kemudahan ini sering menjadi jebakan.
Banyak sistem RabbitMQ dibangun dengan pendekatan:
“Kita buat dulu, nanti kalau ada masalah baru kita rapikan.”
Inilah kebalikan dari best practice.
Dalam sistem messaging, desain harus didahulukan sebelum implementasi.
Artikel ini membahas mengapa pendekatan design first sangat penting dalam arsitektur RabbitMQ.
“Masalah terbesar dalam sistem messaging jarang berasal dari syntax — tetapi dari desain yang tidak pernah benar-benar dipikirkan.”
Mengapa Messaging Lebih Sensitif terhadap Desain? #
Dalam sistem synchronous:
- Error langsung terlihat
- Request gagal segera diketahui
Dalam sistem asynchronous:
- Message bisa tertunda
- Error bisa tersembunyi di DLQ
- Retry bisa terjadi diam-diam
- Ordering bisa berubah tanpa disadari
Kesalahan desain sering baru terlihat saat sistem sudah besar.
Itulah sebabnya design first sangat penting.
Apa Saja yang Harus Didisain Terlebih Dahulu? #
Sebelum menulis kode producer atau consumer, tentukan:
1️⃣ Kontrak Event #
- Apa nama routing key?
- Apa struktur payload?
- Apakah versioned?
- Siapa pemilik event?
Event adalah API antar service. Ia harus didokumentasikan seperti API HTTP.
2️⃣ Topologi Exchange & Queue #
- Tipe exchange apa yang digunakan?
- Berapa queue yang dibutuhkan?
- Apakah berdasarkan domain atau SLA?
- Apakah perlu isolation?
Tanpa desain topologi, sistem akan tumbuh secara organik dan tidak terkendali.
3️⃣ Retry & DLQ Strategy #
- Apakah menggunakan retry queue?
- Apakah exponential backoff?
- Berapa batas retry?
- Apakah ada DLQ final?
Retry bukan keputusan implementasi. Ia adalah keputusan arsitektural.
4️⃣ Ordering Requirement #
- Apakah ordering penting?
- Per entity atau global?
- Apakah perlu partitioning manual?
Ordering yang tidak dirancang akan menjadi sumber bug paling mahal.
5️⃣ Delivery Guarantee #
- At-most-once?
- At-least-once?
- Apakah consumer idempotent?
RabbitMQ default adalah at-least-once. Jika tidak dirancang, duplicate bisa merusak data.
6️⃣ Backpressure & Scaling Model #
- Bagaimana scaling consumer?
- Apakah perlu rate limiting?
- Bagaimana menangani overload?
Tanpa desain ini, sistem akan runtuh saat traffic naik.
Dampak Tidak Design First #
Beberapa gejala umum sistem tanpa desain matang:
- Queue bertambah tanpa kontrol
- Tidak ada DLQ
- Retry tidak dibatasi
- Routing key tidak konsisten
- Consumer tidak idempotent
- Monitoring tidak jelas
Sistem terlihat berjalan. Namun rapuh.
Design First ≠ Overengineering #
Design first bukan berarti membuat diagram kompleks tanpa akhir.
Ia berarti:
- Memahami kebutuhan
- Menentukan boundary
- Mendokumentasikan kontrak
- Menentukan strategi kegagalan
Desain yang sederhana tetapi jelas jauh lebih baik daripada implementasi cepat tanpa arah.
Prinsip Design First dalam RabbitMQ #
1️⃣ Mulai dari Domain, Bukan dari Queue #
Tanyakan:
- Event apa yang terjadi dalam domain ini?
- Siapa yang berhak memproduksi?
- Siapa yang berhak mengonsumsi?
Queue adalah konsekuensi desain domain.
2️⃣ Dokumentasikan Kontrak Event #
Gunakan:
- JSON schema
- Versioning
- Naming convention konsisten
Event contract adalah fondasi stabilitas jangka panjang.
3️⃣ Simulasikan Failure Scenario #
Sebelum deploy, pikirkan:
- Apa yang terjadi jika consumer crash?
- Jika dependency down?
- Jika disk penuh?
- Jika retry melebihi batas?
Arsitektur matang selalu mempertimbangkan kegagalan.
4️⃣ Pisahkan Concern #
- Database untuk state
- RabbitMQ untuk transport
- Retry untuk resilience
- Monitoring untuk observability
Campur aduk concern adalah sumber anti-pattern.
Contoh Singkat: Tanpa vs Dengan Design First #
Tanpa design first:
- Satu queue untuk semua
- Tanpa DLQ
- Tanpa retry limit
- Tanpa dokumentasi
Dengan design first:
- Queue per domain
- DLQ terpisah
- Exponential backoff
- Event contract terdokumentasi
- Monitoring jelas
Perbedaannya mungkin tidak terlihat di awal.
Tetapi akan sangat terasa saat sistem berkembang.
Ringkasan #
Design First berarti:
- Mendesain event contract
- Mendesain topologi exchange & queue
- Mendesain retry & DLQ
- Mendesain delivery guarantee
- Mendesain scaling & backpressure
Sebelum satu baris kode ditulis.
Penutup #
RabbitMQ membuat messaging terasa mudah.
Namun kemudahan ini tidak boleh membuat kita meremehkan desain.
Sistem asynchronous memiliki kompleksitas tersembunyi yang tidak langsung terlihat di permukaan.
Design first bukan formalitas. Ia adalah investasi.
Investasi untuk mencegah:
- Data loss
- Retry storm
- Bottleneck
- Arsitektur yang sulit diperbaiki
Karena dalam sistem messaging, keputusan kecil di awal bisa menjadi biaya besar di masa depan.
Dan arsitektur yang matang selalu dimulai dari desain — bukan dari kode.