Microservis Nedir?

İsminden anlaşılacağı gibi tek bir işi yapmak ile sorumlu, mikro servislerden oluşan modüler projelerdir. Bu servisler birbirinden izole, bağımsız, kolay dağıtılabilir bir yapıya sahip olmalıdır.
Son zamanlarda araştırma ve geliştirme yapmadan, üzerinde konuşmadan, avantajları ve zorluklarını bilmeden bu mimariyi kullanmaya karar veriyoruz. İlk olarak microservices mimarisinin avantajlarını ve zorluklarını görmemizde fayda var.
Örnek projeyi github üzerinden indirmek veya görüntülemek için https://github.com/ayzdru/MicroservicesCleanArchitecture adresine gidebilirsiniz.
Bu proje örnek bir mikroservis projesidir. Burada amaç mimariyi anlatmaya çalışmak, dilediğiniz teknolojileri ve kütüphaneleri kullanabilirsiniz.
Microservis Mimari Avantajları
Mikro servisler bağımsız olarak dağıtıldığından, hata düzeltmelerini ve servis sürümlerini yönetmek daha kolaydır. Bir uygulamayı, tüm servisleri yeniden dağıtmadan güncelleyebilir ve bir şeyler ters giderse bir güncellemeyi geri alabilirsiniz. Birçok geleneksel uygulamada, uygulamanın bir bölümünde bir hata bulunursa, tüm sürüm sürecini sıkıntıya sokabilir. Bir hata düzeltmesinin entegre edilmesi, test edilmesi ve yayınlanması için yeni özellikler bekletilebilir.
- Küçük, tek bir işe odaklanmış takımlar
Bir mikro servis, tek bir ekibin onu oluşturabileceği, test edebileceği ve dağıtabileceği kadar küçük olmalıdır. Küçük takım boyutları daha fazla çeviklik sağlar. Büyük takımlar daha az üretken olma eğilimindedir, çünkü iletişim daha yavaştır, yönetim yükü artar ve çeviklik azalır.
- Birbirinden bağımsız kodlar
Monolitik bir uygulamada, kodların birbirine bağımlı hale gelme eğilimi vardır. Yeni bir özellik eklemek için birçok yerde koda dokunmak gerekir. Kod veya veri depolarını paylaşmamakla, bir mikro servis mimarisi bağımlılıkları en aza indirir ve bu da yeni özellikler eklemeyi kolaylaştırır.
- Fark Teknolojiler ve Farklı Yazılım Dilleri
Takımlar, uygun gördükleri şekilde istediği teknoloji ve yazılım dillerini kullanarak hizmetlerine en uygun olanı seçebilirler.
Tek bir mikro servis kullanılamaz duruma gelirse, yukarı akıştaki mikro servislerin her biri hataları doğru şekilde ele almak üzere tasarlandığı sürece (örneğin, devre keserek) tüm uygulamayı bozmaz.
Servisler bağımsız olarak ölçeklendirilebilir, böylece tüm uygulamayı ölçeklendirmeden daha fazla kaynak gerektiren alt sistemleri ölçeklendirebilirsiniz. Kubernetes veya Service Fabric gibi bir orkestratör kullanarak, kaynakların daha verimli kullanılmasını sağlayan tek bir ana bilgisayara daha yüksek yoğunlukta hizmetler koyabilirsiniz.
Her bir mikro servis birbirinden farklı veri katmanları (MSSQL, MongoDb vs.) olabilir.
Microservis Mimari Zorlukları
Bir mikro servis uygulamasının eşdeğer monolitik uygulamadan daha hareketli parçaları vardır. Her servis daha basittir, ancak bir bütün olarak tüm sistem daha karmaşıktır.
Diğer bağımlı hizmetlere dayanan küçük bir servis yazmak, geleneksel monolitik veya katmanlı bir uygulama yazmaktan farklı bir yaklaşım gerektirir. Mevcut araçlar her zaman servis bağımlılıkları ile çalışacak şekilde tasarlanmamıştır. Servis sınırları arasında yeniden düzenleme yapmak zor olabilir. Özellikle uygulama hızlı bir şekilde geliştiğinde, servis bağımlılıklarını test etmek de zordur.
Mikro servislerin oluşturulmasında merkezi olmayan yaklaşımın avantajları vardır, ancak aynı zamanda sorunlara da yol açabilir. Uygulamanın bakımını zorlaştıracak kadar çok farklı yazılım dili ve framework ile karşılaşabilirsiniz. Ekiplerin esnekliğini aşırı derecede kısıtlamadan, proje çapında bazı standartları uygulamaya koymak faydalı olabilir. Bu özellikle loglama gibi kesişen işlevler için geçerlidir.
Birçok küçük, ayrıntılı servisin kullanımı servis içi iletişimin artmasına neden olabilir. Ayrıca, servis zinciri bağımlılıkları çok uzarsa, ek gecikme bir sorun haline gelebilir. API'leri dikkatli bir şekilde tasarlamanız gerekir.
Her mikro hizmetin kendi verilerinden sorumlu olması. Sonuç olarak, verilerin tutarlılığı zor olabilir.
Mikro servis mimarisinde başarılı olmak için olgun bir DevOps kültürü gerekir. Servisler arasında birbiriyle ilişkili loglama yapmak zor olabilir.
Bir servise yapılan güncelleştirmeler, ona bağlı servisleri bozmamalıdır. Birden fazla servis herhangi bir zamanda güncellenebilir, bu nedenle dikkatli bir tasarım olmadan, geriye veya ileriye dönük uyumluluk ile ilgili sorunlarınız olabilir.
Mikro hizmetler oldukça dağıtılmış sistemlerdir. Takımın başarılı olmak için gerekli beceri ve deneyime sahip olup olmadığını dikkatle değerlendirilmelidir.
Mikroservis Mimari Kullanmalı mıyız?
Mikro servis mimarisinin yukarıda avantajlarını ve zorluklarını gördük. Ortaya çıkaracağımız yazılım ürünü ihtiyaçlarını karşılayacaksa, yazacağımız projenin kullanıcı sayısının gün geçtikçe artacağını düşünüyorsak, bildiğiniz gibi monolitik mimarilerde yük dengelemeyi dikeyde yani bir bütün olarak yapabiliyoruz, servisleri yatayda örneğin görüntü işleme servisi gibi sunucuya yük binecek modülleri yatayda yani servis bazlı ölçeklendirmek istiyorsak, en küçük bir değişiklikte bütün projeyi deploy etmek istemiyorsak, büyük bir projeyi (E-ticaret vs.) parçalara ayırıp geliştirileri 5-6 kişilik takımlar ile servisleri ayrı takımlar şeklinde bölmek istiyorsak mikro servis mimarisini kullanabiliriz.
Mikroservis Mimari için Neler Gerekli?
- Container (Docker vb.) ve Container Orchestration (Kubernetes vb.)
Mikroservislerimizi yatayda ölçeklendirmek, servislerin kaynak kullanımı hızlıca düzenleyebilmek, load balancing (yük dengeleme), güncelleme stratejileri oluşturma gibi bir çok avantajlarından dolayı bir Container ve Container Orchestration kullanmamız çok yararlı olacaktır.
Daha önce bir container orchestrator kullanmadıysanız buradan blog yazımı inceleyebilirsiniz.
Mikroservis mimarisinin getirdiği operasyonel yükü kaldırabilecek, güçlü bir devops ekibi gerekiyor. Aksi takdirde çok fazla zaman kaybetmeniz kaçınılmaz olacaktır.
CI/CD süreçlerinizi kolaştıran Docker Uygulamısını buradaki blog yazımdan inceleyebilirsiniz.
- Her Servisin İzole Veritabanı ve Birbirine Bağımlılığı Olmamalı
Mikroservis mimarisinde her servisin birbirinden tamamen izole veritabanı olmalıdır. Bir servis diğer servisin veritabanına direkt erişmemelidir. Servisler arası ortak kütüphane kullanılmamalıdır. Gerekiyorsa ortak yeni bir servis oluşturup birbiriyle konuşturmamız gerekiyor.
Mikroservisler Arası Veri Paylaşımı Nasıl Olacak?

