RabbitMQ

RabbitMQ uygulamalar arasindaki haberlesmeyi asenkron bir sekilde gerceklestirmek,  daha olceklendirilebilir bir sisteme sahip olmak istenildiginde kullanilan bir Mesaj Kuyrugu sistemidir.

  • Erlang dili ile gelisitirilmistir. Erlang, yogun concurrent islem yapilan, distributed sistemler icin tasarlanan bir dildir. 
  • 2007 yilinda open source olarak yayinlanmistir.
  • Cross platform destekler.
  • Bir cok dil icin destegi vardir.
  • Anlisilir bir arayuze sahiptir.
  • Guzel bir dokumantasyonu vardir.

RabbitMQ temel bilesenleri ve calisma mantigi en temel haliyle Sekil 1’deki gorselden anlasilabilir. Ozetle publisher tarafindan gonderilen mesaji, exchange ilgili queue ya iletir ve o kuyrugu dinleyen consumer tarafindan alip islenir.

Publisher/Producer

RabbitMQ ya mesajlari gonderen taraftir. Mesaj gonderilirken set edilen bazi bilgiler :

  • Exchange = Bu mesaji yonlendirecek exchange bilgisi
  • Rounting Key = Hangi queulara iletilecegini belirten yonlendirme anahtari
  • Content Type = Icerik turu, json payload olan mesajlar icin application/json olarak set edilmelidir.
  • Mandatory = Default olarak “false” set edilir. Gonderilmek istenen mesaj bir sebepten dolayi kuyruga yonlendirilemediginde discard edilir. Eger bu alan “true” olarak set edilirse. Mesaj bir kuyruga yonlendirilemediginde, mesaj geri dondurulur.

Bir mesajin RabbitMQ tarafindan basariyla kabul edildiginden emin olmak icin “confirm.select(Publisher confirms)” mekanizmasi kullanilir. Mesaj gonderildikten sonra, brokerdan Positive Ack(mesaji aldim) bilgisi donerse islem basarilidir. Eger Negative Ack(mesaji alamadim) donerse, loglama veya yeniden gondermeye calisma gibi islemler yapilabilir.

*Producer baglantilari genellikle uygulama ayaga kalkarken acilir ve uygulama calistigi surece yasarlar. Tek bir mesaj yayinlamak icin baglanti acma/kapama dogru bir yaklasim degildir.

Exchange

Gelen mesajlari, iclerindeki routing key ve exchant tipi bilgilerine gore ilgili kuyruklara yonlendiren aractir. 4 adet exchange tipi vardir.

Direct Exchange =Default exchange tipidir. Mesajlar yalnizca routung ile tam olarak eslesen binding keye sahip olan kuyruklara iletilir. Mesajlarin tek bir kuyruga yonlendirilmesi icin idealdir fakat birden cok kuyruga yonlendirmek icin de kullanilabilir.

Sekil 2’deki ornekte 3 farkli routing keyi olan mesaj exchange ‘e gonderilmistir. Exchange yalnizca routing key ile birebir eslesen kuyruklara mesajlari iletmistir. Hatta M1 mesaji iki ayri kuyruga gonderilmistir. Sizin de farkedeceginiz uzere M3 mesajinin keyi birebir eslesmedigi icin herhangi bir kuyruga iletilemedi.

Fanout Exchange = Mesajlar routing keylerine bakilmadan, bu exchange’e bagli tum kuyruklara iletilir. N adet kuyruk bu exchange’e bagliysa, yeni bir mesaj gonderildiginde N tane kuyruga iletilir.

Sekil 3’deki ornekte 2 farkli mesaj exchange’e gonderilmistir. Exchange routing keye bakmadan gelen mesajlari tum kuyruklara iletmistir.

Topic Exchange = En cok tercih edilen exchange tipidir. Mesajlar routing keylerine bakilarak, routing patterni ile eslesen kuyruklara iletilir.

Sekil 4’deki ornekte 2 farkli mesaj exchange’e gonderilmistir. Exchange routing keylere bakti ve M1 mesaji, patternlerine uydugu icin 2 ayri kuyruga iletildi. Fakat M2 mesaji hic bir patterne uymadigi icin iletilemedi.

Header Exchange = Mesajlar header bilgileri icerisindeki ozellikleri ile “x-match” keyi ile eslesen kuyruklara iletilirler. Cok fazla kullanilan bir exchange tipi degildir.

Queue

Kendisine gelen mesajlari dogru bir sekilde consumerlara dagitmaya yarayan aractir. Bir queue tanimlanirken set edilebilen bazi ozellikler:

  • Durability = Kuyruk hakkindaki bilgilerin nerede tutulacaginin ve broker restart oldugunda da kuyrugun kaldigi yerden hayatina devam edip etmeyecegi kararinin verildigi ozelliktir. Durable/Transient olmak uzere iki secenek vardir. Default olarak durable secilidir, kuyruk bilgileri diskte tutulur ve broker restart olsa dahi kuyruk kaybolmaz. Transient de ise ram de saklanir.
  • Exclusivity = Yalnizca bir connection icin kullanilir ve baglanti kapandiginda silinir.
  • Auto-delete = Kuyrugu dinleyen consumer yoksa kuyruk otomatik olarak silinir.
  • Args = Optional olarak set edilirler. Kullandigimiz bir kacina bakalim.
    • Time to live and expiration(TTL) = Bu ozellik ile kuyruktaki mesajlarin belirtilen sure bittikten sonra kuyruktan otomatik silinmesi saglanir. TTL kuyruga veya mesaja set edilebilir.
    • Dead Letter Exchange(DLX) = TTL suresi dolup kuyruktan silinen bir mesajin veya kuyrugun uzunluk limiti asildigi icin drop edilen bir mesajin baska bir kuyruga yonlendirilmesini saglayan ozelliktir.

DLX nedir daha iyi anlamak icin daha once tanimlanan kuyrugu inceleyelim. Sekil 5’de kuyruga dusen mesaj, 25 saniye sonra bu kuyruktan silinecek ve “Merchant-Exchange” icerisindeki, binding keyi “Test.Deneme.CreatedEvent_TryAgain” olan kuyruga iletilecek.

Consumer

Kuyruklari dinleyip, gelen mesajlari islemeye yarayan aractir. Consumerlar kuyruklari dinlemeye baslarken Acknowledgement modu set edilir.

  • Automatic = Mesaji kuyruktan silmek icin consumerdan onay beklemez. Fire and forget seklinde calisir.
  • Manuel = Mesaji kuyruktan silmek icin consumerdan onay bekler. Consumer mesaji isledikten sonra herhangi bir hata almazsa RabbitMQ ya positive ack bilgisini gonderir ve mesaj kuyruktan silinir. Islem sirasinda bir hata alirsa RabbitMQ ya negative ack bilgisini ve mesaji yeniden kuyruga gonderilip gonderilmeyecegi bilgisini gonderir.
channel.basicAck(deliveryTag, true); //Positive ack bilgisini gonderir ve mesaj kuyruktan silinir.

** Nack ve reject arasindaki fark; reject yalnizca bir mesaj icin calisabiliryorken, nack birden fazla mesaj icin calisabilir.

channel.basicReject(deliveryTag, true); //Negative ack ve mesaji yeniden kuyruga al bilgisini gonderir.

channel.basicReject(deliveryTag, false); //Negative ack ve mesaji yeniden kuyruga alma,sal gitsin bilgisini gonderir.

channel.basicNack(deliveryTag, true, true); //Negative ack ve bu delivery tagi olan tum onaylanmamis mesajlari yeniden kuyruga al.