RabbitMQ Nedir

Selamlar,

Bugün RabbitMQ hakkında, hem Windows10 üzerine olan kurulumunu hem de .Net ortamında nasıl çalıştığı konusunu, örnekler ile derinlemesine inceleyeceğiz.

RabbitMQ bir mesaj kuyruğu sistemidir. Benzerleri Apache Kafka, Msmq, Microsoft Azure Service Bus, Kestrel, ActiveMQ olarak sıralanabilir. Amacı herhangi bir kaynaktan alınan bir mesajın, bir başka kaynağa sırası geldiği anda iletilmesidir. Mantık olarak Redis Pub/Sub’a benzemektedir. Ama burada yapılacak işler bir sıraya alınmaktadır. Yani iletimin yapılacağı kaynak ayağa kalkana kadar, tüm işlemler bir quee’de sıralanabilir. Fakat aynı durum Redis Pub’Sub için geçerli değildir. RabbitMQ çoklu işletim sistemine destek vermesi ve açık kaynak kodlu olması da en büyük tercih sebeplerinden birisidir.

Peki neden kullanılmalıdır: Bazı işlemlerin anlık yapılmasına ihtiyaç yoktur. Örnek vermek istenir ise sisteme yeni bir haber girildiğinde, ya da var olan bir haberin güncellenmesi anında cache’in düşürülmesi, bir başka örnek de upload edilen”Gif” dosyalarının scale işleminin yapılması gibi düşünülebilir. Hatta zaman ayarlı message ve otomatik mailler de yine RabbitMq’ya güzel bir örnek olabilir. Sıraya alınan bu işlemlerin asenkron bir şekilde yapılması, hem çalışan uygulamanın boş yere bekletilmemesinden hem de sunucu üzerindeki işlem maliyetinin minimuma indirilmesinden dolayı RabbitMQ iyi bir tercih sebebi olabilir. Ayrıca scalable olmasından dolayı da değişen trafikli yapılarda ayrıca tercih edilebilir.

Öncelikle Windows 10 İşletim Sistemine Kurulum :

  1. RabbitMQ Erlang virtual runtime’da çalışır. Bunun için öncelikle Erlang‘in ilgili link’den yüklenmesi gerekmektedir. Peki Erlang nedir : Ericsson’da çalışan Joe Armstrong, Mike Williams ve Robert Virding in tarafından geliştirilen aynı zamanda message broker olan RabbitMQ için muhteşem bir platform olan bir programlama dilidir.
  2. RabbitMQ ilgili adresden indirlir.

  3. Yukarıdaki kod çalıştırılarak RabbitMQ için gerekli olan pluginlere izin verilir.

4. Son olarak oluşturulan RabbitMQ servisi aşağıda görüldüğü gibi tekrardan başlatılır.

Internet browser’a gelinip http://localhost:15672 yazılır ise aşağıdaki gibi bir monitor ekranı ile karşılaşılır.

Böylece gerekli laboratuvar ortamı hazırlanmış olunur.

Şimdi sıra geldi RabbitMQ’nun çalışma mantığına ve bilinmesi gereken bazı terimlerine:

  • Producer: Mesajı atan kaynak yani uygulamadır. Redis’deki Pub/Sub düşünüldüğünde Publisher tarafıdır.
  • Queue : Gönderilen mesajlar alıcaya ulaştırılmadan önce bir sıraya konur. Gelen yoğunluğa göre veya alıcıya erişilemediği durumlarda, gelen tüm mesajlar Queue’de yani memory’de saklanır. Eğer bu süreç uzun sürer ise memory şişebilir. Ayrıca server’ın restart edilmesi durumunda ilgili mesajlar kaybolabilir.
  • Consumer: Gönderilen mesajı karşılayan sunucudur. Yani Redis Pub/Sub’daki Subscribe’dır. Kısaca ilgili kuyruğu(Queue)’yu dinleyen taraftır.
  • Fifo: RabbitMQ’da giden mesajların işlem sırası first in first out yani ilk giren ilk çıkar şeklindedir.

Producer olarak ilk paketin gönderilmesi [POST]:

Bu örnekde Visual Studio 2015 kullanılarak bir console application yazılmıştır. Öncelikle indirilecek paketler, aşağıdaki gibidir. RabbitMQ.Client ve Newtonsoft.Json Nuget package manager kullanılarak indirilebilir.

