RabbitMQ Zero to Hero

Ahmet Murat Gençay
7 min readOct 24, 2020

RabbitMQ hakkında örnek uygulamalar. RabbitMQ ile ilgili kavramları temel seviyeden ileri seviyelere kadar anlatırken kendi örneklerim ile konuyu pekiştireceğim. RabbitMQ .net kütüphanesini uyarladığım ve verilen örneklerin kolay anlaşılması için oluşturduğum yardımcı sınıflar ile anlatımı gerçekleştireceğim. Her örneği github’da bulabilirsiniz.

RabbitMQ Nedir?

RabbitMQ yaygın olarak kullanılan open source bir mesaj broker uygulamasıdır. Queue(Kuyruk) yapısı ile çalışır. Küçük ölçekli uygulamalardan kurumsal uygulamalara kadar bir çok kullanım alanı mevcuttur. Cloud ve on-premises ortamlarda deploy edilebilir ve çoklu mesajlaşma protokollerini destekler. Distributed çalışma imkanı sağlar ve işletim sistemi bağımsız çalışır.

Ne zaman kullanılır?

Özellikle mikro servis uygulamalarının artması ile sistemlerin bağımlılıkları azaldı ve daha light yapılar ile uygulamalar geliştirilmeye başlandı.

Bu avantajların yanında uygulamaları küçük parçalara bölmek, bu parçaların yönetilmesi ve haberleşmesi gibi sorunlar ortaya çıkardı. Yanlış tasarımlar sonucu mikro servisler, gelen isteklerin yükü ile performans kaybı yaşamaya başladı. İşte bu noktada RabbitMQ bize gerek geleneksel uygulamalarda asenkron işlemler için gerek mikro servisler arasındaki haberleşme ve performans artırımı için kolaylıklar sağlamaktadır.

Örnek olarak bir alışveriş uygulamasında, siparişi tamamla işlemini başlattığınızda kullanıcıyı tüm işlemler bitene kadar bekletmek yerine, bu işlemi arka planda yönetip kullanıcıya daha hızlı cevap verilebilir.

Simple Queue

RabbitMQ mesaj yöneticisidir. Mesajları alır ve yönlendirir. Posta ofisi gibi düşünülebilir. Postayı gönderdikten sonra önünde sonunda posta alıcıya ulaşacaktır. Bu bağlamda RabbitMQ hem posta kutusu hem postacı hem de posta ofisi görevini yerine getirir.

RabbitMQ ile ilgili genel kavramlar.

  • Producer: Mesaj gönderen uygulama.
  • Queue: Mesajın gönderildiği posta kutusu.
  • Consumer: Mesajı alan uygulama.

Bu parçalar farklı uygulama sunucuları üzerinde olabilir. RabbitMQ dağıtık sistemler ile çalışmaya imkan sağlar

Simple Queue

Simple Queue Clock Example

Simple Queue — Clock Example
Simple Queue — Clock Publisher Code
Simple Queue — Clock Consumer Code

Work Queues

İlk uygulamamızda, saat bilgisini “clock” kuyruğuna gönderen ve bu kuyruktan gelen mesajı kendi saat bilgisi ve farkıyla ekrana yazan bir uygulama oluşturmuştuk. Bu sefer ki uygulama örneğimizde rastgele sayılar üretip “prime” adında bir kuyruğa yolladıktan sonra birden fazla alıcı ile bu sayının asallık kontrolünü yapacağız.

Work Queues(Task Queues) kavramının asıl amacı yoğun iş gücü gerektiren durumlarda işlemin bitmesini beklemekten kaçınmaktır. Bunun yerine işlemin daha sonra tamamlanmasını sağlayacak yapı kurulur. Yapılmasını istediğimiz işlemi paketleyip kuyruğa göndeririz. Arka planda çalışan bir worker process(İşçi) görevi açar ve işlemi gerçekleştirir. Birden fazla işçi olduğunda görevler aralarında paylaştırılır.

Bu kavram, özellikle kısa bir HTTP istek sırasında karmaşık bir görevi gerçekleştirmenin imkansız olduğu web uygulamalarında kullanışlıdır.

Work Queues

Work Queues Prime Number Example

Work Queues — Prime Example
Work Queues — Prime Publisher Code
Work Queues — Prime Consumer Code

Publish/Subscribe

Önceki örneğimizde bir iş kuyruğu oluşturmuştuk. İş kuyruğunun ana amacı her görevin yalnızca bir işçiye gönderilmesidir. Bu örneğimizde ise farklı bir yapı kuracağız ve bir görevin birden fazla işçiye gönderilmesini sağlayacağız. Bu yapı, “publish/subscribe”(“yayınla / abone ol”) olarak adlandırılır.

