“Monolith” uygulamaların günümüzün hızlı değişim ihtiyaçlarına çok sağlıklı cevap verememesi ile “microservices” mimari stili, geliştirme yöntemi olarak hayatımıza girdi. Son 3-4 yıldır da “tüketim” ve “pazarlama” dünyası gerçekleri ile de reklamı yapılınca belli kalıplar içinde herkesin tercih etmeye çalıştığı bir stil oldu. Gerçekten ne kadar bu mimari yöntem ihtiyaç olarak tercih ediliyor ya da getirilerinden ne kadar değer üretiliyor bilemeyeceğim. Sonuçta “microservices” kusursuz bir çözüm yöntemi ya da ideal bir çözüm değil. Ayrıca tüm çözümler “microservices” tasarımı ile en doğru, en ideal olacak diye de bir şey yok.
Her fırsatta paylaşmaya çalışıyorum, konuya girmeden tekrar altınız çizmek isterim; “microservices”, servis odaklı mimarinin günümüz ihtiyaçlarına uygun bir şekilde evrilerek kullanılmasını sağlıklı hale getiren bir tasarım stili.
Bu kısa girişten sonra konumuza gelelim. “Microservices”(Mikroservis)’lerin bir birleri arasındaki veri ihtiyacı nasıl olmalı? Servisin bir fonksiyonunu başka bir servisten aldığımız verileri kullanarak nasıl sağlarız? Bu sorular karşıma çok çıkıyor, direkt mikroservis tasarımları ile geliştirmeye başlayan herkesin problem olarak da en çok takıldığı nokta olarak görüyorum, duyuyorum.
Açıkcası bu sorular karşınıza çıkıyor ya da kendi kendinize bunları soruyorsanız, mikroservis tasarımın stili kavram olarak tam netleşmemiştir. Öncelikle servislerin bir birleri arasındaki veri ihtiyaçları için bir birlerini çağırması, bir servisin belli işlemleri için başka servisten verileri alması falan normal ve zaten “Remote Procedure Call”(RPC) ile hayatımızda olan bir kavram. “Service Oriented Architecture(SOA)”‘nın ve dağıtık sistemlerdeki servis çağırımları yöntemleri ile servisler bir birlerinin her türlü verisini paylaşabilir. Ama bu yaklaşım günümüz ihtiyaçları ile bazen uyuşmadığı için, mikroservis tasarım stilinde de bu şekilde bir yol çok gösterilmiyor.
Mikroservislerin, en önemli karakteristik özelliği; servislerin kendi başlarına çalışan, tek bir sorumluluğu olan, bağımsız servis olmalarıdır. Dolayısıyla bir mikroservis bir veri için başka bir mikroservise ihtiyaç duymamalıdır. Aksi takdirde tek başına çalışan, bağımsız bir servis olma karakteristik özelliğini kaybedecektir.
Mikroservislerin ikinci önemli karakteristik özelliği de “business capability” yani iş alanlarının belli yetkinliklere göre sadece belli bir işi yapacak şekilde geliştirilen servisler olmaları. Yani eğer iş alanı bir veriye ihtiyaç duyuyorsa, o veri aslında o iş alanının(domain) bir parçasıdır. Eğer ihtiyaç duyduğu veriyi başka bir iş alanından alma durumu varsa yine bağımsız olma özelliği kaybolmuş oluyor. Mikroservisin çalışması için başka bir mikroservise bağımlı olması mikroservis mimari tasarım stiline ters bir durum.
Biraz gerçek hayattan bir örnek ile biraz daha anlaşılır hale getirmeye çalışacağım. Adres bilgimiz bankaların bizimle iletişim kurabilmesi için gerekli olan bir veri. Bu veri hesabımızın olduğu tüm bankalarda ayrı ayrı banka özelinde tutulmakta. Bankalar, bu adres verisi ile bizimle iletişim kurabilmekte ve fonksiyonel özelliğini gerçekleştirebilmekte. Bize her ekstre gönderecekleri zaman telefon edip, “Ekstre göndereceğiz, adresinizi söyler misiniz?” diye sormuyorlar. Böyle olsaydı eğer, telefon ettiklerinde ilgili veriyi alamadıkları zaman ekstre göndermeleri sıkıntılı olup, ekstre gönderme özelliği için istenmeyen bir bağımlılık olacaktı. Bunun yerine ilk hesap açılırken adres bilgimizi alıyorlar, kendi sistemlerine kaydediyorlar ve onu kullanıyorlar. Adresimiz değiştiği zaman bizim bilgilendirmemiz ile kendi sistemlerini güncelliyorlar.
Mikroservislerde de aynı benzer yaklaşım olmalı. Mikroservisin, iş yetkinliği için gerekli olan veriler servis içinde saklanmalı. Bu da mikroservislerin kendi verilerinden sorumlu olması, kendi veri tabanları olması ilkesi aslında. Şu an eminim bir çoğunuz, “Ama aynı veriyi bir çok yerde tutmak durumunda olacağız, gerek yok. Tek bir yerden alırız…” diye düşünecektir. Yazılım geliştirirken ki bazı yaklaşımlardan(düşünce alışkanlığı aslında) dolayı direkt bu şekilde düşünüyoruz. Ama mikroservis mimari stilinde, verinin niceliğinden çok, niteliği çok daha değerli. Yukardaki adres örneğine dönelim. Bir bankada adres verisi 500 karakterli tek bir alanda tutuluyorken, başka bir bankanın fonksiyonel özelliklerinden dolayı adres verisi; sokak, kapı numarası, ilçe, il şeklinde 100’er karakterli alanlarda tutulma ihtiyacında olabilir.
Her servisin kendi verilerini tutmasının da getireceği tabi ki başka problemler ve soru işaretleri var. Bu verilerin doğruluğu ve güncelliği ilk sorulacak soru olacaktır genelde. A mikroservisinin tuttuğu adres bilgisi ile B mikroservisinin tuttuğu adres bilgisinin güncelliği “event-based” yaklaşımları ile çözülebilir. Bunların çok farklı senaryoları ve ihtiyaçlara göre çözüm yöntemleri değerlendirilebilir. Çok ayrıntılarına girmeyeceğim. Ama özetle (adres verisi örneğinden devam…) adresiniz değiştiği zaman bir “event” yaratıyorsunuz, bu “event”‘i dinleyen bankalar(müşteri hizmetlerini arayabilmeniz.) değişen adres bilgisini kendi içlerinde güncelliyor. Burada mikroservisler arasındaki iletişim sağlanabileceği bir kanal olması, mikroservis tasarım stili için önemli. Bu kanal asenkron şekilde işleyen bir yapıda olmalı. Bu sayede her hangi bir iş kesintisi minimuma inmiş olur; mikroservislerin tek başına çalışabilme özelliğine yine uygun bir şekilde de olmuş olur. Verinin güncelliğinin kritikliğine göre farklı iletişim yöntemleri gerçekleştirilebilir. Belli bir “event”’in oluşmasını beklemek yerine, iş yetkinliğini revize edip belki gerçekten her seferinde senkron olarak adres verisini sorması da gerekecektir. Bu tamamen iş ihtiyacının gerektirdiği şekilde olabilir. Ama mikroservislerin karakteristik özelliklerini koruyarak çözüm yaratmak, mikroservis mimari stilinin avantajlarını görmek için sağlıklı olacaktır.
Burada önemli olan ve altını çizmek istediğim asıl nokta, mikroservislerin ihtiyaç duyduğu verilerin ve iş alanları bilgisinin olabildiğince net oluşturulabilmesi ve tasarlanması. Bir mikroservisin ihtiyaç duyduğu veri, gerçekten o mikroservisin iş alanının bir parçası mı yoksa tetikleyici rolde olan bir veri mi bunların farkındalığı mikroservisin geliştirme sürecini ciddi bir şekilde etkiliyor. Belli bir iş alanı bilgisinde ne kadar yetkin bilgiye sahip isek, onun servis olarak tasarımı o kadar net olacaktır.
Mikroservisler olarak çözümlerini geliştiren herkesin benzer soru işaretleri oluyor bu ve niceleri gibi. En çok karşılaştığım, benim de çözümlemeye çalıştığım bir durumu bu şekilde paylaşmak istedim. Umarım az biraz faydası olmuştur. Bir sonraki yazıda görüşmek üzere. 🙂
Bu arada mikroservisler ile ilgili uzun zaman önce paylaştığım bir yazıya da buradan göz atabilirsiniz.