[ OK ]Kernel başlatılıyor...
~/im/blog
Beni İşe Alın

Konuşalım

Çözülmesi gereken bir altyapı probleminiz mi var veya projeniz için desteğe mi ihtiyacınız var? Yeni projeler için bana ulaşabilirsiniz.

İletişime geç

Bağlantılar

Beni sosyal medyada ve profesyonel ağlarda bulun.

© 2026 Irfan Miral. Tüm hakları saklıdır.Geliştiren:Irfan Miral
Gizlilik PolitikasıŞartlar & Koşullar
Ana SayfaHizmetlerHakkımda/ÖzgeçmişBlogİletişimAraçlar
2026-08-05• 5 dk okuma süresi

Bir Kuyruk (Queue) Tablosu Yeterli Olmadığında: RabbitMQ'ya Geçiş

Databases RabbitMQ Message Queues Architecture

Reklam

Şaşırtıcı sayıda üretim (production) sistemi arka plan işlerini tam olarak aynı şekilde halleder. Bir jobs tablosu, bir status sütunu (pending, processing, done, failed) ve onu bir döngü içinde yoklayarak bekleyen (pending) satırları alıp ilerledikçe durumlarını güncelleyen bir veya birden fazla worker (işçi).

Bu başlangıç için tamamen mantıklı bir yöntemdir. Kesinlikle hiçbir yeni altyapı gerektirmez. İncelemesi inanılmaz derecede kolaydır (SELECT * FROM jobs WHERE status = 'failed', herkesin nasıl kullanılacağını zaten bildiği mükemmel bir hata ayıklama aracıdır). Ve düşük hacimlerde, dürüst olmak gerekirse çok uzun bir süre boyunca hiçbir sorun çıkarmadan tıkır tıkır çalışır.

Bir sistemin artık bu yaklaşıma sığmadığını gösteren işaretler genellikle soyut bir "çok fazla hacim (volume)" argümanı değildir. Bunlar çok daha spesifiktir.

Sorgulamanın (Polling) kendisi asıl yüke dönüşür

Her birkaç saniyede bir tabloyu kontrol eden her bir worker, ortada yapacak bir iş olup olmadığına bakılmaksızın bir sorgu (query) çalıştırır. Düşük hacimlerde bu tamamen göz ardı edilebilir bir durumdur.

Ancak tablo büyüdükçe ve iş hacmini (throughput) kaldırmak için daha fazla worker eklendikçe, bu sürekli sorgulama (polling) hali, veritabanı üzerinde istikrarlı ve yıpratıcı bir arka plan yüküne dönüşür. Asıl desteklemesi gereken gerçek uygulama sorgularıyla doğrudan rekabet etmeye başlar. Bunu güvenli bir şekilde yapmanın doğru yolu olan SELECT ... FOR UPDATE SKIP LOCKED komutunu kullansanız bile, bu durum hala her bir worker'ın her döngüde tam olarak aynı tabloyu sürekli çekiçlemesi (hammering) anlamına gelir.

Yeniden deneme (Retry) ve hata yönetimi acı verici şekilde baştan icat edilir

Bir kuyruk tablosunun (queue table) yeniden deneme mantığı genellikle bir retry_count sütunu ve o sayacı artırıp işi yeniden kuyruğa ekleyen, ta ki pes edene kadar bunu tekrarlayan bir uygulama kodundan ibarettir.

Zamanla uç durumlar (edge cases) birer birer özel durum (special case) olarak birikmeye başlar. Başarısız olmadan önce kısmen tamamlanan işler, iki worker aynı anda sorguladığı için kazara iki kez alınan işler veya neden başarısız olduklarını net bir şekilde inceleme yolu olmadan öylece yığılan hatalı işler. Bunlar imkansız problemler değildir, ancak bunlar özel bir mesaj kuyruğunun (message queue) yıllar önce çözdüğü problemlerdir. Onları uygulama kodunda yeniden çözmeye çalışmak, basitçe tüm o uç durumları da acı verici bir şekilde yeniden çözmek anlamına gelir.

RabbitMQ gerçekte neyi değiştirir?