Yapıyı göstermek için basit bir dizi sıralama sistemi oluşturacağız. Sistem üç uygulamadan oluşacak. Birincisi rastgele sayılardan oluşan bir dizi oluşturup gönderecek, diğerleri ise biri quick sort ile diğeri bubble sort ile diziyi sıralayarak ekrana yazacak ve geçen süreyi hesaplayacak.

Örneğimizde, alıcı uygulamaların ikisi de gönderilen mesajları alacaktır. Bu şekilde bir problemin çözümünü farklı uyarlamalar ile eşzamanlı gerçekleştirebiliriz.

Temelde bu işlem broadcast(canlı yayın) sistemi olarak düşünülebilir.

Exchanges

Önceki bölümlerde, bir kuyruktan mesajlar gönderip aldık. Şimdi RabbitMQ ile full messaging yapısını gerçekleştireceğiz. Bu yapıdaki ana fikir, mesaj gönderen uygulamanın mesajı doğrudan bir kuyruğa değil yönlendirici(exchange) mekanizmasına göndermesidir.

Exchange(Yönlendirici) çok basit anlamda router görevi görür. Bir taraftan producer üzerinden gelen mesajları alır ve diğer taraftan bu mesajları ilgili kuyruk veya kuyruklara yönlendirir. Exchange gelen mesajı nasıl yönlendireceğini bilmelidir. Mesajı doğrudan tek bir kuyruğa mı, birden fazla kuyruğa mı göndereceğini yada iptal edeceğini önceden configure etmemiz gerekir. Bu ayar ise Exchange Type ile gerçekleştirilir.

Exchange Type

  • Direct Exchanges: Doğrudan ilgili kuyruğa yönlendirme mekanizması. Queue Name ile çalışır.
  • Fanout Exchanges: Tüm kuyruklara canlı yayın mekanizması.
  • Topic Exchanges: Belirli bir path yapısı ile ilgili kuyruk veya kuyruklara yönlendirme yapan mekanizma. Routing Key ile çalışır.
    “*.green.*” ortasında green olanlar,
    “#” tüm istekler,
    “#.animal”, animal ile bitenler. vb…
  • Header Exchanges: İstekteki header kısmındaki key-value alanları ile yönlendirme yapan mekanizma. Topic exchange ile benzer yapıdadır yalnızca path yapısı header’daki alanlar üzerinden oluşturulur.
Publish/Subscribe

Publish/Subscribe Sort Example

Publish/Subscribe — Array Sort Example
Publish/Subscribe — Array Sort Publisher Code
Publish/Subscribe — Quick Sort Consumer Code

Routing

Önceki örneğimizde basit bir dizi sıralama sistemi oluşturmuştuk. Rastgele sayılardan oluşan bir diziyi birden fazla consumer’a canlı yayın yapmıştık.

Bu örneğimizde consumerların kendileri ile ilgili mesajları aldığı bir sistem oluşturacağız. Bunun için basit bir hesap makinası uygulaması oluşturacağız. Publisher rastgele iki sayı ve rastgele bir işlem(add,sub,mul,div) oluşturacak daha sonra bu veriyi paketleyerek ilgili kuyruğa yönlendirilmesini sağlayacağız. Consumer tarafı ise kendisine gelen sayılar ile ilgili işlemi gerçekleştirerek ekrana yazacak.

Örneğimizdeki yönlendirme işlemlerini Direct Exchange yapısı ile kuracağız buna göre Routing Key alanına hangi işlemi verirsek yalnızca o key ile çalışan kuyruğa istek düşecek.

Bindings

Binding exchange ile queue arasındaki ilişki yapısıdır. Basitçe kuyruğun exchange deki hangi mesajlar ile ilgileneceğini tanımlarız. Direct Exchange yapısında kuyruğu routing key ile ilişkilendiririz. Fanout yapısında routing key alanı boş bırakılır çünkü mesaj tüm consumerlara iletilecektir.

Direct exchange

Direct Exchange

Multiple bindings

Multiple Bindings

Aynı routing key’i birden fazla kuyruğa bağlayabiliriz. Bu yapı aslında Fanout’a karşılık gelir ve sistem broadcast ile çalışır. Ya da bir kuyruğa birden fazla routing key bağlayabiliriz.

Routing

Routing Calculator Example

Routing — Calculator Example
Routing — Calculator Publisher Code
Routing — Calculator Add Consumer Code
Routing — Calculator Sub Consumer Code
Routing — Calculator Mul Consumer Code
Routing — Calculator Div Consumer Code

Topics

Önceki örneğimizde hesap makinası uygulaması geliştirdik. Fanout exchange type’ı yerine direct kullandık ve yalnızca ilgili consumer’ın mesajı almasını sağladık.

