7 min read

Mesajlaşma(Messaging) ile uygulamalar arası iletişim

Bu yazıda uygulamalar arasında iletişim kurulmasını sağlayan mesajlaşma sistemlerindeki önemli kavramlara değindik.
Mesajlaşma(Messaging) ile uygulamalar arası iletişim

İki uygulama arasında iletişim kurmak için kullanabileceğimiz farklı yaklaşımlar mevcut. Bu yazıda mesajlaşma konusuna değineceğiz.

Uygulamalar arası iletişim yöntemleri

Mesajlaşma konusuna girmeden önce mesajlaşma dışında hangi yöntemler kullanarak uygulamaları konuşturabiliriz, bir düşünelim.

Dosya transferi

Bir uygulamanın oluşturduğu veriyi xml, json gibi popüler bir formatta dosyaya yazması halinde bu bilgileri kullanacak olan diğer uygulamalar bu dosyayı okuyup gerekirse düzenleyebilirler. Örnek vermek gerekirse, bir programın çıktılarının gün sonunda derlenip bir gün sonu raporu halinde özetlenmesi için dosya transferi yeterli olacaktır.

Veritabanı paylaşımı

Birden fazla uygulamanın aynı veriyi okuyup yazması gerekliyse bunlar aynı veritabanını kullanabilirler. Eğer aynı anda bir veriye yazma olursa, transaction yönetimiyle veri tutarlılığı sağlanır. Örneğin bir uygulama diğerinin yazdığı verileri zaman zaman okuyup değiştirebilmesi gerekiyorsa, aynı veritabanını paylaşmaları halinde sorun çözülmüş olur.

RPC (Remote procedure call)

Bir programdan veri isteyen diğer programlar bunu direk olarak yapabilir. Yani bir uygulamanın diğer uygulamalara yönelik bir arayüzü olabilir. gRPC'yi buna örnek olarak verebiliriz.

Eğer bu ve benzeri yöntemler kullanım senaryonuza uygunsa bunlardan yararlanabilirsiniz. Fakat bazen uygulamalar arasında daha büyük ve detaylı bir mesaj trafiği kurup bunu kontrollü bir şekilde yönetebilmek isteriz. Bu gibi durumlarda mesajlaşma (messaging) uygulamaları imdadımıza yetişiyor.

Mesajlaşma / Messaging

Mesajlaşma uygulamaları genellikle posta veya kargo hizmetine benzetilir. Siz paketinizi bir şubeye adres ve gerekli bilgileri yazıp bırakırsınız. Paketiniz servis sağlayıcı tarafından sizden bağımsız (=asenkron) olarak hedefe iletilir. Bu sistemi kullanan çok sayıda kişi olmasına ve bu kişilerin çok farklı mekanlarda bulunmasına rağmen bu sistem hiç karışıklık çıkmadan paketlerin doğru kişilere vakitli şekilde iletilmesini sağlar.

Özellikle dağıtık sistemlerde çalışıyorsanız uygulamalarınız arasında asenkron olarak mesaj gönderilebilmesi çok önemlidir; çünkü her uygulama her an veri almaya hazır durumda olmayabilir. Mesajlaşma uygulamaları kullandığınızda uygulamalarınız mesajlarını belli bir kanala (channel) gönderir. Bu andan itibaren mesajlaşma sistemi işi devralır ve bu kanallara gelen mesajların sistemli ve güvenli bir şekilde hedef uygulamalara iletimini sağlar.

Temel mesajlaşma kavramları

Mesajlaşmayı daha iyi anlayabilmek için önce mesajlaşma sistemlerinde kullanılan bazı temel kavramlara kısaca değinelim.

Mesaj

Bir uygulama tarafından üretilen veri paketidir. Tek tip olmak zorunda değildir, çeşitli mesaj tipleri olabilir.

Kanal

Uygulama ürettiği veriyi bir yada daha fazla mesaj olacak şekilde paketleyerek bu mesajları bir mesajlaşma kanalına verir.

Pipe ve Filter

Kanalda bu paketler belirli sıralarla art arda dizilmiş bazı ön işlemlerden geçirilebilir. Örneğin şifre çözme, kimlik doğrulama vb.

Filter mesaja uygulanan bağımsız bir işlemdir. Örneğin şifre çözme işlemi için bir filter kullanabilirsiniz.

Bu işlemler art arda pipe'lar ile belirli bir sıralama oluşturacak şekilde dizilirler. Birkaç aşamalı bir işlemi tanımlarken farklı aşamalardaki filter'ları pipe'larla dilediğiniz düzende sıralayabilirsiniz.

Routing

Routing yani yönlendirme ile mesajlar sadece alıcı olarak belirtilen uygulamaya iletilir.

Bir mesajın alıcı sayısı bir veya daha fazla olabilir. Bu aşamada mesajlara hiçbir değişiklik yapılmaz; yalnızca ilgili sıraya iletilir.

