8 dk

Uygulamalarınız İçin RabbitMQ: Desenler, Kurulum ve Operasyon

Uygulamalarınızda RabbitMQ nasıl kullanılır öğrenin: temel kavramlar, yaygın desenler, güvenilirlik ipuçları, ölçekleme, güvenlik ve üretimde izleme.

Uygulamalarınız İçin RabbitMQ: Desenler, Kurulum ve Operasyon

Neden RabbitMQ Uygulama Ekipleri İçin Önemli?

RabbitMQ bir mesaj aracısıdır: sisteminizin parçalarının arasında durur ve "iş"i (mesajları) üreticilerden tüketicilere güvenilir şekilde taşır. Uygulama ekipleri genellikle doğrudan, senkron çağrılar (servisler arası HTTP, paylaşılan veritabanları, cron işleri) kırılgan bağımlılıklar, dengesiz yükler ve zor debuglanan hata zincirleri yarattığında RabbitMQ'ya yönelir.

RabbitMQ'nin çözdüğü problemler

Trafik sıçramaları ve dengesiz iş yükleri. Uygulamanız kısa sürede 10× daha fazla kayıt veya sipariş alırsa, her şeyi hemen işlemek downstream servisleri zorlayabilir. RabbitMQ ile üreticiler görevleri hızlıca kuyruğa alır, tüketiciler ise bunları kontrollü bir hızda işler.

Hizmetler arası sıkı bağlılık. Servis A, Servis B'yi çağırıp beklemek zorundaysa, hatalar ve gecikmeler yayılır. Mesajlaşma bunları ayırır: A bir mesaj yayınlar ve devam eder; B uygun olduğunda işler.

Daha güvenli hata yönetimi. Her hata kullanıcıya gösterilecek bir hataya dönüşmemeli. RabbitMQ arka planda yeniden denemeleri, “zehirli” mesajları izole etmeyi ve geçici kesintiler sırasında iş kaybını önlemeyi kolaylaştırır.

Ekiplerin gördüğü tipik sonuçlar

Ekipler genellikle daha düzgün iş yükleri (zirveleri tamponlama), ayrışmış servisler (daha az çalışma zamanı bağımlılığı) ve kontrollü yeniden denemeler elde eder. Aynı derecede önemli olarak, işin nerede takıldığını—üreticide mi, bir kuyruğun içinde mi yoksa tüketicide mi—anlamak kolaylaşır.

Bu rehber neyi kapsıyor (ve neyi kapsamaz)