Direct exchange bize yönlendirme mekanizması için kolaylıklar sağlasa da hala bazı kısıtlarımız var. Örneğin çoklu kriter yapısına sahip değiliz tek bir kriter ile ilgili kuyruğa yönlendirme yapıyoruz.

Topic exchange

Topic exchange ile gönderilen mesajlar noktalar ile ayrılmış kelimelerden oluşan routing key ile çalışır. Örneğin “stock.usd.nyse”, “nyse.vmw”, “quick.orange.rabbit”. Burada limitimiz 255 byte’dır.

Buradaki kısıdımız sistemdeki routing keyler aynı formatta olmalıdır. Aynı direct exchangedeki gibi topic exchange’te de mesajlar ilgili kuyruklara eşleşen routing key ile iletilir.

Özel karakterler:

  • * (star) karakteri doğrudan bir kelimeye karşılık gelir.
  • # (hash) karakteri bir veya birden fazla kelimeye karşılık gelir.
Topics

Yukarıdaki örnekte yapısı “<speed>.<colour>.<species>” şeklinde olan bir routing key yapısı vardır:

  • Q1 tüm turuncu renkli türler ile ilgilenir.
  • Q2 tüm tavşanlar ve yavaş olan her şey ile ilgilenir.

Topics Observer Example

Topics — Observer Example
Topics — Observer Publisher Code
Topics — Observer Consumer Code

RPC(Remote Procedure Call)

İkinci örneğimizde, zaman alan görevleri birden çok çalışan arasında dağıtmak için İş Kuyruklarının nasıl kullanılacağını öğrendik.

Peki ya uzak bir bilgisayarda bir işlevi çalıştırmamız ve sonucu beklememiz gerekirse? Bu yapı genellikle Uzaktan Prosedür Çağrısı veya RPC olarak bilinir.

Bu örnekte bir server ve ölçeklenebilir birden fazla client ile RPC sistemi kuracağız. Singleton design patterni ile client uygulamaların aynı counter değeriyle çalışmaları sağlayacağız.

Client interface

Bir RPC hizmetinin nasıl kullanılabileceğini göstermek için basit bir client sınıfı oluşturacağız.

Callback queue

Genel olarak RabbitMQ üzerinden RPC yapmak kolaydır. Client bir mesaj gönderir ve sunucu bir yanıt mesajı ile yanıt verir. Bir yanıt almak için istekle birlikte bir “callback” kuyruk adresi göndermemiz gerekir:

RPC

RPC Singleton Example

RPC Singleton Counter Queue Example
RPC — Singleton Example
RPC — Singleton Publisher Code
RPC — Singleton Consumer Code

Publisher Confirms

Publisher confirms, güvenilir yayınlamayı uygulamak için bir RabbitMQ extentions’ıdır. Publisher confirms bir kanalda etkinleştirildiğinde, istemcinin yayınladığı mesajlar aracı tarafından asenkron olarak onaylanır, yani sunucu tarafında ilgilenildiği anlamına gelir.

Bu örnekte builder design patterni ile iki adet menüyü farklı yiyecek ve içecekler ile oluşturan bir uygulama yazacağız. Meal Consumer, VegMeal(VegBurger, Pepsi) ve NonVegMeal(ChickenBurger, Coke) olacak şekilde iki menü isteğinde bulunan bir uygulamadır. Burger Publisher kendisine gelen isteğe göre iki farklı burger oluşturur ve döner. Drink publisher ise aynı şekilde gelen istekteki değere göre iki içecekten birini oluşturur ve döner.

Burada Publisher confirms yapısı bize karmaşık bir modelin oluşturulması sırasında tüm alt modellerin oluşturulduğunu garanti eder. Yani VegMeal oluşturulması için VegBurger ve Pepsi oluşturulana kadar bekler.

Publisher Confirms Meal Service Example

Publisher Confirms — Meal Builder Example
Publisher Confirms — Burger Publisher Code
Publisher Confirms — Drink Publisher Code
Publisher Confirms — Meal Consumer Code

Başka yazılarda görüşmek üzere.

Referanslar

  1. RabbitMQ
  2. Queue
  3. AMQP RabbitMQ
  4. Basic Queue RabbitMQ
  5. Work Queue RabbitMQ
  6. Publish/Subscribe RabbitMQ
  7. Routing RabbitMQ
  8. Topics RabbitMQ
  9. RPC RabbitMQ
  10. Publisher Confrims RabbitMQ
  11. Exchange Types
  12. Builder Pattern
  13. Strategy Pattern
  14. Observer Pattern
  15. Singleton Pattern
  16. Quick Sort
  17. Bubble Sort
  18. Prime Numbers
  19. RPC
  20. RabbitMQ Extentions

--

--