Şimdi elimizde User ve Post diye iki tane mikroservis olsun, Users tablosundaki Id kolonu ile ----> Posts tablosundaki UserId kolonu arasında bir ilişki var. Ama bu servislerin veritabanları tamamen izole olduğundan Post servisinin veritabanında Users diye (sadece gerekli kolonlar olsa yeter) bir salt okunur kopya tablo açıyoruz.
Şimdi diyeceksiniz ki ağ bağlantısı gitti, bir kopya tabloya veri eklenmedi ne olacak? Burada yapılacak şey, eğer servisin kendi tablosunda bu kayıt yok ise, ilgili servise api aracılığıyla bağlanıp kaydın var olup olmadığını kontrol edebiliriz.
Mikroservisler Birbirleriyle Nasıl Haberleşecek?
Burada siz dilerseniz Request-Driven, Event-Driven veya benim örnek projede kullanacağım gibi gRPC ve Transactional Outbox (Asenkron bir protokol olan AMQP'yi destekleyen RabbitMQ, Kafka, AzureServiceBus vb. gibi bir message broker aracılığıyla) hibrit bir yapı kullanabilirsiniz.
gRPC'yi Blazor WebAssembly SPA web uygulamamızı servislerle konuşturmak, izole veritabanlarındaki salt okunur kopya tabloları senkronize etmek ve veri tutarlılığını sağlamak için kullanacağız.
Transactional Outbox Pattern (Transaction log tailing yöntemi ile) tasarım deseniyle monolitik uygulamalarda nasıl transaction oluşturuyorsak, mikroservis mimari ile aynı şekilde bir transaction oluşturup, distributed transaction sorununu çözeceğiz. Siz dilerseniz burada, Two-Phase Commit (2PC) ve Saga Pattern yöntemlerini kullanabilirsiniz.
Örnek projeyi github üzerinden indirmek veya görüntülemek için https://github.com/ayzdru/MicroservicesCleanArchitecture adresine gidebilirsiniz.
Bu proje örnek bir mikroservis projesidir. Burada amaç mimariyi anlatmaya çalışmak, dilediğiniz teknolojileri ve kütüphaneleri kullanabilirsiniz.
Örnek Projeyi zamanla geliştirmeye devam edeceğim.
Sağlıcakla kalın.