RRabbitMQ Handbook

UZMAN

Production Checklist & Troubleshooting

Production'a çıkmadan önce "unuttuğum bir şey var mı?" kontrol listesi ve sorun olduğunda "ne yapmalıyım?" rehberi. Sırasıyla: deploy öncesi hazırlık → çalışma anı izleme → sorun giderme → güncelleme stratejisi.

Kod örneği görünümü Bu sayfadaki eşleşen örnekleri seçilen istemciye göre gösterir.

Seviye: Uzman — Production deployment ve incident response deneyimi gerektirir.

Production Lifecycle ① Pre-Deploy Cluster, TLS, DLX Disk, Memory, FD ② Runtime Monitor, Alert Scaling, Rebalance ③ Troubleshoot Alarm, Partition Consumer Stuck ④ Upgrade Rolling / Blue-Green Backup & Restore Continuous — iterate after each incident

Pre-Deploy Checklist

Managed Service Alternatifi: Self-hosted yerine CloudAMQP, AWS Amazon MQ for RabbitMQ veya Azure Service Bus (AMQP uyumlu) kullanılabilir. Trade-off: daha az operasyonel yük ama daha az kontrol (plugin kısıtlamaları, versiyon gecikmesi, maliyet). Küçük ekiplerde veya RabbitMQ ops deneyimi yoksa managed tercih edilebilir.

Konu Kontrol Risk (Skip edilirse)
Cluster size Minimum 3 node (tek sayı) Split-brain, HA yok
Queue type Production queue'ları quorum Node failure = data loss
Partition handling pause_minority aktif Split-brain veri tutarsızlığı
Disk space Quorum WAL × 3 kadar free disk Disk alarm → tüm publish durur
Memory watermark vm_memory_high_watermark.relative = 0.7 OOM kill
File descriptors > 65536 (production default) Connection refuse
Erlang cookie Tüm node'larda aynı, Secret'tan Cluster join fail
TLS Inter-node + client connections Plaintext credentials on wire
DLX configuration Her queue için DLX tanımlı Mesajlar sessizce kaybolur
Monitoring Prometheus scraping aktif Sorunları geç fark edersin
Alerting Queue depth, disk, memory alert'leri Outage'ı müşteriden öğrenirsin
Backup strategy Definitions export scheduled Cluster kaybında topology rebuild

Runtime Checklist

Konu Periyodik Kontrol
Queue depth trending Haftalık: depth artış trendi var mı?
Consumer lag Günlük: unacked count normal mi?
Connection leaks Haftalık: connection count artış trendi?
Disk usage Günlük: WAL/segment growth normal mi?
Leader distribution Maintenance sonrası: rebalance gerekli mi?
Dead letter queue Günlük: DLX queue'da mesaj birikimi?

Common Problems & Solutions

Problem Belirti Root Cause Çözüm
Memory alarm Publish durdu, "resource limit exceeded" Queue'lar çok büyüdü veya message leak 1) rabbitmq-diagnostics memory_breakdown 2) Queue purge veya consumer scale-out
Disk alarm Publish durdu, disk free < limit WAL/segment dosyaları birikmiş 1) Consumer'ları hızlandır (ack → compaction) 2) Disk ekle 3) max-length policy
Network partition Bazı node'lar "partitioned" logluyor Network flap veya DNS failure 1) Network fix 2) pause_minority otomatik recover eder 3) Manuel: rabbitmqctl force_boot
Queue unavailable "NOT_FOUND" veya "timeout" hataları Quorum kaybı (majority node down) 1) Node'ları geri getir 2) Son çare: rabbitmq-queues delete_member + force
Consumer stuck Messages_unacked sürekli artıyor Consumer deadlock veya slow dependency 1) Consumer restart 2) Prefetch düşür 3) Consumer timeout (4.3+) aktifleştir
Connection refused Client "connection refused" logluyor FD exhaustion, memory alarm, veya node down 1) rabbitmq-diagnostics check_alarms 2) FD limit kontrol 3) Node health

Upgrade Stratejisi

Strateji Ne Zaman Avantaj Risk
Rolling upgrade Minor version (4.3.0 → 4.3.1) Zero downtime Mixed-version window'da davranış farkı
Blue-Green Major version (3.13 → 4.x) Tam rollback imkanı Geçiş sırasında mesaj loss (Shovel ile bridge)
In-place (stop-all) Dev/test ortamları Basit Downtime kabul edilmeli

Rolling Upgrade Prosedürü (Minor/Patch)

① Pre-check → ② Drain node → ③ Upgrade → ④ Rejoin → ⑤ Verify → (tekrarla)
CLI — Rolling Upgrade Step-by-Step
# ═══ PRE-FLIGHT CHECKS ═══
# 1. Cluster sağlıklı mı? (tüm node'lar running, alarm yok)
rabbitmq-diagnostics check_running
rabbitmq-diagnostics check_alarms
rabbitmqctl cluster_status

