Uygulamalar arası iletişimi veya uygulamanın asenkron olarak yapacağı işleri yöneten araçtır. Genelde RabbitMQ, Kafka kullanılanılıyor fakat konu sadece asenkron işlerin yapılması ise burada veritabanı veya Redis gibi araçlarıda kullanabiliriz.
Ne Yapar?
Bir mesajı başka bir uygulamanın veya asenkron işlemlerin gerçekleşmesi için kuyruğa alır. Bu mesaj bir işi tanımlayabilir veya işin gerçekleşmesi için gerekli bilgiyi içerebilir. İlk giren ilk çıkar(FIFO) mantığında işleyen kuyruklar kendilerini dinleyen tüketiciler(Consumer) tarafından tüketilirler ve yapması gereken işleri gerçekleştirirler.
Message broker mesajı gönderenin(Producer), gönderdiği mesajı ilgili kuyruğa yönlendirmekle sorumludur. Message broker içerisinde bulundurduğu exchange mekanizması ile gelen mesajın hangi kuyruğa gitmesi gerektiğini mesajın header bilgisi üzerinden veya exchange tipine göre belirler.
Producer -> Message Broker -> Consumer Temelde basit 3 bileşenden oluşuyor.
Çok basit bir örnekle; uygulamanıza kayıt olan kullanıcılara hoş geldin maili atmak istiyorsunuz. Kayıt olma işlemi aslında bir olaydır(Event) bu olayı dinleyen dinlecileriniz(Listener) bu olayı yakalar ve Producer‘a iletir . Producer bu mesajı Low-Level bir kuyruğa iletmek üzere Message broker’a gönderir. Message broker bu mesajın header bilgisinden ve exchange tipine göre hangi kuyruğa gitmesi gerektiğini belirler ve o kuyruğa gönderir. Mesajın gönderildiği kuyruğu dinleyen işçileriniz(Consumer) maili hazırlar ve gönderir. Mesaj içeriği bir olay adı ve olay ile ilgili verileri içerebilir.
Event->Listener->Producer->Message Broker->Exchange->Queue->Consumer şeklinde bir akışı ifade edebiliriz.
Neden?
Kaynak kullanımlarını optimize etmek veya uygulamalarınız(hizmetleriniz) arasında düşük bağımlılık sağlayabilirsiniz. Kullanıcı sayınız arttıkça etkileşim sayısıda artacaktır ve bu etkileşimlerin başka uygulamalar(hizmet) ile etkileşime geçmesi gerekecektir. İşte tam bu noktada yükü hafifletmek ve sağlıklı bir yapı sağlayabilmek için kullanılırlar. Ölçeklenebilir yapıdadır; kuyrukları bir makinede tutarken, consumer başka bir makinede olabilir hatta consumerlar dağıtık bir şekilde çalışabilirler çünkü bilmeleri gereken tek şey kuyruğun nerede olduğu. Bir olay karşısında yapılması gereken birden fazla iş olabilir tüm bu işleri Message broker üzerinden ilerletebilirsiniz. Bir olay karşısında A işlemi yapıldıktan sonra Consumer B işlemi için tekrar Producer rolü üstlenerek yeni bir mesaj oluşturabilir. Uygulamayı küçük ve birbirine daha az bağımlı parçalara bölmeyi sağlar.
Exchange Tipleri
Direct: Exchange mesajın header bilgisinde bulunan yönlendirme anahtarına(routing key) göre kendisine bağlı olan kuyruğa mesajı yönlendirir.
Fanout: Exchange mesajı kendisine bağlı tüm kuyruklara çoklar.
Topic: Bir yönlendirme anahtarı ile bu anahtara uygun şablon ile bir veya birden fazla kuyruğa mesajı yönlendirir. Burada güzel bir anlatım mevcut.
Kullanım Tipleri
Buraya kadar aslında nasıl kullanılmasıyla ilgili bir çok örnek canlanmıştır. Fakat temelde Message Broker bir olay(event) veya bir emir(command) yürütmek için.
Uygulamanızda bir olay gerçekleştiğinde; yeni üye kaydı, yeni sipariş vs. Bu bilgiye ihtiyaç duyan diğer uygulamalar ile bu bilgiyi paylaşarak, uygulamaların bu olay karşısında gerçekleştirmesi gereken işlemleri gerçekleştirmelerini sağlayabilirsiniz. Yeni üye kaydı bilgisine ihtiyaç duyan onlarca farklı uygulamanız(hizmet) olduğunu düşünün. Olay anında her birine bu bilgiyi paylaşmak ve işlemlerini tamamlamasını beklemek gereksiz zaman kaybı oluşturacaktır.
Kullanıcılarınızın bir işlemi başlatma veya olayların bir durumda bir işlemi gerçekleştirmek için emir(command) olarak nitelendirilen bir mesaj göndermesi gerekecektir. Burada farkı ayırt etmek zor olabilir. Bir olay karşısında da aslında bir işlem yapılıyor. Neden emir ve olay mesajları ayrı ayrı nitelendiriliyor ki diyebilirsiniz. Burada aslında mesajlarıda bir birinden ayırmak için düşünülmüş bir yapı ve uygulamanızda CQRS gibi bir yapıyı kullanmanı gerektiğinde aslında durumun netliği daha da ortaya çıkıyor.
Olayları dinleyen Consumer aslında uygulamanızın bir parçası. Bu dinleyicileri de mesaj tiplerine göre ayırmak mantıklı bir yaklaşım olacaktır. Hangi tüketicinin ne iş yaptığı daha belirgin olacaktır bu da okunabilirliği arttırır. Bir olaylar silsilesi yaratma görevinide bir mesaj olarak iletebilirsiniz. Kullanıcı bir işlem gerçekleştirir ve toplu bir işlem yapılması gerekir fakat istek süresi içerisinde bu işlemi yapmak mümkün değildir. Bu durumda emir tipinde bir mesajı iletirsiniz ve onu dinleyen tüketici bu emri yerine getirerek başka bir kuyruğa olayları iletir. Yani çok fazla olay yaratmak için de kullanabilirsiniz. Canınız nasıl isterse.