RabbitMQ Temelleri
RabbitMQ, AMQP (Advanced Message Queuing Protocol) protokolünü implemente eden, açık kaynaklı ve en yaygın kullanılan message broker'lardan biridir. Erlang dili ile yazılmıştır ve yüksek güvenilirlik, esneklik ve geniş dil desteği sunar. Bu derste RabbitMQ'nun temel kavramlarını, exchange türlerini, kuyruk mekanizmalarını ve mesaj yaşam döngüsünü detaylıca inceleyeceğiz.
AMQP Protokolü
AMQP (Advanced Message Queuing Protocol), mesaj aracıları için tasarlanmış açık standart bir uygulama katmanı protokolüdür. AMQP şunları tanımlar:
Mesaj formatı: Header, properties ve body bölümlerinden oluşan standart yapı
Exchange ve Queue mekanizmaları: Mesajların nasıl yönlendirileceği
Connection ve Channel modeli: TCP bağlantısı üzerinden çoklu sanal kanallar
Güvenilirlik mekanizmaları: Acknowledgement, transaction, persistence
AMQP'nin önemli bir özelliği wire-level protocol olmasıdır — yani farklı dillerde yazılmış uygulamalar sorunsuz iletişim kurabilir. Java producer'ınız Python consumer'a mesaj gönderebilir.
┌─────────────┐ TCP Connection
│ Application │ ─────────────────────▶ ┌──────────────┐
│ │ Channel 1 ──────────▶│ │
│ (Producer/ │ Channel 2 ──────────▶│ RabbitMQ │
│ Consumer) │ Channel 3 ──────────▶│ Broker │
│ │ │ │
└─────────────┘ └──────────────┘Connection: Uygulama ile broker arasındaki TCP bağlantısıdır. Maliyetli bir işlemdir (TCP handshake, TLS).
Channel: Bir connection içindeki hafif sanal bağlantıdır. Her thread kendi channel'ını kullanır. Connection oluşturmak pahalı olduğu için, tek bir connection üzerinden birçok channel açılır.
RabbitMQ Mimarisi: Exchange → Binding → Queue
RabbitMQ'da mesaj akışı şu şekilde çalışır:
Producer ──msg──▶ Exchange ──routing──▶ Queue ──msg──▶ Consumer
│ ▲
└─binding─┘
(routing key + pattern)Producer mesajı bir exchange'e gönderir (doğrudan kuyruğa değil).
Exchange, mesajın routing key'ine ve binding kurallarına bakarak mesajı uygun kuyruğa/kuyruklara yönlendirir.
Queue mesajı saklar ve consumer'a teslim eder.
Bu üç katmanlı mimari büyük esneklik sağlar: producer kuyruğu bilmez, exchange yönlendirme mantığını soyutlar.
Exchange Türleri
RabbitMQ dört farklı exchange türü sunar:
1. Direct Exchange
Mesajın routing key'i ile queue'nun binding key'i tam eşleştiğinde mesaj o kuyruğa yönlendirilir. En basit ve en yaygın kullanılan türdür.
Producer ──routing_key="order.created"──▶ [Direct Exchange]
│
binding_key="order.created" ──▶ Queue-A ✓
binding_key="payment.done" ──▶ Queue-B ✗Kullanım alanı: Belirli bir kuyruğa hedefli mesaj gönderme. Örneğin, hata loglarını "error-queue"ya, bilgi loglarını "info-queue"ya yönlendirme.
2. Topic Exchange
Pattern matching ile yönlendirme yapar. Routing key nokta (.) ile ayrılmış kelimelerden oluşur. Binding key'de iki özel karakter kullanılır:
*(yıldız): Tam olarak bir kelimeyle eşleşir#(diyez): Sıfır veya daha fazla kelimeyle eşleşir
Routing key: "order.eu.created"
Binding "order.*.created" → ✓ eşleşir (eu tek kelime)
Binding "order.#" → ✓ eşleşir (eu.created sıfır veya daha fazla)
Binding "order.us.created" → ✗ eşleşmez (us ≠ eu)
Binding "#.created" → ✓ eşleşirKullanım alanı: Hiyerarşik routing. Örneğin log.error.payment, log.warn.auth gibi yapılarla farklı aboneleri farklı log seviyelerine yönlendirme.
3. Fanout Exchange
Routing key'i tamamen yok sayar ve mesajı kendisine bağlı tüm kuyruklara kopyalar. Klasik broadcast mekanizmasıdır.
Producer ──▶ [Fanout Exchange] ──▶ Queue-A (kopya)
──▶ Queue-B (kopya)
──▶ Queue-C (kopya)Kullanım alanı: Bir olayın birden fazla servise bildirilmesi gerektiğinde. Örneğin, kullanıcı kaydı sonrası e-posta servisi, analitik servisi ve CRM servisi hepsine bildirim.
4. Headers Exchange
Routing key yerine mesajın header değerlerine göre yönlendirme yapar. Binding'de x-match parametresi ile eşleşme kuralı belirlenir:
x-match = all: Tüm belirtilen header'lar eşleşmeli (AND)x-match = any: Herhangi bir header eşleşmeli (OR)
Message headers: {format: "pdf", type: "report"}
Binding {x-match: all, format: "pdf", type: "report"} → ✓ eşleşir
Binding {x-match: any, format: "pdf", type: "invoice"} → ✓ eşleşir (format eşleşti)
Binding {x-match: all, format: "csv", type: "report"} → ✗ eşleşmez (format farklı)Kullanım alanı: Karmaşık yönlendirme kuralları gerektiğinde, routing key yetmediğinde kullanılır. Pratikte en az kullanılan exchange türüdür.
Queue Özellikleri
Queue (kuyruk), mesajların FIFO (First-In-First-Out) sırasıyla depolandığı yapıdır. Önemli özellikleri:
Durable: Broker yeniden başladığında kuyruk kaybolmaz. Production ortamında mutlaka
durable=trueolmalıdır.Exclusive: Yalnızca bir connection tarafından kullanılabilir, connection kapanınca kuyruk silinir. Geçici, özel kullanım için.
Auto-delete: Son consumer ayrıldığında kuyruk otomatik silinir.
TTL (Time-to-Live): Mesajların kuyrukta ne kadar süre kalacağını belirler. Süresi dolan mesajlar otomatik silinir veya dead letter queue'ya yönlendirilir.
Max-length: Kuyrukta tutulabilecek maksimum mesaj sayısı. Aşıldığında en eski mesajlar düşürülür veya dead letter queue'ya gönderilir.
Routing Key ve Binding
Routing key, producer'ın mesajla birlikte gönderdiği bir string'dir. Exchange, bu key'i kullanarak mesajı hangi kuyruğa yönlendireceğine karar verir.
Binding, exchange ile queue arasındaki bağlantı kuralıdır. Bir queue birden fazla exchange'e, bir exchange birden fazla queue'ya bind edilebilir.
// Direct exchange ile binding
channel.queueBind("email-queue", "notification-exchange", "email");
channel.queueBind("sms-queue", "notification-exchange", "sms");
// Producer routing key ile mesaj gönderir
channel.basicPublish("notification-exchange", "email", null, message.getBytes());
// → email-queue'ya gider
channel.basicPublish("notification-exchange", "sms", null, message.getBytes());
// → sms-queue'ya giderAcknowledgement (Mesaj Onayı)
RabbitMQ'da mesaj tesliminin güvenilirliği acknowledgement mekanizmasıyla sağlanır:
Consumer acknowledgement: Consumer, mesajı başarıyla işlediğinde broker'a ACK gönderir. ACK gelene kadar mesaj kuyruktan silinmez.
basicAck: Mesaj başarıyla işlendi, kuyruktan silinebilir.basicNack: Mesaj işlenemedi, tekrar kuyruğa konabilir (requeue) veya düşürülebilir.basicReject: Tek mesaj için nack — benzer şekilde requeue veya drop.
// Manuel acknowledgement
channel.basicConsume("orders", false, (consumerTag, delivery) -> {
try {
processOrder(delivery.getBody());
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
} catch (Exception e) {
// Mesajı tekrar kuyruğa koy (requeue=true)
channel.basicNack(delivery.getEnvelope().getDeliveryTag(), false, true);
}
}, consumerTag -> {});Publisher confirm: Producer tarafında da onay alınabilir. Broker mesajı diske yazıp kuyruğa ekledikten sonra producer'a confirm gönderir. Bu, mesajın broker'a ulaştığından emin olmanızı sağlar.
Dead Letter Queue (DLQ)
Dead Letter Queue, işlenemeyen veya reddedilen mesajların yönlendirildiği özel bir kuyruktur. Bir mesaj şu durumlarda "dead letter" olur:
Consumer mesajı
rejecteder verequeue=falsebelirtirMesajın TTL'i dolar
Kuyruk maksimum uzunluğa ulaşır ve eski mesajlar düşürülür
// DLQ yapılandırması
Map<String, Object> args = new HashMap<>();
args.put("x-dead-letter-exchange", "dlx-exchange");
args.put("x-dead-letter-routing-key", "dead-orders");
args.put("x-message-ttl", 60000); // 60 saniye TTL
channel.queueDeclare("orders", true, false, false, args);DLQ stratejisi, production sistemlerinde olmazsa olmaz bir bileşendir. İşlenemeyen mesajları kaybetmek yerine DLQ'ya yönlendirip, sonra analiz ederek sorunu çözmek en güvenilir yaklaşımdır. Monitoring araçlarıyla DLQ'daki mesaj sayısını izlemek, sistemdeki sorunları erken tespit etmenizi sağlar.
RabbitMQ Management UI
RabbitMQ, web tabanlı bir yönetim arayüzü sunar (varsayılan port: 15672). Bu arayüzden:
Exchange, queue ve binding'leri görsel olarak yönetebilir
Mesaj oranlarını (message rate) izleyebilir
Kuyruk derinliklerini (queue depth) kontrol edebilir
Manuel olarak mesaj yayınlayabilir veya kuyruktan mesaj okuyabilirsiniz
Docker ile hızlıca başlatmak için:
docker run -d --name rabbitmq \
-p 5672:5672 \
-p 15672:15672 \
rabbitmq:3-management
# Management UI: http://localhost:15672 (guest/guest)
AI Asistan
Sorularını yanıtlamaya hazır