# 2. Feature flags kontrol (4.x gerekli)
rabbitmqctl list_feature_flags --formatter=json | jq '.[] | select(.state != "enabled")'
# Tüm required feature flags enabled olmalı UPGRADE ÖNCESINDE

# 3. Definitions yedekle
rabbitmqctl export_definitions /backup/pre-upgrade-$(date +%Y%m%d).json

# 4. Queue'ların healthy olduğunu doğrula
rabbitmq-queues check_if_node_is_quorum_critical  # Bu node'u kapatmak quorum bozar mı?
rabbitmq-queues check_if_node_is_mirror_sync_critical  # (3.x legacy)

# ═══ NODE UPGRADE (her node için tekrarla) ═══
# 5. Node'u maintenance mode'a al (4.0+)
rabbitmqctl drain  # Yeni connection kabul etmez, mevcut bağlantılar kapanır

# 6. Queue leader'larını başka node'lara taşı
rabbitmq-queues rebalance all

# 7. Node'u durdur
rabbitmqctl stop_app

# 8. Upgrade uygula (OS package manager)
# Debian/Ubuntu:
sudo apt-get update && sudo apt-get install rabbitmq-server=4.3.1-1
# RHEL/Rocky:
sudo yum update rabbitmq-server-4.3.1-1.el9

# 9. Node'u başlat ve cluster'a rejoin
rabbitmqctl start_app

# 10. Doğrula
rabbitmq-diagnostics check_running
rabbitmqctl cluster_status
rabbitmq-queues quorum_status <critical-queue>

# 11. Maintenance mode'u kaldır
rabbitmqctl revive

# ═══ POST-UPGRADE (tüm node'lar bittikten sonra) ═══
# 12. Yeni feature flag'leri enable et
rabbitmqctl enable_feature_flag all

# 13. Queue rebalance (leader'ları dengeli dağıt)
rabbitmq-queues rebalance all

Blue-Green Upgrade Prosedürü (Major Version)

Major upgrade'larda (3.13→4.0) rolling upgrade desteklenmez. İki ayrı cluster çalıştırıp Shovel ile bridge kurarsın:

CLI — Blue-Green with Shovel Bridge
# ═══ PHASE 1: Yeni cluster kur (Green) ═══
# Docker/K8s ile yeni versiyon cluster'ı ayağa kaldır
# Topology'yi import et:
rabbitmqctl import_definitions /backup/pre-upgrade-definitions.json

# ═══ PHASE 2: Shovel bridge kur (Blue → Green) ═══
# Eski cluster'dan (blue) yeni cluster'a (green) mesaj akışı:
rabbitmqctl set_parameter shovel bridge-orders     '{"src-protocol":"amqp091",
      "src-uri":"amqp://blue-cluster.internal",
      "src-queue":"orders",
      "dest-protocol":"amqp091",
      "dest-uri":"amqp://green-cluster.internal",
      "dest-queue":"orders",
      "reconnect-delay":5,
      "ack-mode":"on-confirm"}'

# Tüm kritik queue'lar için tekrarla veya wildcard policy kullan:
rabbitmqctl set_parameter shovel bridge-payments     '{"src-protocol":"amqp091",
      "src-uri":"amqp://blue-cluster.internal",
      "src-queue":"payments",
      "dest-protocol":"amqp091",
      "dest-uri":"amqp://green-cluster.internal",
      "dest-queue":"payments",
      "reconnect-delay":5,
      "ack-mode":"on-confirm"}'

# ═══ PHASE 3: Cutover ═══
# 1. Consumer'ları green cluster'a yönlendir (DNS/config change)
# 2. Publisher'ları green cluster'a yönlendir
# 3. Blue cluster queue depth'lerinin 0'a düşmesini bekle
rabbitmqctl list_queues name messages -n rabbit@blue-node1 | awk '$2 > 0'

# 4. Tüm queue'lar boşaldığında → shovel'ları kaldır
rabbitmqctl clear_parameter shovel bridge-orders
rabbitmqctl clear_parameter shovel bridge-payments

# ═══ PHASE 4: Rollback (sorun olursa) ═══
# DNS/config'i blue cluster'a geri çevir
# Shovel'ları ters yönde kur (green → blue) henüz consume edilmemiş mesajlar için
# Blue cluster hâlâ çalışıyor — hızlı rollback mümkün

Feature Flag Uyarısı (4.x): RabbitMQ 4.0+ feature flag sistemi kullanır. Upgrade öncesinde eski cluster'da enable_feature_flag all çalıştırılmalıdır. Aksi halde yeni versiyon cluster'a katılamaz. Feature flag enable işlemi geri alınamaz — bu yüzden önce yedek alın.

CLI — Definitions Backup & Restore
# Export: tüm topology (exchanges, queues, bindings, users, policies)
rabbitmqctl export_definitions /backup/rabbit-definitions-$(date +%Y%m%d).json

# VEYA HTTP API ile:
curl -u admin:password -X GET     http://localhost:15672/api/definitions     -o /backup/definitions.json

# Restore (yeni cluster'a):
rabbitmqctl import_definitions /backup/rabbit-definitions-20260528.json