Bu rehber uygulama ekipleri için pratik RabbitMQ bilgisine odaklanır: temel kavramlar, yaygın desenler (pub/sub, work queue'lar, yeniden denemeler ve dead-letter kuyrukları) ve operasyonel konular (güvenlik, ölçekleme, gözlemlenebilirlik, sorun giderme).

AMQP spesifikasyonunun tamamını veya her RabbitMQ eklentisinin derinlemesine incelemesini amaçlamaz. Amaç, gerçek sistemlerde sürdürülebilir kalan mesaj akışları tasarlamanıza yardımcı olmaktır.

Hızlı sözlük

  • Producer: mesaj gönderen uygulama bileşeni.
  • Consumer: mesaj alıp işleyen uygulama bileşeni.
  • Queue: bir tüketici işleyene kadar mesajları tutan tampon.
  • Exchange: mesajları bir veya daha fazla kuyruğa yönlendiren giriş noktası.
  • Routing key: exchange'in mesajı nereye göndereceğine karar verirken kullandığı etiket.

RabbitMQ Temelleri: Nedir ve Ne Zaman Kullanılır

RabbitMQ, sisteminizin parçaları arasında mesajları yönlendiren bir mesaj aracısıdır; böylece üreticiler işi devreder ve tüketiciler hazır olduklarında işler.

AMQP mesajlaşma vs doğrudan HTTP çağrıları

Doğrudan bir HTTP çağrısında Servis A, Servis B'ye bir istek gönderir ve genellikle bekler. Servis B yavaşsa veya kapalıysa, Servis A başarısız olur veya bekler; zaman aşımı, yeniden deneme ve backpressure her arayan taraf için ele alınmalıdır.

RabbitMQ ile (çoğunlukla AMQP üzerinden) Servis A broker'a bir mesaj yayınlar. RabbitMQ onu saklar ve doğru kuyruk(lar)a yönlendirir; Servis B asenkron olarak tüketir. Ana fark, iletişiminizi spike'ları tamponlayan ve dengesiz iş yüklerini düzelten kalıcı bir ara katman üzerinden yapmanızdır.

Mesajlaşma ne zaman uygundur (ve ne zaman değildir)

Mesajlaşma uygundur eğer:

  • Takımları/servisleri bağımsız dağıtıp ölçeklemek istiyorsunuz (decouple).\
  • Kullanıcı isteğini engellemeden asenkron iş yapmanız gerekiyor (e-posta gönderme, PDF oluşturma, dolandırıcılık kontrolleri).\
  • Patlayıcı trafik bekliyorsunuz ve kuyruklarla zirveleri emmek istiyorsunuz.\
  • Onaylar, yeniden denemeler ve dead-letter kuyruğuyla güvenilir teslim istiyorsunuz.

Mesajlaşma uygun değildir eğer:

  • Gerçekten anında bir yanıt gerekiyorsa (ör. "bu parola geçerli mi?").\
  • Basit senkron okumalar yapıyorsanız doğrudan çağrı daha net ve debug edilmesi kolaydır.\
  • Mesaj sürümlendirme, yeniden deneme ve izleme için planınız yoksa (karmaşıklığı başka yere taşırsınız, azaltmazsınız).

Request/response vs asenkron iş akışı (basit örnek)

Senkron (HTTP):

Bir checkout servisi, fatura servisini HTTP ile çağırır: "Fatura oluştur." Kullanıcı faturanın oluşturulmasını bekler. Eğer fatura servisi yavaşsa checkout gecikir; eğer kapalıysa checkout başarısız olur.

Asenkron (RabbitMQ):

Checkout invoice.requested(id ile) yayınlar. Kullanıcıya sipariş alındı onayı hemen döner. Fatura servisi mesajı tüketir, faturayı oluşturur ve e-posta/bildirimlerin alması için invoice.created yayınlar. Her adım bağımsız olarak yeniden denenebilir; geçici kesintiler tüm akışı otomatik olarak bozmaz.

Temel Yapı Taşları: Exchange'ler, Kuyruklar ve Yönlendirme

RabbitMQ'yu anlamak için "mesajların nerede yayınlandığını" "nerede saklandığını" ayırmak faydalıdır. Üreticiler exchangelere yayın yapar; exchange'ler kuyruklara yönlendirir; tüketiciler kuyruklardan okur.

Exchange'ler: RabbitMQ mesajı nereye göndereceğine nasıl karar verir

Bir exchange mesajları saklamaz. Kuralları değerlendirir ve mesajları bir veya daha fazla kuyruğa iletir.

  • Direct exchange: routing key ile tam eşleşme yaparak yönlendirir. Belirli hedefler için kullanın (ör. billing veya email).\
  • Topic exchange: routing key desenlerini kullanarak yönlendirir. Esnek pub/sub ve “kategoriye abone ol” davranışı için idealdir.\
  • Fanout exchange: routing key'i yok sayarak bağlı tüm kuyruğa yayın yapar. Her tüketicinin her olayı alması gereken durumlar için kullanın (örn. önbellek temizleme).\
  • Headers exchange: yönlendirmeyi routing key yerine mesaj header'larına göre yapar. Birden fazla niteliğe bağlı yönlendirme gerektiğinde kullanın (ör. region=eu VE tier=premium), ama özel durumlar için saklayın çünkü anlaşılması zordur.

Kuyruklar ve binding'ler: mesajlar doğru yere nasıl gider

Bir kuyruk, mesajlar tüketici işlemeye hazır olana kadar beklediği yerdir. Bir kuyruğun bir tüketicisi olabilir veya birden fazla (rekabet eden tüketiciler) ve mesajlar tipik olarak aynı anda tek bir tüketiciye teslim edilir.

Bir binding exchange'i bir kuyruğa bağlayan ve yönlendirme kuralını tanımlayan şeydir. Şöyle düşünün: "Mesaj exchange X'e routing key Y ile gelirse, Q kuyruğuna teslim et." Aynı exchange'e birden fazla kuyruk bağlı olabilir (pub/sub) veya tek bir kuyruğu farklı routing key'ler için birden çok kez bind edebilirsiniz.

Routing key'ler ve desenler (topic exchange)

Direct exchange'lerde yönlendirme tam eşlemelidir. Topic exchange'lerde routing key, noktayla ayrılmış kelimeler şeklindedir, örneğin:

  • orders.created\
  • orders.eu.refunded

Binding'ler wildcard içerebilir:

  • * tam olarak bir kelime ile eşleşir (örn. orders.* orders.created ile eşleşir)
  • # sıfır veya daha fazla kelime ile eşleşir (örn. orders.# orders.created ve orders.eu.refunded ile eşleşir)

Bu, üreticiyi değiştirmeden yeni tüketiciler eklemenin temiz bir yolunu verir—yeni bir kuyruk oluşturup ihtiyacınız olan desenle bind edin.

Mesaj onayları: ack, nack, requeue

RabbitMQ mesaj teslim ettikten sonra tüketici sonucu bildirir:

  • ack: "Başarıyla işlendi." RabbitMQ mesajı kuyruğundan kaldırır.\
  • nack (veya reject): "Başarısız." Mesajı düşürebilir veya requeue edebilirsiniz.\
  • requeue: mesajı tekrar kuyruğa koyar, böylece yeniden denenir (genellikle hemen).

Requeue ile dikkatli olun: sürekli başarısız olan bir mesaj sonsuza kadar döngüye girip kuyruğu bloke edebilir. Birçok ekip nack ile retry stratejisi ve bir dead-letter kuyruğu (aşağıda) eşleştirir ki hatalar öngörülebilir şekilde ele alınsın.

Gerçek Uygulamalarda Yaygın Kullanım Durumları

RabbitMQ, işleri veya bildirimleri sistem parçalarınız arasında bekletmeden taşımak istediğinizde parlıyor. Aşağıda günlük ürünlerde karşılaşılan pratik desenler var.

Publish/subscribe bildirimleri (fanout/topic)

Bir olaya birden fazla tüketici tepki vermeli ve yayıncı kimin abone olduğunu bilmemeli—bu durumda publish/subscribe temiz bir çözüm.

Örnek: bir kullanıcı profilini güncellediğinde, arama indeksleme, analitik ve CRM senkronizasyonu paralel olarak bilgilendirilebilir. Fanout exchange ile tüm bağlı kuyruklara yayın yaparsınız; topic exchange ile seçici yönlendirme yapabilirsiniz (örn. user.updated, user.deleted). Bu, servisleri sıkı şekilde bağlamayı önler ve ekiplerin üreticiyi değiştirmeden yeni aboneler eklemesine izin verir.

Arka plan işleri için work queue'lar

Bir görev zaman alıyorsa, onu kuyruğa atıp işçilerin asenkron işlemesine izin verin:

  • resim/video işleme\
  • işlem e-postaları gönderme\
  • PDF veya rapor oluşturma\
  • veri içe/aktarma

Bu, web isteklerini hızlı tutar ve işçileri bağımsız ölçeklendirmenizi sağlar. Ayrıca concurrency'yi kontrol etmenin doğal bir yoludur: kuyruk sizin “yapılacaklar listesi”niz olur ve işçi sayısı throughput kontrol düğmeniz olur.

Servisler arası olay odaklı entegrasyon

Birçok iş akışı servis sınırlarını aşar: order → billing → shipping klasik örnektir. Bir servis bir sonraki servisi çağırıp bloke olmak yerine, her adımı tamamlandığında bir olay yayınlayabilir. Downstream servisler olayları tüketip iş akışını sürdürür.

Bu, dayanıklılığı artırır (ör. shipping geçici olarak kapalıyken checkout bozulmaz) ve sahipliği netleştirir: her servis ilgilendiği olaylara tepki verir.

Yavaş veya güvenilmez bağımlılıkların köprüsü

RabbitMQ ayrıca uygulamanız ile yavaş veya hataya açık bağımlılıklar (üçüncü taraf API'ler, eski sistemler, toplu veritabanları) arasında tampon görevi görür. Talepleri hızlıca kuyruğa alırsınız, sonra kontrollü yeniden denemelerle işler sinirli bir şekilde işlenir. Bağımlılık kapalıysa iş güvenle birikir ve daha sonra boşalır—bunun yerine tüm uygulama çapında zaman aşımı ve hatalar oluşmaz.

Kuyrukları kademeli olarak tanıtmayı planlıyorsanız, küçük bir “async outbox” veya tek arka plan iş kuyruğu genellikle iyi bir ilk adım olur (bkz. /blog/next-steps-rollout-plan).

Sürdürülebilir Mesaj Akışları Tasarlamak

RabbitMQ kurulumu, yönlerin kolay tahmin edilebilir olduğu, isimlerin tutarlı olduğu ve yüklerin eski tüketicileri bozmayacak şekilde evrildiği zaman çalışması keyifli olur. Yeni bir kuyruk eklemeden önce bir mesajın "hikâyesinin" açık olduğundan emin olun: nereden kaynaklandığı, nasıl yönlendirildiği ve bir ekip arkadaşının uçtan uca nasıl debug edebileceği.

Yönlendirme ihtiyaçlarınıza uyan exchange tipini seçin

Doğru exchange'i baştan seçmek tek seferlik binding'leri ve sürpriz fan-out'ları azaltır:

  • Direct exchange: routing key belirli bir kuyruğa gittiğinde en iyisidir (örn. billing.invoice.created).\
  • Topic exchange: desenlerle esnek pub/sub için iyidir (örn. billing.*.created, *.invoice.*). Bu, sürdürülebilir olay yönlendirmesi için en yaygın tercihtir.\
  • Fanout exchange: her tüketici her mesajı almalıysa en iyisidir (iş olayları için nadir; broadcast benzeri sinyallerde daha yaygın).

İyi bir kural: karmaşık yönlendirme mantığını kodda "icat ediyorsanız", muhtemelen bunun yerine topic exchange desenini kullanmalısınız.

Mesaj şeması temelleri: sürümlendirme ve geriye dönük uyumluluk

Mesaj gövdelerini halka açık API gibi ele alın. Açık sürümlendirme kullanın (ör. üst düzey schema_version: 2) ve geriye dönük uyumluluğa çalışın:

  • Alan ekleyin; yeniden adlandırmayın/kaldırmayın.\
  • Varsayılanları güvenli olan opsiyonel alanları tercih edin.\
  • Kırıcı bir değişiklik kaçınılmazsa, eski mesajı sessizce değiştirmek yerine yeni bir mesaj türü/routing key yayınlayın.

Bu, eski tüketicilerin kendi takvimlerinde yeni sürüme geçmesine izin verir.

Kesişim ID'leri ve trace ID'leri ile çapraz-servis debug

Sorun gidermeyi ucuzlatmak için metadata standardize edin:

  • correlation_id: aynı işsel işlemdeki komutları/olayları birbirine bağlar.\
  • trace_id (veya W3C traceparent): HTTP ve asenkron akışlar arasında izlemeyi bağlar.

Her yayıncının bunları tutarlı şekilde ayarlaması, tek bir işlemi birden fazla servis boyunca izlemeyi kolaylaştırır.

Ölçeklenen isimlendirme konvansiyonları

Tahmin edilebilir, aranabilir isimler kullanın. Yaygın bir desen:

  • Exchanges: <domain>.<type> (örn. billing.events)\
  • Routing key'ler: <domain>.<entity>.<verb> (örn. billing.invoice.created)\
  • Kuyruklar: <service>.<purpose> (örn. reporting.invoice_created.worker)

Tutarlılık zekice olmaktan daha faydalıdır: gelecekteki siz ve on-call ekibiniz minnettar kalacaktır.

Güvenilirlik Desenleri: Yeniden Denemeler, DLQ ve Idempotency

Export and own the source
İnceleyip test edebileceğiniz, kendi ortamınızda çalıştırabileceğiniz temiz bir kod tabanı alın.

Güvenilir mesajlaşma çoğunlukla hatayı planlamaktan ibarettir: tüketiciler çöker, downstream API'ler zaman aşımı verir ve bazı olaylar bozuk olabilir. RabbitMQ size araçları sağlar, ama uygulama kodunuz işbirliği yapmalıdır.

En az bir kez teslimat (ve bunun kodunuz için anlamı)

Yaygın bir kurulum en az bir kez teslimattır: bir mesaj birden fazla kez teslim edilebilir, ama sessizce kaybolmamalıdır. Bu genellikle tüketici mesajı alıp işleme başlar, sonra ack göndermeden başarısız olursa olur—RabbitMQ mesajı tekrar kuyruğa koyar ve yeniden teslim eder.

Pratik sonuç: çoğaltmalar normaldir, bu yüzden handler'ınız birden fazla çalıştırılmaya dayanıklı olmalıdır.

Tüketiciler için idempotency stratejileri

Idempotency, "aynı mesaj iki kez işlenirse tek kez işleme ile aynı etkiye sahip olması" demektir. Kullanışlı yaklaşımlar:

  • Dedupe anahtarları: stabil message_id (veya order_id + event_type + version) dahil edin ve bunu TTL'li bir “işlenmiş” tablo/cache'ine kaydedin.\
  • Güvenli güncellemeler: sadece durum PENDING ise güncelle gibi koşullu yazmalar veya veritabanı benzersizlik kısıtları kullanın.\
  • Outbox/inbox desenleri: önce olay alımını persist edin, sonra işleyin; böylece yeniden denemeler yan etkileri tekrarlamaz.

TTL + DLX/DLQ ile yeniden denemeler

Yeniden denemeler tüketicide sıkı döngü olarak değil, ayrı bir akış olarak ele alınmalıdır.

Yaygın desen:

  1. Geçici hata durumunda reddet ve retry kuyruğuna yönlendir; bu kuyruğun bir per-queue (veya per-message) TTLsi olsun.\
  2. TTL dolunca mesaj bir dead-letter exchange (DLX) aracılığıyla orijinal kuyruğa dead-letter edilir.\
  3. Deneme sayısını bir header ile takip edin (veya routing key içinde kodlayın) ve N denemeden sonra durdurun.

Bu, mesajları unacked bırakmadan backoff sağlar.

Zehirli mesajlar: karantina ve yeniden oynatma

Bazı mesajlar asla başarılı olamayacaktır (kötü şema, eksik referans verisi, kod hatası). Bunları şöyle tespit edin:

  • maksimum yeniden deneme sayısına ulaşılması\
  • aynı hata imzasıyla tekrar eden başarısızlıklar

Bunları bir DLQye gönderin ve DLQ'yu operasyonel bir gelen kutusu gibi ele alın: payloadları inceleyin, temel sorunu düzeltin ve seçili mesajları manuel olarak yeniden oynatın (mümkünse kontrollü bir araç/script ile)—hepsini ana kuyruğa yeniden dökmeyin.

Performans ve Ölçekleme: Pratik Ayar İpuçları

RabbitMQ performansı genellikle bağlantıları nasıl yönettiğiniz, tüketicilerin işi ne kadar hızlı güvenle işleyebildiği ve kuyruğun bir “depolama” olarak kullanılıp kullanılmadığı gibi birkaç pratik faktörle sınırlanır. Amaç, büyüyen bir backlog oluşturmadan istikrarlı throughput elde etmektir.

Bağlantılar vs kanallar (yeniden kullanım ve limitler)

Her yayıncı veya tüketici için yeni bir TCP bağlantısı açmak yaygın bir hatadır. Bağlantılar düşündüğünüzden daha ağırdır (handshake, heartbeats, TLS), bu yüzden uzun ömürlü tutun ve yeniden kullanın.

Yayın için az sayıda bağlantı ve çok sayıda channel kullanın. Genel kural: az bağlantı, çok kanal. Yine de binlerce kanal oluşturmayın—her kanalın overhead'i vardır ve client kütüphanenizin kendi limitleri olabilir. Her servis için küçük bir kanal havuzu oluşturup kanalları yeniden kullanmayı tercih edin.

Prefetch ve concurrency (yük olmadan throughput)

Tüketiciler aynı anda çok fazla mesaj çekerse bellek sıçraması, uzun işleme süreleri ve düzensiz gecikme görürsünüz. Her tüketicinin kontrollü sayıda unacked mesaj tutması için prefetch (QoS) ayarlayın.

Pratik rehber:

  • Daha yavaş işler için (API çağrıları, dosya işleme) her tüketici için prefetch 1–10 ile başlayın.\
  • CPU hafif hızlı handler'lar için prefetch'i ack oranlarını ve host kaynaklarını izleyerek kademeli artırın.\
  • Prefetch'i çok yükseltmeden önce daha fazla tüketici örneği (veya thread) ekleyerek ölçekleyin.

Mesaj boyutu: yükü hafif tutun

Büyük mesajlar throughput'u düşürür ve bellek baskısını artırır (yayıncıda, broker'da ve tüketicide). Eğer payload büyükse (dokümanlar, resimler, büyük JSON), bunları başka bir yerde (nesne depolama veya veritabanı) saklayıp RabbitMQ üzerinden sadece bir ID + metadata gönderin.

Kural: mesajları KB aralığında tutun, MB değil.

Backpressure: “sonsuz kuyruk büyümesini” önleyin

Kuyruk büyümesi bir strateji değil, belirtidir. Üreticilerin tüketiciler yetişemezken yavaşlamasını sağlayın:

  • Tüketici işini sınırlandırın: concurrency'yi sınırlayın ve prefetch'i öyle ayarlayın ki in-flight işler öngörülebilir olsun.\
  • Büyümeyi algılayıp tepki verin: kuyruk derinliğinde ve publish vs ack oranında alarmlar kurun.\
  • Yük azaltma: kritik olmayan olaylar için spike sırasında mesajları düşürün veya örnekleme yapın.

Şüphede kaldığınızda tek bir ayarı değiştirin ve ölçün: publish hızı, ack hızı, kuyruk uzunluğu ve uçtan uca gecikme.

RabbitMQ Dağıtımları İçin Güvenlik Kontrol Listesi

Make changes with confidence
Yönlendirme veya handler değişikliklerini hızlıca deneyin ve bir binding ya da handler yanlış giderse kolayca geri alın.

RabbitMQ güvenliği çoğunlukla "kenarları sıkılaştırmak"le ilgilidir: istemciler nasıl bağlanır, kim ne yapabilir ve kimlik bilgilerini yanlış yerde tutmamak.

Bağlantıları TLS ile şifreleyin

  • Tüm istemci bağlantıları için TLS etkinleştirin (AMQP over TLS 5671 veya sizin belirlediğiniz port) ve modern TLS sürümlerini/cipher'larını tercih edin.\
  • Broker ana bilgisayar adına uyan sertifikalar kullanın.\
  • Sertifika rotasyonunu planlayın: son kullanma tarihlerini takip edin, yenilemeleri otomatikleştirin ve rotasyonun kesintiye yol açmaması için reload prosedürlerini prova edin.\
  • Mümkünse duyarlı verileri işleyen iç servisler için istemci doğrulamasını (mTLS) kullanın.

Kimlik doğrulama ve yetkilendirme

RabbitMQ izinleri tutarlı kullanıldığında güçlüdür.

  • Her uygulama için ayrı kullanıcılar oluşturun (paylaşılan “app” hesaplarından kaçının).\
  • Tenant'ları veya sistemleri bölümlendirmek için vhost'lar kullanın (örn. ürün/ekip başına bir vhost).\
  • Her vhost için en az ayrıcalık prensibini uygulayın:\
    • Configure (kaynak oluştur/degistir)\
    • Write (yayın yap)\
    • Read (tüket)

Dev/staging/prod ayrımını güvenle yapın

  • Mümkünse her ortam için ayrı cluster çalıştırın. Paylaşılan altyapı gerekiyorsa sıkı vhost sınırları ve ayrı kimlik bilgileri ile izole edin.\
  • Bir geliştirme uygulamasının testi için prod broker'a bağlanmasını "sadece test için" engelleyin—bunu ağ politikası ve DNS adlandırması ile pratikte imkansız hale getirin.

Uygulamalarda sırları doğru yönetin

  • Kimlik bilgilerini koda, git'e veya container image'a gömmeyin.\
  • Sırları çalışma zamanında platformunuzdan enjekte edin (Kubernetes secrets, bir secrets manager veya şifrelenmiş CI değişkenleri).\
  • Kimlik bilgilerini düzenli döndürün ve kullanılmayan kullanıcıları kaldırın.

Operasyonel sertleştirme (portlar, firewall, denetim) için kısa bir iç runbook tutun ve ekiplerin tek bir standardı takip etmesi için belgenize bağlayın (ör. /docs/security).

İzleme ve Gözlemlenebilirlik: Ne Ölçmeli

RabbitMQ bozulduğunda semptomlar önce uygulamanızda görünür: yavaş uç noktalar, zaman aşımaları, eksik güncellemeler veya "hiç bitmeyen" işler. İyi gözlemlenebilirlik broker'ın sebep olup olmadığını doğrulamanızı, darboğazı (üretici, broker veya tüketici) tespit etmenizi ve kullanıcılar fark etmeden önce müdahale etmenizi sağlar.

Takip edilmesi gereken temel broker metrikleri

Akışın devam edip etmediğini söyleyen küçük bir sinyal seti ile başlayın:

  • Kuyruk derinliği (ready + unacked): artan derinlik tüketicilerin yetişemediğini veya takıldığını gösterir.\
  • Publish hızı ve ack hızı: publish artarken ack sabit kalıyorsa backlog vardır. Acknowledge'lerde ani düşüş tüketici hatası veya zaman aşımına işaret eder.\
  • Tüketici kullanım oranı: tüketiciler boşta mı, doymuş mu yoksa sık sık mı yeniden başlıyor? Bunu prefetch ve concurrency ile eşleştirin.\
  • Redeliveries / requeues: işleme hataları, kötü retry politikası veya zehirli mesajların güçlü göstergesidir.

Erken olay yakalayan uyarı sinyalleri

Eşikler yerine trendler üzerine uyarı verin:

  • N dakika boyunca artan backlog: derinliğin tutarlı artışı, tek seferlik eşikten daha eylemseldir.\
  • Tekrarlayan requeue/redelivery: CPU tüketen ve kuyruğu bloke eden hata döngüsüne işaret eder.\
  • Bağlantı ve kanal dalgalanmaları: sık disconnect'ler uygulama çökmesi, ağ sorunları veya yanlış heartbeat konfigürasyonuna işaret edebilir.\
  • Uzun süre yüksek unacked: tüketicilerin asılı kaldığını veya her mesaj için çok uzun zaman harcadığını gösterir.

Olay anında loglar ve mesaj izleme

Broker logları "RabbitMQ çöktü" ile "istemciler onu yanlış kullanıyor" arasındaki farkı ayırt etmenize yardımcı olur. Kimlik doğrulama hataları, bloklanan bağlantılar (resource alarm'ları) ve sık kanal hatalarını arayın. Uygulama tarafında her işleme denemesi için bir correlation ID, kuyruk adı ve sonuç (acked, rejected, retried) loglandığından emin olun.

Dağıtık izleme kullanıyorsanız trace header'larını mesaj özellikleri aracılığıyla taşıyın ki "API isteği → yayınlanan mesaj → tüketici işi" zincirini bağlayabilesiniz.

Paneller ve iç runbook'lar

Her kritik akış için bir pano oluşturun: publish hızı, ack hızı, derinlik, unacked, requeues ve tüketici sayısı. Panoya iç runbook'unuzun ve "ilk bakışta kontrol edilecekler" kontrol listesinin bağlantılarını ekleyin (ör. /docs/monitoring).

Yaygın RabbitMQ Sorunlarını Giderme

Bir şey "ilerlemeyi kestiğinde", önce yeniden başlatma dürtüsüne direnin. Çoğu sorun (1) binding ve yönlendirmeler, (2) tüketici sağlığı ve (3) kaynak alarm'larına baktığınızda barizleşir.

Mesajlar tüketilmiyor

Eğer üreticiler "başarıyla gönderildi" diyor ama kuyruklar boş kalıyorsa (veya yanlış kuyruk doluyorsa), önce yönlendirmeyi kontrol edin.

Management UI'da başlayın:

  • Exchange tipini ve kuyruğun beklenen bindinge sahip olup olmadığını doğrulayın.\
  • Üreticinin yayınladığı routing keyin binding paterniyle eşleşip eşleşmediğini kontrol edin (özellikle topic exchange'lerde).\
  • Doğru vhosta yayın yaptığınızdan emin olun.

Kuyrukta mesaj var ama kimse tüketmiyorsa doğrulayın:

  • Bir tüketici bağlı mı ve doğru kuyruğa abone mi?\
  • Tüketici prefetch yüzünden sıkışmış veya downstream yavaş iş nedeniyle bloklanmış mı?\
  • Ack'ler gerçekleşiyor mu (unacked artıyorsa tüketici ack göndermiyor veya aşırı yüklü)?

Çoğaltmalar ve sıra dışı teslim

Çoğaltmalar genellikle yeniden denemelerden (tüketici ack göndermeden çöktüğünde), ağ kesilmelerinden veya manuel requeue işlemlerinden gelir. Handler'ları idempotent yaparak (örn. veritabanında mesaj ID'sine göre dedupe) hafifletin.

Sıra kayması, birden fazla tüketici veya requeue olunca beklenen bir durumdur. Sıra önemliyse o kuyruk için tek bir tüketici kullanın veya anahtara göre partition ederek birden çok kuyruk oluşturun.

Bellek/disk alarmı

Alarm, RabbitMQ'nin kendini korumasıdır.

  • Disk alarmı: boş disk alanı sağlayın, logları taşıyın veya hacmi genişletin; sonra alarmın temizlendiğini doğrulayın.\
  • Bellek alarmı: in-flight mesajları azaltın (prefetch'i düşürün, tüketicileri yavaşlatın), ve büyük mesajları kontrol edin.

DLQ'den güvenli yeniden oynatma

Yeniden oynamadan önce kök nedeni düzeltin ve "zehirli mesaj" döngüsünü önleyin. Mesajları küçük partiler halinde yeniden kuyruğa verin, yeniden deneme sınırı ekleyin ve yeniden oynatılan mesajları ayrı bir kuyruğa göndererek aynı hatanın tekrar etmesi durumunda hızlıca durdurma şansı bırakın.

RabbitMQ vs Alternatifler: Doğru Aracı Seçmek

Go from idea to deployment
Sohbette doğruladığınız akışı dağıtın ve kuyruk destekli uygulamanızı barındırın.

Mesajlaşma aracını seçmek "en iyi"den çok trafik modelinize, hata toleransınıza ve operasyonel konforunuza bağlıdır.

RabbitMQ hangi durum için uygundur

RabbitMQ, güvenilir mesaj teslimi ve esnek yönlendirme gerektiğinde parlıyor. Komutlar, arka plan işleri, fan-out bildirimleri ve request/response desenleri için güçlü bir seçimdir, özellikle:

  • Mesaj başına onaylar ve backpressure istiyorsanız (yavaş tüketiciler işi sessizce düşürmez).\
  • Zengin yönlendirme (topic, headers, direct) sizden kodla yapılmasını istemezsiniz.\
  • Birçok ekip için operasyonel olarak basit ölçeklendirme istiyorsunuz (tüketici ekle, prefetch ayarla, kuyruğu yönetin).

Eğer amacınız olayları uzun süre saklamak değil de işi taşımaksa, RabbitMQ genellikle rahat bir varsayılandır.

RabbitMQ vs Kafka-benzeri akış sistemleri

Kafka ve benzerleri yüksek throughput streaming ve uzun süreli event log için tasarlanmıştır. Kafka-benzeri bir sistem seçin eğer:

  • Yeniden oynatma (tüketiciler geçmişi yeniden işleyebilsin) istiyorsanız.\
  • Bölümlenmiş ölçeklemeyle çok yüksek throughput gerekliyse.\
  • Analitik + servisler için tek bir "gerçeklik kaynağı" olay akışı istiyorsanız.

Takas: Kafka türü sistemler daha yüksek operasyonel yük getirebilir ve sizi throughput odaklı tasarıma (batching, partition stratejisi) itebilir. RabbitMQ genellikle düşük-orta throughput, düşük uçtan uca gecikme ve karmaşık yönlendirme için daha kolaydır.

Basit bir görev kuyruğu yeterliyse

Eğer tek bir uygulama iş üretiyor ve tek bir worker havuzu tüketiyorsa—ve daha basit semantiklerle yetinebiliyorsanız—Redis tabanlı kuyruk veya yönetilen görev servisi yeterli olabilir. Ekipler genellikle teslim garantileri, dead-lettering, birden fazla yönlendirme deseni veya üreticiler/tüketiciler arasında daha net ayrım gerektiğinde bu noktadan çıkar.

İhtiyaçlar değişirse migration dikkate alınması gerekenler

Mesaj sözleşmelerinizi ileride taşıyabileceğinizi varsayarak tasarlayın:

  • Mesaj şemalarını sürümlendirin ve geriye dönük uyumlu tutun.\
  • Payload'ta broker'a özgü özelliklerden kaçının (routing'i header/metadata'da tutun, gövdede değil).\
  • Üreticiler/tüketiciler paralel çalışabilecek şekilde tasarlayın, böylece migration sırasında her ikisini aynı anda çalıştırabilirsiniz.

Daha sonra replay edilebilir stream'lere ihtiyaç duyarsanız, RabbitMQ olaylarını bir log-temelli sisteme köprüleyebilirsiniz; operasyonel iş akışları için RabbitMQ'yu koruyabilirsiniz. Pratik bir rollout planı için bkz. /blog/rabbitmq-rollout-plan-and-checklist.

Sonraki Adımlar: Rollout Planı ve Ekip Kontrol Listesi

RabbitMQ'yu devreye almak onu bir ürün gibi ele almakla en iyi sonuç verir: küçük başlayın, sahipliği tanımlayın ve daha fazla servise yaymadan önce güvenilirliği kanıtlayın.

Başlangıç kontrol listesi (tek servis benimsemesi)

Asenkron işlemden fayda sağlayan tek bir iş akışı seçin (ör. e-posta gönderme, rapor oluşturma, üçüncü taraf API ile senkronizasyon).

  • Mesaj sözleşmesini tanımlayın: gerekli alanlar, sürüm ve "başarı"nın ne anlama geldiği.\
  • Bir exchange + bir kuyruk oluşturun ve açık bir adlandırma konvansiyonu kullanın.\
  • Downstream sistemleri aşırı yüklememek için tüketici concurrency limitleri ve prefetch ayarlayın.\
  • Baştan yeniden deneme davranışı (backoff ile) ve bir dead-letter kuyruğu (DLQ) ekleyin.\
  • Handler'ları idempotent yapın.\
  • Operasyonel "kanamayı durdur" adımlarını belgeleyin (tüketiciyi durdur, kuyruğu boşalt, DLQ'yi yeniden oynat).

Referans şablonlarına ihtiyacınız varsa, adlandırma, retry katmanları ve temel politikalar için merkezi bir /docs tutun.

Birçok ekip uygulamayı hayata geçirirken altyapı ve şablonları standartlaştırmayı düşünür. Örneğin Koder.ai kullanan ekipler genellikle sohbet isteminden küçük bir üretici/tüketici iskeleti üretir (adlandırma, retry/DLQ bağlantıları ve trace/correlation header'ları dahil), sonra kaynak kodunu dışa aktarır ve rollout öncesi planlama aşamasında gözden geçirir.

Operasyonel sahiplik (açıkça belirtin)

RabbitMQ, "birinin kuyruğu sahiplenmesi" ile başarılı olur. Bunu üretime almadan önce kararlaştırın:

  • Kim izliyor: genellikle platform/SRE broker sağlığını izler; servis ekipleri kendi kuyruklarını ve tüketici davranışını izler.\
  • DLQ kim yönetir: servis ekibi on-call (kesin yükseltme yolu ile).\
  • Runbook'lar: kritik her kuyruk için bir broker-seviyesi runbook ve bir servis-seviyesi runbook.

Yönetilen hosting veya resmi destek planlıyorsanız, beklentileri baştan hizalayın (bkz. /pricing) ve onboarding/destek için bir temas yolu belirleyin (bkz. /contact).

Sonraki deneyler (ölçeklemeden önce doğrulayın)

Güveni artırmak için küçük, zaman kutulu egzersizler yapın:

  • Load test: peak benzeri koşullarda throughput, tüketici concurrency ve gecikmeyi doğrulayın.\
  • Hata tatbikatları: tüketicileri öldürün, broker yeniden başlatmaları simüle edin, ağ gecikmesi zorlayın; yeniden denemeleri ve DLQ davranışını doğrulayın.\
  • Şema sürümlendirme: v2 mesajı tanıtın; v1 tüketiciler çalışırken uyumluluğu ve rollout adımlarını doğrulayın.

Bir servis birkaç hafta stabil kaldığında, aynı desenleri diğer servislere çoğaltın—ekip başına yeniden icat etmeyin.

SSS

When should an application team use RabbitMQ instead of direct HTTP calls?

RabbitMQ'yu, servisleri birbirinden ayırmak, trafik dalgalanmalarını absorbe etmek veya yavaş işleri istek akışından uzaklaştırmak istediğinizde kullanın.

Arka plan işleri (e-postalar, PDF oluşturma), birden fazla aboneyi bilgilendiren bildirimler ve geçici downstream kesintilerinin iş akışını bozmasını istemediğiniz durumlar iyi birer örnektir.

Gerçekten anlık bir cevap gerektiğinde (basit okuma/doğrulama) veya sürümleme, yeniden deneme ve izleme için taahhütte bulunamıyorsanız mesajlaşmadan kaçının—bunlar üretimde opsiyonel değildir.

How do I choose between direct, topic, fanout, and headers exchanges?

Bir exchangee yayın yapın ve mesajları kuyruklara yönlendirin:

  • Belirli bir hedefe gitmesi gereken routing key için direct exchange kullanın.
  • orders.* veya orders.# gibi esnek desenler istiyorsanız topic exchange kullanın.
  • Her tüketicinin her mesajı alması gerekiyorsa fanout exchange kullanın.
  • Yönlendirme birden fazla özelliğe bağlıysa ve istisnai durumsa headers exchange kullanın.

Çoğu ekip, sürdürülebilir olay tarzı yönlendirme için varsayılan olarak topic exchangee yönelir.

What’s the difference between a queue and a binding, and how does routing go wrong?

Bir kuyruk mesajları saklar; bir binding exchange ile kuyruk arasındaki bağlantı kuralını tanımlar.

Yönlendirme sorunlarını debug etmek için:

  • Exchange tipini ve kuyruğun beklenen binding desenine sahip olup olmadığını doğrulayın.
  • Üreticinin yayınladığı routing key'in binding ile eşleştiğini kontrol edin (özellikle topic wildcard'ları ile).\
  • Yayın/abone işleminin doğru vhost'ta yapıldığından emin olun.

Bu üç kontrol, "gönderildi ama tüketilmedi" vakaların çoğunu açıklar.

What’s the simplest “work queue” pattern for background jobs?

Bir iş birimini her seferinde bir işçi işlemeli diyorsanız work queue kullanın.

Pratik kurulum ipuçları:

  • Her mesajı tek bir iş birimi olarak tutun (küçük, yeniden denenebilir).
  • İşçilerin çok fazla unacked mesaj almasını önlemek için prefetch ayarlayın.
  • Prefetch'i yüksek ayarlamadan önce işçi sayısını artırarak ölçekleyin.
  • Büyük veriler yerine ID + metadata gönderin; büyük blob'ları başka yerde saklayın.
What does at-least-once delivery mean, and how do I handle duplicates?

At-least-once teslimat, bir mesajın birden çok kez teslim edilebileceği anlamına gelir (ör. tüketici iş yaptıktan sonra ack göndermeden çökebilir).

Tüketicileri güvenli hale getirmek için:

  • Sabit bir message_id (veya iş anahtarı) kullanıp işlenmiş ID'leri TTL ile saklayın.
  • Güvenli güncellemeler yapın (ör. sadece durum PENDING ise güncelleme) veya benzersizlik kısıtları kullanın.
  • Yan etkileri ayırın ki yeniden denemeler çifte ücretlendirme, çift e-posta veya çift kayıt oluşturmaya yol açmasın.

Yineleme ve çoğaltmaların normal olduğunu varsayın.

How should I implement retries and dead-letter queues (DLQ) in RabbitMQ?

Sıkı requeue döngülerinden kaçının. Yaygın bir yöntem "retry kuyrukları" + DLQ'dur:

  • Geçici bir hata durumunda mesajı TTL'li bir retry queue'ya yönlendirin (backoff için).\
  • TTL dolunca mesaj bir DLX aracılığıyla ana kuyruğa dead-letter edilir.\
  • Deneme sayısını bir header ile takip edin ve N denemenin ardından durdurun.\
  • Kalıcı hataları karantina için DLQye gönderin.

DLQ'den yeniden oynatma yapmadan önce kök nedeni düzeltin ve küçük partiler halinde yeniden oynatın.

How do I keep message contracts maintainable as services evolve?

Açık ve tahmin edilebilir isimler kullanın ve mesajları halka açık API gibi düşünün:

  • Yüklemelere schema_version ekleyin.
  • Alan eklemeyi tercih edin; alanları yeniden adlandırmayın veya kaldırmayın.\
  • Kırıcı bir değişiklik gerekiyorsa yeni bir mesaj tipi/routing key yayınlayın.

Ek metadata standardize edin:

  • correlation_id ile aynı işleme ait komutları/olayları bağlayın.\
  • trace_id (veya W3C traceparent) ile HTTP ve asenkron akışlar arasında izlemeyi bağlayın.

Bu, yeni gelenlerin ve on-call ekibin işini kolaylaştırır.

What metrics and alerts matter most for RabbitMQ in production?

İşin akıp gitmesini gösteren birkaç sinyale odaklanın:

  • Kuyruk derinliği (ready + unacked)
  • Publish hızı vs ack hızı
  • Redelivery/requeue oranları (hata döngüsü göstergesi)
  • Tüketici sayısı/kullanımı ve sık yeniden başlama

Eşikler yerine trendleri uyarın (ör. "backlog 10 dakika boyunca artıyor"). Loglarda kuyruk adı, correlation_id ve işleme sonucu (acked/retried/rejected) olsun.

What’s the minimum security checklist for deploying RabbitMQ?

Temel uygulamalar:

  • Tüm istemci bağlantıları için TLS kullanın; hassas iç trafik için mTLS düşünün.\
  • Her uygulama için ayrı kullanıcı oluşturun (paylaşılan kimlik bilgileri kullanmayın).\
  • Ortamları/tenant'ları izole etmek için vhost kullanın ve en az ayrıcalık prensibini uygulayın (configure/write/read).\
  • Kimlik bilgilerini kodda/hard-coded config'te saklamayın; çalışma zamanında platformunuzdan enjekte edin ve düzenli rotasyon yapın.

Kısa bir iç runbook hazırlayın ki ekipler tek bir standardı takip etsin.

How do I troubleshoot “messages aren’t being consumed” or “everything is stuck”?

Akışın nerede durduğunu bulun:

  • Kuyruklar boşsa exchange/binding/routing key ve vhost'u kontrol edin.\
  • Kuyrukta mesaj varsa ama ilerlemiyorsa tüketici bağlantılarını, prefetch'i ve unacked sayısını kontrol edin.\
  • Çoğaltmalar veya sıranın karışması varsa yeniden denemeleri ve çoklu tüketicileri varsayın; idempotency ve partitioning ile hafifletin.\
  • Disk/ram alarmı varsa in-flight mesajları azaltın (prefetch/concurrency), yayın hızını düşürün ve kaynak limitlerini çözün.

Çoğu durumda yeniden başlatma ilk ve en iyi hamle değildir.

Related posts