Kategori arşivi: Bottleneck

Perspektif Açıdan MicroService

Microservice, günümüzde çok popüler bir konu olarak karşımıza çıkmaktadır. Popülarite kazanmasını sağlayacak bir çok sebep bulunuyor. Her projenin Microservice Mimarisinde geliştirilmesi gerektiğini söyleyemeyiz. Avantaj ve dezavantajlarını değerlendirerek uygulamak en mantıklı çözüm yolu olarak görünüyor. O halde Ne, Neden, Ne Zaman sorularına cevap bulmaya başlayabiliriz. 

Microservice Mimarisini incelemeden önce Monolithic olarak geliştirilmiş bir proje hangi konularda dezavantaj oluşturduğuna değinmek daha sağlıklı olacaktır.

Monolithic Mimarisi, Self-Contained olarak tasarlanan projelere denilmektedir. Bu tip projeler genellikle birbirine bağımlı olarak tasarlanmış olması dikkat çekmektedir. Öncelikle dezavantajlarından bahsetmek gerekirse;

  • Component’lerin aynı framework üzerinde geliştirilmiş olması gerekir. Bu başlarda sorun gibi görünmese bile projenin ilerleyen süreçlerinde sorun haline dönüşecektir.
  • Ekiplerin birbiri ile çalışması git gide zorlaşır.
  • Versiyonlam sorunları artmaya başlar.
  • CI & CD aşamalarının zorlaşır
  • Scaling

Monolithic olarak tasarlanan projeler başarılı olamaz gibi bir cümle kurmak mantıklı olmayacaktır. Avantaj ve dezavantajlar değerlendirilerek projeyi geliştirmek daha mantıklı bir hareket olacaktır. Monolithic Mimari üzerine tasarlanan projeler tabii ki başarılı olabilir fakat yükselen internet kullanımı ile yük altında çalışabilen uygulamalar sınıfına dahil olması biraz zor görünüyor. Bunun en büyük sebebi ölçeklendirme şeklidir. Monolithic tasarlanan uygulamalar Scale Up dediğimiz Dikey Ölçeklendirme ile yük altında çalışabilir hale geliyor. Bu maliyetli bir yöntemdir ve yönetilmesi zamanla zorlaşmaya başlar. Kaynak tüketen uygulamanız için sürekli Ram yükseltmek veya CPU arttırmak çözüm gibi görünse bile zamanla bağımlılığınız daha fazla artmaya başlayacak ve upgrade sorunları yaşamanıza sebep olacaktır.   

MicroService ise bir bütün olan uygulamanızı en ufak fonksiyonel parçalar halinde modüler bir biçimde ayrışmasıyla ortaya çıkıyor. Her bağımsız modülün birbirinin çalışmasına engel olmayacak şekilde izole olması tüm sistemin daha sağlıklı çalışmasını sağlıyor. Her bir modülü, yalnızca bir göreve odaklanıp sadece o göreve ait işleri yürüten mekanizmalar olarak tanımlayabiliriz. Bu şekilde her bir modülü farklı bir teknoloji ile geliştirebilirsiniz. Her bir modül için farklı database seçeneklerini değerlendirmeniz mümkün görünmekte.

MicroService, modüler yapıya sahip olması nedeniyle “Loosely Coupled” oldukça bağımsız çalışabilir ve deploy edilebilir. Herhangi bir modülünüzün yeni versiyonunu deploy etmeniz bir diğer modülünüzü etkilemez. Bu şekilde tüm uygulamanızı deploy etmek yerine sadece değişiklik yaptığınız modülü deploy etmeniz yeterli olacaktır. Bu şekilde ekipler birbirinden bağımsız çalışabilir ve hızlı bir şekilde geliştirme ve test süreçlerini tamamlayabilir. Aralık 2019 “AGILE Devrimi” yazımda ekibin Lead Time ve Cycle Time sürelerinin yönetimsel olarak nasıl düşürülebileceğine değinmiştik. Cycle Time, geliştirme sürecinin performansına göre seyir eden bir zaman dilimiydi. MicroService mimarisi bu noktada çözüm önerisi gibi görünmektedir. MicroService Mimarisinin tercih sebeplerinden birisi ise Scale Out(Yatay Ölçeklendirme) kolaylığı. Scale Out her geçen gün daha fazla önem kazanan bir konu haline geldi. Yatay olarak ölçeklendirilen sistemler kolaylıkla yönetilebilir durumdadır. Yük altında çalışan uygulamalar hızlı manevralar ile başarılı sonuçlara ulaştırılabilir.

MicroService Mimarisinin artı yönlerinin çok fazla olduğu ortaya çıkarken eksi yönlerinide incelemekte fayda var. Projeniz için mimari kararı vermeden önce artı ve eksileri mutlaka göz önünde bulundurmalısınız.