# ⚠️ NOT: Bu sadece TOPOLOGY'yi yedekler. Mesaj içerikleri yedeklenmez!
# Mesajları yedeklemek için: Shovel ile drain → yeni cluster'a pump

Definitions export mesaj yedeklemez! export_definitions sadece topology'yi (exchange, queue, binding, user, policy) export eder. Queue'lardaki mesajlar dahil değildir. Mesaj kaybı kabul edilemezse, upgrade öncesi queue'ları drain edin veya Shovel ile bridge kurun.

Rollback Playbook

Production'da bir şeyler ters gittiğinde adım adım ne yapacağın:

Sorun Tetik Acil Aksiyon Rollback
Queue mesaj birikiyor Queue depth > 50K 5dk HPA scale-up veya consumer restart Prefetch düşür, slow consumer'ı izole et
Memory alarm Node memory > high_watermark rabbitmqctl set_vm_memory_high_watermark 0.5 Publisher'ları throttle et, lazy queue'ya geç
Disk alarm Free disk < disk_free_limit Log rotate, eski mnesia backup sil Disk ekle veya limit'i düşür (geçici)
Network partition partitions list non-empty pause_minority otomatik handle eder Manual: minority side'ı restart et
Consumer stuck (0 ack/s) Consumer utilisation = 0% Pod restart, connection kill Yeni consumer deploy et, eski kill
Poison message loop Aynı mesaj tekrar DLX'e düşüyor delivery-limit kontrol et Manual ack + dead-letter queue'ya taşı
CLI — Emergency Commands
# 1. Cluster durumunu kontrol et
rabbitmq-diagnostics cluster_status
rabbitmq-diagnostics check_running
rabbitmq-diagnostics check_alarms

# 2. Sorunlu queue'yu bul
rabbitmqctl list_queues name messages consumers state --formatter=json | \
    jq '.[] | select(.messages > 10000)'

# 3. Stuck consumer'ı bul ve connection'ını kes
rabbitmqctl list_consumers queue_name channel_pid ack_required | grep "target-queue"
rabbitmqctl close_connection "<connection_pid>" "emergency: stuck consumer"

# 4. Emergency: Queue purge (DİKKAT: mesaj kaybı!)
# Sadece test/dev ortamda kullanın. Production'da önce drain edin.
rabbitmqctl purge_queue "stuck-queue-name"

# 5. Memory pressure azaltma
rabbitmqctl set_vm_memory_high_watermark 0.6  # geçici yükselt

# 6. Flow control bypass (ASLA production'da yapma - sadece drain için)
# rabbitmqctl eval 'rabbit_alarm:clear_alarm({resource_limit, memory, node()}).'

purge_queue geri alınamaz! Mesajlar kalıcı olarak silinir. Production'da yanlış queue'yu purge etmek veri kaybına yol açar. Sadece list_queues ile doğruladıktan sonra çalıştırın.

TLS Konfigürasyonu

Production'da inter-node ve client bağlantıları TLS ile şifrelenmeli. Plaintext AMQP (5672) kapatılmalı, sadece AMQPS (5671) açık olmalıdır.

# Client TLS (port 5671)
listeners.tcp = none
listeners.ssl.default = 5671
ssl_options.cacertfile = /certs/ca.pem
ssl_options.certfile = /certs/server.pem
ssl_options.keyfile = /certs/server-key.pem
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = true
ssl_options.versions.1 = tlsv1.3
ssl_options.versions.2 = tlsv1.2

# Management UI TLS
management.ssl.port = 15671
management.ssl.cacertfile = /certs/ca.pem
management.ssl.certfile = /certs/server.pem
management.ssl.keyfile = /certs/server-key.pem

# Inter-node TLS (Erlang distribution)
ssl_options.honor_cipher_order = true
ssl_options.honor_ecc_order = true
var factory = new ConnectionFactory
{
    HostName = "rabbitmq-cluster.internal",
    Port = 5671,  // AMQPS
    Ssl = new SslOption
    {
        Enabled = true,
        ServerName = "rabbitmq-cluster.internal",
        CertPath = "/certs/client.pfx",
        CertPassphrase = configuration["RabbitMQ:CertPassword"],
        Version = System.Security.Authentication.SslProtocols.Tls13
    },
    AutomaticRecoveryEnabled = true
};
var connection = await factory.CreateConnectionAsync();

Sertifika Rotasyonu: Production'da sertifika expiry monitoring ekleyin. RabbitMQ sertifika değişikliğinde restart gerektirir (hot-reload desteklemez). Rolling restart ile zero-downtime rotation yapın.

Gerçek hayat senaryosu: SaaS platform major upgrade (3.13→4.0): Blue-green strateji. Yeni cluster kuruldu, Shovel ile eski cluster'dan yeni cluster'a mesaj bridge'lendi. DNS CNAME ile cutover yapıldı. 5 dakika dual-write sonrası eski cluster drain edildi ve kapatıldı. Rollback planı: DNS'i geri çevir.