Transformation

Bazen alıcı tarafta farklı bir veri formatı beklenir. Bu durumda transformation yani dönüştürme işlemi yapılır. Örneğin sizin patentli bir özel veri formatınız vardır, ve 3rd party bir uygulamadan gelen xml formatlı veriyi kendi uygulamanızda bu özel formatta işlemek istiyorsunuzdur. Bu gibi durumlarda yapılacak dönüştürme işlemi, iki taraf arasındaki uyumsuzluğu yok edecek bir adaptör görevi görür.

Endpoint

Uygulamalar bir mesajlaşma sistemini kullanabilmek için bir kanala bağlanmak zorundadır. Bu amaçla yazılan bir client kodunu kullanarak mesajlaşma sisteminde bağlandıkları kanala ait birer endpoint yani uç nokta olarak yer alırlar.

Mesaj tipleri

Mesajlaşma sisteminde kullanılan mesajlar çok farklı amaçlara hizmet edebilirler. Genellikle şu üç tip mesaj kullanılır:

  • Command message: Komut mesajı ile bir işlemin yapılması emri verilir
  • Document message: Dosya mesajı ile bir veri dosyası iletilir
  • Event message: Olay mesajı ile belli bir olayın olduğuna dair bildirim yapılır

Şimdi bu mesaj tiplerini inceleyelim.

Komut mesajı

RPC de olduğu gibi bir komutun başka bir uygulama tarafından çalıştırılmasını sağlar. Komut mesajı basittir, içerisinde yapılacak işlemin detayları belli bir formatta yazılıdır. Örnek vermek gerekirse SOAP mesajı bir komut mesajıdır.

Dosya mesajı

Uygulamalar arasında veri iletimi sağlar; yani bilgi paylaşımı yapmakta kullanılır.

Esasında uygulamalarımız kendi aralarında bilgi paylaşmak için dosya sistemine direkt olarak dosya yazabilir veya veritabanına yazıp buraya erişim sağlayabilirler. Ancak bu yöntemlerin özellikle iletişimin yoğunluğu ve karmaşıklığı arttığında birtakım dezavantajları ortaya çıkıyor. İşte bu engelleri mesajlaşma sistemleri kullanarak aşabiliyoruz.

Olay mesajı

Bir bildirim mesajıdır. Bir uygulamanın herhangi bir önemli olay gerçekleştiğinde bundan diğerlerini haberdar etmesini, alıcıların da gereken işlemleri vakit kaybetmeden hemen yapabilmelerini sağlar.

Mesajların içerisinde neler bulunur?

Mesajlar birçok uygulama arasında gidip geldiğinden nereden gelip nereye gittiğini belirten adres, numara, vb bilgiler içerirler. Bu bilgilere de kısaca değinelim.

Request - reply

Bazen bir mesaja cevap alabilmek de isteriz. Bunun için bir istek kanalı ve bir de cevap kanalı olmak üzere iki ayrı kanal kullanabiliriz. Bazı örneklerde RPC yapmak amacıyla bir komut mesajı gönderilip, yapılan işlemin sonucunun bir dosya mesajı ile cevap kanalından alındığını görürüz. Bir diğer senaryoda da uzaktan bir sorgulama yapılıp cevabı dosya mesajı ile alınabilir.

Return address

Bir mesajın karşılığında cevabını almak istiyorsak buna iade adresi olarak cevap kanalı bilgisini de eklemek gerekir. Bu şekilde alıcının cevabı bu kanaldan ilk mesajın göndericisine iletilebilir. Örnek olarak Go dilinde mesajlaşma kanalları hazır olarak tanımlıdır. Bir istek yapısı içerisinde chan tipinde bir alan eklenerek iade adresi kolayca tanımlanmış olur.

Correlation identifier

Bir cevap mesajının hangi mesaja cevap olarak geldiğini tespit etmek için bu değere bakılır. Her cevap mesajında mutlaka bu değerin bulunması gerekir.

Message sequence

Mesajlaşma ile gönderilecek olan veri bir mesaja sığmayacak kadar büyükse bu durumda veri bir mesaj dizisi şeklinde yollanır. Bu dizideki her mesaja da sıra numarası verilir. Böylece alıcıya ulaştığında tekrar orijinal halinde birleştirilebilir.

Message expiration

Mesajlar belirli bir süre geçtikten sonra geçersiz hale gelsin ve değerlendirmeye alınmasın istiyorsak, bunlara bir nevi son kullanma tarihi ekleyebiliriz. Bu süre geçtiği taktirde mesaj iletilmeyecektir. Eğer bir mesaj alıcıya vardığı anda zamanaşımı olmuşsa, alıcı bu mesajı hiç almamış gibi davranacaktır. Bu tür mesajlar tercihe bağlı olarak sistemden silinebilir veya geçersiz mesaj kanalına aktarılabilir.

Format indicator