Bağımsızlık, Microservice için en önemli konudur. Microservice Mimarisi kararını aldıktan sonra bağımsız servisler kurgulayarak ilerleyemezseniz eğer Microservice Mimarisi bozulmaya ve Monolithic yapıya doğru bir yol almaya başlayacaktır. Bu performans kaybı, ölçeklendirilememe, çalışma zorluğu, okunulabilirlik gibi bir çok konuda sisteminizin puan kaybedeceğini gösterir. Microservice Mimarisi fikri ile başlayıp sistemi teknik olarak daha karmaşık hallere getirebileceğinizi de göz önünde bulundurmanız ve karar vermeniz gerekir.

Test süreçlerinin uygulanmasında zorluklar Microservice’de genellikle yaşanan bir sorundur. Farklı teknolojiler ve farklı veritabanı kullanımları sistemin dağıtık olması test senaryoları geliştirmenizi zorlayacaktır. Bu konuda test süreçlerini iyi planlamanız gerekmektedir. Yine aynı şekilde yönetim ve metrikleri takip etmeniz zorlaşabilir. Dağıtık sistemlerde uygulamanın metriklerini farklı farklı servisler için bağımsız bir şekilde takip etmeniz gerekecektir. Bunun için her teknoloji ve ya servis için birbirinden bağımsız tool’lar kullanmanız ve bu tool’ların yönetimini sağlamanız gerekecek.

Deployment çok dikkat edilmesi gereken bir adımdır. Dağıtık sistemlerde deployment’lar her bir servis için ayrı ayrı birbirinden bağımsız şekilde yönetilmeli. Bu durumda deployment’lar arasında versiyon farklılıkları ortaya çıkacaktır. Bu sürecin profesyonelce yönetilmesi ve takip edilmesi gerekiyor.

Microservice, Monolithic Mimariye göre daha yüksek başarıya sahip olsa da, operasyonel olarak fazla karmaşık bir yapıdadır. Yönetimi tam yapılamadığı zaman daha büyük sorunlar ortaya çıkarabilecek bir yapıya sahiptir.

Büyük sorunların ve yük altında çalışan uygulamaların Microservice Mimarisine geçişiyle firmalarda da büyük kültür değişimleri oldu. Değişime açık, bağımsız uygulama geliştirme konusunda çok fazla tecrübe kazanıldı. Netflix, Amazon gibi büyük firmaların 700’den fazla servis ile uygulamalarını Microservice Mimarisine geçirdiklerini biliyoruz.

Performans için Struct ve Class Kavramları

Performanslı Web Uygulamaları geliştirirken dikkat edilmesi gereken bir çok nokta bulunmaktadır. Biz Struct ve Class kavramlarını inceleyeceğiz.

Struct ve Class Traffic
Hanny Naibaho‘nun “The Tunnel” isimli fotoğrafı Unsplash’ten alınmıştır.

Struct ve Class’lar birbirlerine benzer özellikler içermektedir. En önemli farklılıkları Memory üzerindeki davranışlarıdır. Struct bir Value Type, Class ise Reference Type’tır. Bu çok önemli bir detay.

Reference Type ve Value Type ile ilgili yazıma bu linkten ulaşabilirsiniz.

Struct ve Class arasında Constructor farklılıkları da bulunmaktadır. Struct için Default Constructor oluşturulduğunda Derleyici Hatası alınır. Fakat parametrik bir Constructor tanımlaması yapılabilir. Class için Default Constructor engellemesi yoktur.

Class’lar kalıtım yolu ile başka bir sınıftan türetilebilirler. Struct’ta ise böyle birşey yapılamaz. Fakat Struct yapınıza Polymorphism uygulayabilirsiniz. Bu konularla ilgili paylaşacağım bazı forum tartışmaları bulunmaktadır.

https://stackoverflow.com/questions/2310103/why-c-sharp-structs-cannot-be-inherited

https://stackoverflow.com/questions/1222935/why-dont-structs-support-inheritance


New anahtar sözcüğü kullanılarak oluşturulan bir Struct nasıl bir çalışma sergiler örnekle inceleyelim.

Bu şekilde StructSample’ın instance’ı alındığında içerisinde bulunan property’lerin default değerleri atanmış olacaktır. Eğer New anahtar sözcüğü kullanılmasaydı, “Use of possibly unassigned field” hatası alacaktık.

Class’larda olduğu gibi instance alma zorunluluğu yok ama Struct’larda property’leri kullanabilmek için default değerleri tanımlanması gerekiyor.

Struct ve Class Ne Zaman Kullanılmalıdır?

Büyük boyutlara sahip datalarınız için Class kullanmanız daha mantıklıdır. Bunun nedeni Memory yönetimidir. Büyük boyutlu dataların Struct ile Stack’te tutulması performans kaybına yol açacaktır. Aynı şekilde Küçük boyutlara sahip datalarınız için Class kullanırsanız gereksiz yere Heap’i şişirmiş olursunuz. Bu performans açısından büyük bir etkendir.

Çok beğendiğim bir yazıyı paylaşıyorum incelemenizde fayda var.

http://clarkkromenaker.com/post/csharp-structs/

Sonuç

Bu basit görünen seçim bazen size çok fazla hafızaya mâl olabilir, bu yüzden akıllıca seçin!