Bu örnekde Person tipinde bir sınıf doldurularak “Borsoft” adında bir queue’ye gönderilecektir.

  • ConnectionFactory :RabbitMQ hostuna bağlanmak için kullanılır. Bulunulan sunucudaki host name (localhost),virtual host ve credentials (password) girilir.
  • CreateModel() methodu ile RabbitMQ üzerinde yeni bir channel yaratılır. İşte bu açılan channel yani session ile yeni bir queue oluşturulup istenen mesaj bu channel üzerinden gönderilmektedir.
  • QueueDeclare() methodu ile oluşturulacak olan queue‘nin ismi tanımlanır. “durable” ile in-memory mi yoksa fiziksel olarak mı saklanacağı belirlenir. Genel de RabbitMQ’da hız amcı ile ilgili queuelerin memory’de saklanması tercih edilse de sunucunun restart olması durumunda ilgili mesajların kaybolmasından dolayı da, hızdan ödün verilerek fiziksel olarak bir hard diskte saklanması tercih edilebilir. “exclusive” parametresi ile diğer connectionlar ile kullanılması izni belirlenir. Eğer queue deleted olarak işaretlenmiş ise ve tüm consumerlar bunu kullanmayı bitirmiş ise ya da son consumer iptal edilmiş veya channel kapanmış ise silinmez. İşte bu gibi durumlarda “autoDelete” ile  delete method’u normal olarak çalıştırılır. Ve ilgili queueler silinir. “arguments” Belirlenen exchanges ile alakalı parametrelerdir. Exchangeler birazdan inceleyeceğiz.
  • İlgili doldurulan “Person” sınıfı JsonConvert ile Serialize edilir ve byte[] dizisine çevrilip “body“‘e atanır.
  • BasicPublish() methodu “exchange” aslında mesajın alınıp bir veya daha fazla queue’ya konmasını sağlar. Bu route algoritması exchange tipine ve bindinglere göre farklılık gösterir. “Direct, Fanout ,Topic ve Headers” tiplerinde exchangeler mevcuttur.

Direct exchange: Yapılacak işlere göre bir routing key belirlenir ve buna göre ilgili direct exchange ile amaca en uygun queue gidilir.

Fanout exchange: Burada routing key’in bir önemi yoktur. Daha çok broadcast yayınlar için uygundur. Özellikle (MMO) oyunlarda top10 güncellemeleri ve global duyurular için kullanılır. Yine real-time spor haberleri gibi yayınlarda fanout exchange kullanılır.

Topic Exchange: Bir route mesajın bir veya daha çok queue’ye gitmesi amacı ile kullanılır. Publish/Subscribe pattern’in bir varyasyonudur. Eğer ilgili sorun birkaç consumer’i alakadar ediyor ise, hangi çeşit mesajı almak istediklerini belirlemek için Topic Exchange kullanılmalıdır.

Örnek stok fiyatlarının değişmesi veya arkada çalışan birkaç farklı task process’in farklı workerlar ile tamamlanması ve hangi taskin hangi worker tarafından ele alınması gibi durumlarda kullanılır.

Headers Exchange: Yine bu exchange de routing key’i kullanmaz ve message headers’daki birkaç özellik ve tanımlama ile doğru queue’ye iletim yapar. Header üzerindeki attributeler ile  queue üzerindeki attributelerin, tamamının değerlerinin birbirini tutması gerekmektedir. Bir tanımlamada Header Exchange’in Direct Exchange’in Steroidli hali dendiğini gördüm :)

“BasicPublish() methoddaki routingKey” : Girilen key’e göre ilgili queue’ye gidilmesi sağlanır. “body:” Queue’ye gönderilecek mesaj byte[] tipinde gönderilir. Mesaj denince aklınıza sadece Text gelmesin. Her türlü object’i gönderebiliriz. Örneğin bu uygulamada “Person” class’ı gönderilecektir.

Gönderme işleminden sonraki Monitor ekranınındaki Queue’lerin görüntüsü aşağıdaki gibidir: Görüldüğü gibi “Borsoft” isimli queue’de gönderilmeyi bekleyen 1 paket bulunmaktadır. Çünkü henüz consumer uygulamasını çalıştırmadık. Ve hiç bir paket henüz iletilmedi.

Consumer olarak Queue’den ilgili paketin alınması [RECEIVE] :

Receive işleminde bağlanılacak host(“localhost”) ve Queue (“Borsoft”) belirlendikten sonra “consumer.Received” event sayesinde ilgili queue sürekli bir dinleme modunda olacaktır. İlgili mesaj geldiğinde öncelikle “byte[]” dizisi olarak alınan mesaj string bir veriye çevrilecek daha sonra “deserialize” işlemi ile beklenen “Person” sınıfına dönüştürülecektir.

channel.BasicConsume(): Methodu ile ilgili Queue’den mesajları çekme işlemine başlanır. Burada noAckparametresi true olarak atanır ise, ilgili mesaj alındıktan sonra Queue’den otomatik olarak silinir.

İlgili code çalıştırıldığında aşağıdaki gibi bir sonuç ekranı alınır:

Ayrıca monitor ekranına bakılır ise ilgili Queue’nin ilgili consumer’a iletiminden sonra silindiği görülür:

RabbitMQ günümüzün en populer mesaj kuyruğu sistemlerinden biri demek hiç de yanlış olmaz. Apache Kafka kadar hızlı olmasa da Erlang ile yazılmış olması, inanılmaz esnek bir yapısı olması, tamamı ile transactional olması, istenirse queuelerin bir storageda da saklanabilmesi ve muhteşem pluginleri ile benim favorim diyebilirim.

Böylece geldik bir makalenin daha sonuna. Yeni bir makalede görüşmek üzere hoşçakalın.

Herkes Görsün:

Bunlar da hoşunuza gidebilir...

2 Cevaplar

  1. Yunus dedi ki:

    Hocam merhaba,sizin bir projeniz vardı.İşe alınma projesi.Merkez bankasından veri çekiyordunuz,
    O konunun linkini bulamadım.Link verebilirmisiniz?
    Teşekkür Ederim

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir