RabbitMQ #5 — Topic Exchange
Merhaba! RabbitMQ serimizin bu bölümünde, belki de en esnek olan Exchange türü olan Topic Exchange’leri ele alacağız. Topic Exchange, Direct ve Fanout Exchange’lerin en iyi özelliklerini birleştirir, bunlar üzerine daha fazla esneklik ekler ve karmaşık mesaj rota senaryolarını destekler.
Topic Exchange Nedir?
Topic Exchange, mesajları routing key ile belirlenen kuyruklara gönderir, ancak bu keyin tam bir eşleşme yerine bir model eşleşmesi olmasına izin verir. Bu, routing key’nin belirli bir yapıyı takip etmesini ve her bileşenin belirli bir anlam taşıdığı durumlar için kullanışlıdır.
Routing key, bir dizi kelimenin nokta (.) ile ayrıldığı bir stringdir, örneğin animal.rabbit.white
veya quick.orange.rabbit
. Bununla birlikte, Topic Exchange, bu kelimelerin bazılarını joker karakterlerle (*
ve #
) eşleştirerek belirli bir modelle eşleşme sağlar:
*
: Tam olarak bir kelimeyi eşleştirir. Örneğin,animal.*.white
routing key'ine eşleşen mesajlaranimal.rabbit.white
veyaanimal.fox.white
olabilir amaanimal.big.rabbit.white
olamaz.#
: Bir veya daha fazla kelimeyi eşleştirir. Örneğin,animal.#
routing key'ine eşleşen mesajlaranimal.rabbit
,animal.rabbit.white
veyaanimal.big.rabbit.white
olabilir.
Topic Exchange ile Mesaj Yönlendirme
Topic Exchange’ler, bir mesajın birden fazla kuyruğa gitmesini sağlar (Fanout Exchange gibi), ancak mesajların hangi kuyruklara gideceği konusunda daha fazla kontrol sağlar (Direct Exchange gibi).
Topic Exchange’leri kullanmanın bir avantajı, bir dizi ilgili kuyruğa aynı anda mesaj gönderme yeteneğidir. Örneğin, bir uygulamanın belirli bir kategorideki tüm hataları loglaması gerektiğini düşünün. Bu durumda, uygulama her hatayı ilgili kategoriye (errors.database
, errors.network
, vb.) gönderebilir ve bir Topic Exchange kullanarak tüm errors.*
hatalarını bir kuyruğa yönlendirebilir.
Bununla birlikte, bir uygulamanın sadece belirli bir tür hatayı loglaması gerektiğini düşünün. Bu durumda, uygulama belirli bir hata türünü (errors.database.deadlock
, errors.network.timeout
, vb.) gönderebilir ve bir Topic Exchange kullanarak sadece errors.database.*
hatalarını bir kuyruğa yönlendirebilir.
Topic Exchange’lerin sunduğu bu esneklik, mesajları belirli kuyruklara dinamik bir şekilde yönlendirme yeteneği sayesinde karmaşık mesaj rotalama senaryolarını destekler.
Topic Exchange ile RabbitMQ’da Yayıncı ve Tüketici Oluşturma
Topic Exchange ile bir yayıncı ve tüketici oluşturmanın nasıl çalıştığını göstermek için bir örneğe bakalım. Bu örnekte, bir hava durumu uygulaması oluşturacağız. Uygulama, belirli bir bölge ve hava durumu türü için hava durumu güncellemeleri yayınlar.
Aşağıdaki örnekte, belirli bir bölge ve hava durumu türü için hava durumu güncellemeleri gönderen bir yayıncı oluşturuyoruz.
Yayıncı Oluşturma
var factory = new ConnectionFactory() { HostName = "localhost" };
using(var connection = factory.CreateConnection())
using(var channel = connection.CreateModel())
{
channel.ExchangeDeclare("weather_updates", "topic");
var routingKey = "europe.rainy"; // Avrupa bölgesi, yağmurlu hava
var message = "It is raining in Europe.";
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish("weather_updates", routingKey, null, body);
Console.WriteLine(" [x] Sent '{0}':'{1}'", routingKey, message);
}
Bu yayıncı, europe.rainy
routing key'i ve It is raining in Europe.
mesajı ile bir güncelleme gönderir. Buradaki "weather_updates" exchange'ini "topic" olarak tanımlıyoruz.
Tüketici Oluşturma
Topic Exchange’lerin gerçek gücü, tüketicinin belirli bir modeli takip edebilmesidir. Örneğin, bir tüketici yalnızca Avrupa’daki hava durumu güncellemelerini alabilir:
var factory = new ConnectionFactory() { HostName = "localhost" };
using(var connection = factory.CreateConnection())
using(var channel = connection.CreateModel())
{
channel.ExchangeDeclare("weather_updates", "topic");
var queueName = channel.QueueDeclare().QueueName;
channel.QueueBind(queue: queueName,
exchange: "weather_updates",
routingKey: "europe.*");
Console.WriteLine(" [*] Waiting for logs.");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (model, ea) =>
{
var body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
var routingKey = ea.RoutingKey;
Console.WriteLine(" [x] Received '{0}':'{1}'", routingKey, message);
};
channel.BasicConsume(queue: queueName,
autoAck: true,
consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}
Bu tüketici, europe.*
modeline uyan her mesajı alır. Bu, tüketiciye yalnızca Avrupa bölgesi için hava durumu güncellemelerini alabilme esnekliğini verir.
Bu örnekte, bir Topic Exchange’in nasıl çalıştığını ve ne tür senaryolarda kullanışlı olabileceğini gördük. Bir sonraki makalemizde, Header Exchange’leri ele alacağız.
Sonuç
Bu makalede, RabbitMQ’nun konu tabanlı (topic) Exchange özelliğinin nasıl kullanılacağını tartıştık. Bu Exchange türü, mesajların belirli bir model veya şablonla eşleşen kuyruklara yönlendirilmesini sağlar.
Yayıncı tarafından, bir bağlantı oluşturulur ve Exchange tanımlanır. Sonrasında belirli bir yönlendirme anahtarı (routing key) ile bir mesaj yayınlanır.
Tüketici tarafında da bir bağlantı oluşturulur, aynı Exchange tanımlanır ve bir kuyruk oluşturulur. Bu kuyruk, belirli bir model ile Exchange’ye bağlanır ve bu modeli eşleşen mesajları alır.
Bu yaklaşım, yayıncıdan gelen mesajların belirli bir modeli takip eden birden fazla kuyruğa gönderilmesine olanak sağlar, böylece daha esnek bir mesaj dağıtımı sağlanmış olur.
Bu makalede, Avrupa’daki yağışlı hava durumu güncellemelerini takip eden bir senaryo üzerinde durduk. Bu senaryo, bir yayıncının belirli bir bölge ve hava durumu için güncellemeler gönderdiğini ve bir tüketici uygulamanın bu güncellemeleri aldığını göstermektedir.
Sonuç olarak, bu makalede RabbitMQ’nun Topic Exchange özelliğinin nasıl kullanılacağını ve bu özelliğin mesajların belirli bir modeli takip eden kuyruklara yönlendirilmesine nasıl olanak sağladığını öğrendik. Bu konunun üzerinde daha fazla duracağız ve bir sonraki bölümde Header Exchange özelliğini ele alacağız.