Definisi sebagai Kode
Seluruh topologi RabbitMQ — vhost, user, permission, exchange, queue, binding, policy — bisa diekspor menjadi satu berkas JSON dan dimuat kembali saat broker start.
# ekspor
rabbitmqctl export_definitions /tmp/definitions.json
# atau lewat HTTP API
curl -s -u admin:rahasia http://localhost:15672/api/definitions \
| jq 'del(.users[].password_hash)' > definitions.json
# muat saat start (rabbitmq.conf)
# load_definitions = /etc/rabbitmq/definitions.jsonHasil ekspor berisi password_hash untuk setiap user. Meng-commit-nya ke Git berarti menyebarkan materi kredensial ke setiap orang yang punya akses repositori dan ke seluruh riwayat commit selamanya.
# buang bagian user sebelum commit; kelola user lewat mekanisme rahasia terpisah
jq 'del(.users)' definitions.json > definitions.aman.jsonSimpan topologi (exchange, queue, binding, policy) di Git; simpan user dan password di brankas rahasia.
{
"rabbit_version": "4.0.5",
"vhosts": [{ "name": "/" }],
"permissions": [
{ "user": "svc-producer", "vhost": "/",
"configure": "^$", "write": "^pesanan$", "read": "^$" }
],
"policies": [
{ "vhost": "/", "name": "batas-antrean", "pattern": "^pesanan\\.",
"apply-to": "queues", "priority": 10,
"definition": { "max-length": 100000, "overflow": "reject-publish" } }
],
"exchanges": [
{ "name": "pesanan", "vhost": "/", "type": "topic",
"durable": true, "auto_delete": false,
"arguments": { "alternate-exchange": "pesanan.tak-terkirim" } }
],
"queues": [
{ "name": "pesanan.email", "vhost": "/", "durable": true,
"auto_delete": false,
"arguments": {
"x-queue-type": "quorum",
"x-dead-letter-exchange": "pesanan.dlx",
"x-delivery-limit": 5
} }
],
"bindings": [
{ "source": "pesanan", "vhost": "/", "destination": "pesanan.email",
"destination_type": "queue", "routing_key": "pesanan.*.dibuat",
"arguments": {} }
]
}Apa yang Perlu Dibackup
| Aset | Cara | Frekuensi |
|---|---|---|
| Definisi topologi | export_definitions | Setiap perubahan, dan harian |
| Isi pesan | Tidak dibackup | — |
| Erlang cookie | Brankas rahasia | Sekali, saat dibuat |
| Konfigurasi | Git | Setiap perubahan |
Pesan bersifat sementara secara desain. Bila kehilangan isi queue tidak dapat diterima, sumber kebenarannya seharusnya ada di basis data (pola outbox, bab 9), bukan di broker.
Menyalin direktori data RabbitMQ saat broker berjalan menghasilkan berkas yang tidak konsisten dan tidak bisa dipulihkan dengan andal.
Prosedur Upgrade
Prasyarat:
• semua queue penting bertipe quorum (classic queue tidak tersedia
selama node-nya mati)
• klien punya reconnect yang teruji
• ekspor definisi sudah tersimpan
Langkah untuk setiap node, satu per satu:
1. rabbitmq-upgrade drain → node masuk maintenance mode,
koneksi dipindahkan
2. tunggu quorum queue memindahkan leader keluar dari node ini
3. hentikan node, ganti versi, jalankan kembali
4. rabbitmq-upgrade revive
5. rabbitmqctl cluster_status → pastikan bergabung kembali
6. tunggu replika quorum tersinkron penuh
7. baru lanjut ke node berikutnya- Rolling upgrade umumnya didukung antar versi minor yang berdekatan.
- Untuk lompatan versi mayor, baca panduan resmi — sering diperlukan upgrade bertahap, bukan langsung.
- RabbitMQ 4.0 menghapus classic queue mirroring. Migrasikan ke quorum queue sebelum upgrade, bukan sesudah.
- Versi Erlang juga punya syarat minimum tersendiri.
Runbook Troubleshooting
GEJALA: publish menggantung tanpa error
→ rabbitmq-diagnostics alarms
→ alarm memori/disk aktif? Kurangi antrean, tambah kapasitas disk.
→ tidak ada alarm? Periksa state koneksi: flow atau blocked.
GEJALA: queue menumpuk terus
→ rabbitmqctl list_queues name messages_ready messages_unacknowledged consumers
→ consumers = 0 : konsumer mati atau gagal reconnect
→ unacked ≈ prefetch: konsumer terlalu lambat, tambah instance
→ unacked tinggi dan diam: konsumer menggantung, periksa thread dump
GEJALA: pesan hilang tanpa jejak
→ periksa binding: rabbitmqctl list_bindings
→ periksa queue alternate-exchange
→ periksa DLQ dan header x-death
→ apakah publisher confirm dipakai?
GEJALA: pesan diproses berkali-kali
→ apakah konsumer idempoten?
→ apakah ack dikirim setelah pemrosesan selesai?
→ apakah pemrosesan lebih lama dari consumer_timeout broker?
GEJALA: konsumer diputus dengan "consumer timeout"
→ pemrosesan melebihi consumer_timeout (default 30 menit)
→ pecah menjadi tugas lebih kecil, atau naikkan batasnya:
consumer_timeout = 3600000 (rabbitmq.conf, dalam milidetik)
GEJALA: cluster tidak terbentuk
→ md5sum .erlang.cookie di setiap node — harus identik
→ port 4369 (epmd) dan 25672 (distribusi) terbuka?
→ resolusi hostname antar node berhasil?consumer_timeout: penyebab redelivery yang membingungkanSejak RabbitMQ 3.8.15, broker memutus konsumer yang tidak mengirim ack dalam 30 menit. Pesan dikembalikan ke queue dan diproses ulang.
Bagi tugas yang memang panjang — konversi video, laporan besar — gejalanya adalah pekerjaan yang terus berulang tanpa pernah selesai, tanpa error yang jelas di sisi aplikasi. Naikkan consumer_timeout, atau lebih baik lagi pecah pekerjaan menjadi bagian yang lebih kecil.
Pemeliharaan Rutin
| Kegiatan | Frekuensi |
|---|---|
| Ekspor definisi ke Git | Setiap perubahan |
| Tinjau isi DLQ | Harian |
| Audit user dan permission | Bulanan |
| Hapus queue yang tidak dipakai | Bulanan |
| Uji reconnect dan failover | Per kuartal |
| Upgrade versi minor | Per kuartal |
| Uji pemulihan dari definisi | Per kuartal |
Penutup: Tanda Instalasi RabbitMQ yang Dewasa
- Seluruh topologi ada di Git dan dimuat lewat
load_definitions. - Semua queue penting bertipe quorum dengan
x-delivery-limit. - Setiap queue punya batas panjang, TTL, dan DLX.
- Setiap DLQ dipantau dan punya pemilik.
- Producer memakai publisher confirms; pesan penting lahir dari tabel outbox.
- Konsumer idempoten, dengan prefetch yang disetel sadar dan graceful shutdown.
- User
guestsudah dihapus; tiap layanan punya izin berpola sempit. - Reconnect klien pernah diuji dengan mematikan broker di tengah beban.
- Alert terpasang untuk alarm broker, queue tanpa konsumer, dan DLQ tidak kosong.