RabbitMQ modeli anket/sorgulama (polling) yönteminden itme (pushing) yöntemine tamamen tersine çevirir. Bir üretici (producer) bir exchange'e bir mesaj yayınlar (publish). RabbitMQ, bağlamalara (bindings) dayanarak onu bir kuyruğa (queue) yönlendirir (route). Ve tüketiciler (consumers), mesajları tekrar tekrar sorup durmak yerine doğrudan onlara ulaştıkça alırlar:

# Producer (Üretici)
channel.basic_publish(
    exchange='',
    routing_key='email_notifications',
    body=json.dumps({'user_id': 123, 'template': 'welcome'}),
    properties=pika.BasicProperties(delivery_mode=2)  # persistent (kalıcı)
)

# Consumer (Tüketici)
def callback(ch, method, properties, body):
    process_notification(json.loads(body))
    ch.basic_ack(delivery_tag=method.delivery_tag)

channel.basic_consume(queue='email_notifications', on_message_callback=callback)

basic_ack sadece mesaj başarıyla işlendikten sonra tetiklenir. Eğer tüketici işlem yapmanın tam ortasında çökerse, mesaj hiçbir zaman onaylanmadığı (acknowledged) için RabbitMQ onu anında yeniden teslim eder. Başarısız olan mesajlar otomatik olarak bir ölü mektup exchange'ine (dead-letter exchange) yönlendirilebilir. Bu size, bu mantığın tek bir satırını bile kendiniz yazmadan, temiz bir şekilde inceleyebileceğiniz tamamen ayrı bir "başarısız olan işler" kuyruğu sunar.

Ne aynı kalır ve ne doğrudan aktarılamaz?

"Bir işin bir yükü (payload) ve bir durumu (status) vardır" zihinsel modeli hiçbir yere gitmez. RabbitMQ bu konsepti değiştirmez; sadece teslimat mekanizmasını değiştirir.

Doğrudan aktarılamayacak olan şey hata ayıklama (debugging) alışkanlığınızdır. SELECT * FROM jobs WHERE status = 'failed' komutu, yerine bir ölü mektup kuyruğunu (dead-letter queue) kontrol etmeye dönüşür. Bunun şekli farklıdır (ancak muhtemelen daha iyidir, çünkü oradaki mesajlar sadece yavaş değil, gerçekten teslim edilemez mesajlardır). Ayrıca, bir veritabanı satırı ve onunla ilgili kuyruk kaydını (queue entry) aynı transaction (işlem) içinde atomik olarak eklemek gibi, kuyruk tablosunun diğer uygulama verileriyle yan yana sorgulanabilir olmasına dayanan her şeyin, kuyruk artık fiziksel olarak ayrı bir sistem olduğu için ciddi şekilde yeniden düşünülmesi gerekir.

Tablonun hala doğru karar olduğu zamanlar

Eğer hacim düşükse, işler inanılmaz derecede basitse ve her birkaç saniyede bir sorgu (poll) atan bir avuç worker veritabanında gözle görülür bir yük yaratmıyorsa, bir kuyruk tablosu kullanmak asla bir hata değildir. Sahip olduğunuz probleme tam olarak uygun boyuttadır.

RabbitMQ'ya geçiş; sorgulama (polling) yükü veritabanı metriklerinde gözle görülür şekilde acı verici hale geldiğinde yapmaya değerdir. Uygulama kodundaki yeniden deneme (retry) ve hata yönetimi, kendi devasa uç durumlar (edge cases) setini yarattığında buna değerdir. Veya, birden fazla farklı servisin aniden tıpatıp aynı olayları (events) üretmesi veya tüketmesi (consume) gerektiğinde kesinlikle buna değerdir. İşte tam o noktada, tam olarak bunun için tasarlanmış bir mesaj aracısı (message broker) "ekstra bir altyapı" olmaktan çıkar ve açık ara çok daha basit bir seçenek haline gelir.

Reklam

Yardıma mı ihtiyacınız var?

Eğer Sunucu Yönetimi ve Bakımı işini sizin yerinize birinin halletmesini tercih ederseniz, benim asıl işim tam olarak bu.

İletişime Geç
ÖncekiÖnbellek Olarak Redis vs Veritabanı Olarak RedisSonraki Yavaş Bir WordPress Sitesini Hızlandırmak: Gerçekte İzlediğim Sıra