Bazen mesajların içerdiği veri formatı zamanla değiştirilebilir. Bu yüzden alıcıya mesajın içerdiği veri formatını bildirecek bir alan eklenebilir. Alıcı bu alan sayesinde gelen mesajın hangi formatta veri içerdiğini önceden haber almış olur. Bu sayede ileride olacak değişikliklerden etkilenmez.

Mesajlaşma kanalları

Mesajlar bahsettiğimiz gibi ilk olarak belirli bir kanala verilir ve bu kanal üzerinden alıcılarına ulaştırılırlar. Biraz da kanallardan bahsedelim.

Point-to-point channel

Bu kanal mesaj sadece tek bir uygulamaya iletilecekse uygundur. Mesajın mutlaka hedefe ulaştığından emin olur. Bir RPC veya dosya iletimi gibi durumlar örnek gösterilebilir.

Publish-subscribe channel

Bu kanal birden fazla uygulamaya bir duyuru yapılacaksa uygundur. Mesajın bu kanala abone olan bütün alıcılara birer kopyasının iletilmesini sağlar. Örnek: Google pub-sub.

Datatype channel

Bir uygulama bir kaç farklı türde veri tipi üretiyorsa, alıcının bunları tespit etmesini kolaylaştırmak için her veri tipini ayrı bir kanaldan gönderebilir. Bu sayede hedefteki uygulama gelen mesajın tipini geldiği kanaldan hemen anlayacaktır. Örneğin bir sipariş bilgisi iletileceği zaman sadece sipariş mesajlarının gönderildiği bir kanalın kullanılması, alıcı için bir kolaylık olacaktır.

Invalid message channel

Bir uygulama teslim aldığı mesajı okuyamazsa bu mesaj geçersiz demektir. Bu tarz geçersiz mesajlar alıcı tarafından geçersiz mesaj kanalına iletilir.

Dead-letter channel

Bazen mesajlar alıcıya ulaşmaz. Bu durumda mesajlaşma sistemi bu mesajları bir alıcı bulunamadı kanalına iletebilir.  Örnek: Amazon SQS.

Guaranteed delivery

Mesajlaşma sistemi bir hata sonucu çöktüğünde mesajlar da yok olmasın istiyorsak, mesajların kalıcı hale gelmesini sağlayabiliriz. Normalde mesajlar bellekte yaşadığından sistem kapandığında mesajlar yok olur. Ama bu yöntemde mesajlaşma sistemi içerisinde gömülü vaziyette bir kayıt programı bulunur. Burada bütün mesajlar, alıcı tarafında kayıt programı tarafından diske yazıldığı onaylanana kadar, silinmeden saklanır. Bu sayede sistem çökse dahi mesajlar silinmez ve sistem yeniden ayağa kalktığında kaldığı yerden mesajları iletmeye ve alındıları takip etmeye devam eder. Bu yöntem performansı düşürse de mesajların iletildiğinden her daim emin olabilmemizi sağlaması açısından önemlidir.

Channel adapter

Bir uygulama mesajlaşma sistemine bağlanamıyor olabilir. Fakat yine de bu uygulamanın bir şekilde mesajlaşma kullanmasını isteyebiliriz. Bunun için mesajlaşma sisteminin bir adaptör kullanarak uygulamanın arayüzüne erişmesini sağlayabiliriz. Örneğin mesajlaşma sistemi uygulamanın APIsi, veritabanı, veya HTTP bağlantısı üzerinden bu uygulamayı kendisine bağlayabilir. Bu uygulamanın üzerinde çalıştığı cihazda mesajlaşma sistemi kurulu olmasa dahi bu şekilde mesajlaşmadan yararlanabilecektir.

Messaging bridge

Bir sistemde birden fazla mesajlaşma sistemi kullanılıyor olabilir. Bunları direk bağlamak mümkün olmasa da, kanalları birbirine bağlamak için iki tarafa da birer kanal adaptörü yazılabilir. Mesaj formatları iki tarafa göre değiştirilebilir. Bu şekilde bir köprü kurulması sağlanır.

Message bus

Bir sistemi oluşturan çok sayıda uygulama belirli kurallar çerçevesinde iletişim kurabilsin, fakat herhangi biri devreden çıkarsa bu diğerlerinin iletişimini etkilemesin isteniyorsa, bunların hepsinin ortak bir message bus üzerinden haberleşmesi uygun olacaktır.

Son söz

Bu yazıda uygulamalar arasında iletişim altyapısı sağlayan mesajlaşma sistemlerindeki önemli kavramlara değindik. Siz de mesajlaşma için hangi sistemi tercih ederseniz edin, karşınıza çıkacak problemler ve bunları çözmek için yararlanacağınız kavramlar benzer olacaktır. Teori ile başladığımız mesajlaşma yazı dizisine bir sonraki yazıda çeşitli mesajlaşma örnekleri ile pratik yaparak devam edeceğiz.