Serverless Mikroservisler: AWS Uygulaması

Giriş
Bu çalışmada kurum projelerinde halihazırda kullanmakta olduğumuz mikroservis mimarisinin avantajlarını keşfetmek, bu avantajları serverless anlayışı ile birleştirerek daha da bağımsız ve güvenilir bir yapı elde edebilmenin
yöntemlerini aradık. Mikroservis mimarisi ile birlikte servislerin birbirinden bağımsızlığını sağlarken, serverless ile de iş mantığı ile altyapı arasındaki ilişkiyi de daha soyut hale getirebiliyoruz. Böylelikle her katmanda
daha modüler bir anlayışı benimseyebilmiş oluyoruz.
Serverless
Serverless altyapı hizmetleri ile ilgilenmeden uygulamaları geliştirme ve deploy etmek için kullanılan bir yaklaşımdır. Altyapısal hizmetler, bizim için bir Cloud Provider tarafından yürütülür. Bu sayede geliştiriciler
daha çok iş mantıklarına odaklanabilir ve donanım, güvenlik, depolama, ölçeklendirme, bakım gibi çeşitli altyapı uğraşları ile ilgilenmek mecburiyetinde olmazlar.
Güncel olarak serverless mimarileri genelde FaaS(Function as a Service) anlayışı ile çalışır. Bu anlayışta uygulama ayrık fonksiyonlar şeklinde geliştirilir ve her fonksiyon bir event tarafından tetiklenir.
Avantajları
- Maliyet
Servislerin ücretlendirmesinde, kullandığın kadar öde mantığı vardır. Kullanılmayan durumlarda ücret ödenmez ve boşa kaynak kullanımı olmaz. - Ölçeklendirme
Kullanılan servislerin ölçeklendirilmesi bulut sağlayıcısı tarafından yönetilir ve geliştiricilerin bir eforu gerekmez. Ölçeklendirme uygulamaya özel olarak daha hassas ve doğru bir şekilde yapılmış olur. Ayrıca istendiği durumda konfigüre edilebilir. - Üretkenlik
Altyapı unsurlarından olabildiğince soyutlanmış geliştiriciler, daha çok iş mantıklarına odaklanır ve daha üretken hale gelirler. Uygulamanın geliştirilmesi ve deploy edilmesi arasında süre kısalır. - Lokalizasyon
Uluslararası bir hizmet sunulduğunda, servis sağlayıcısının dünyanın uzak noktalarında sahip olduğu sunucular sayesinde, isteklerin en yakın sunucu tarafından yanıtlanması sağlanır ve hız artmış olur.
Dezavantajları
- Kontrol Kaybı
Altyapı hizmetlerini bir dış servise bırakmak doğal olarak bunlar üzerindeki kontorlümüzü kısıtlar. Her ne kadar konfigüre edebiliyor olsak da en ince noktasına kadar ayarlama yapabilmemiz mümkün değildir. - Güvenlik
Sahip olduğumuz veriler ve iş mantıklarımız servis sağlayıcısı tarafından ele alındığı için, iyi konfigüre edilmez ise güvenlik açıklarına sebep olabilir. - Performans Etkileri
Uzun süre kullanılmayan fonksiyonlar ilk kez tetiklendiğinde cold starts durumu oluşur. Bu durum fonksiyonun çalışmaya başlamasını geciktirir ve performansı olumsuz etkiler. - Test Etme
Geliştiriciler unit testleri sorunsuz bir şekilde geliştirebiliyor olsa da integration testler için aynı durum söz konusu değildir. Farkı bileşenler arası etkileşim gerektiren testlerin koşulması zor bir hale gelmektedir. - Sağlayıcı Kısıtlaması
Bir bulut sağlayıcısının sunduğu servisler kendi aralarında kolayca entegre olabilirken, farklı sağlayıcı servisleri arasında bu durum söz konusu olmayabilir. Bu durum bizi belirli bir bulut sağlayıcısının servislerini kullanmaya bağlı kılar.
AWS
Amazon Web Services, Amazon tarafından sağlanan servislerin bulunduğu bir bulut platformudur. AWS, herhangi bir tipteki sunucu ile ilgilenmeden uygulama geliştirme imkanı sunar. Sunucusuz teknolojiler, modülerliği arttırmak ve maliyetleri optimize etmek için otomatik ölçeklendirme, yerleşik yüksek erişilebilirlik ve kullanıma göre ödeme modeli içerir.
Temel olarak işleme, uygulama entegrasyonu, veri saklama başlıklarında hizmetler sunar.
Microservices
Uygulamalar başlangıcından itibaren gittikçe büyür ve gün geçtikçe kontrol edilmesi zor bir hal alır. Aslında birbirinden farklı işleri yapmakta olan hizmetlerin tek bir yapıda bulunuyor olması aralarında gereksiz bir bağımlılık oluşmasına sebep olur. Bu bağımlılıklar gittikçe daha kompleks bir hale gelir ve baş edilemez bir hale bürünebilir. Bu sorunu ortadan kaldırmak için iş tanımları ve kapsamları belirli servisler oluşturarak, her bir servisin birbirlerinden bağımsız hatta habersiz çalışabilmesi sağlanabilir.
Avantajları
- Ölçeklendirme
Servisler birbirlerinden bağımsız uygulamalar olduklarından, her biri tek başına ölçeklendirilebilir. Servislerin ihtiyaçları diğer servislere bir etkisi olmadan giderilebilir. - Veri İzolasyonu
Mikroservis mimarisine göre her bir servis kendi veri tabanına sahiptir. Bu servis ile alakalı verilerin gereksiz yere erişilmesini engeller. Aynı zamanda veri tabanlarının ayarlanması da servis özelinde olduğu için bir yan etki yaratması söz konusu olmaz. - Hata İzolasyonu
Servisler birbirlerinden bağımsız olduklarından, birinde oluşan hatanın diğer servislere veya bütün sisteme etkisi minimize edilir ve alakalı yerde kontrolü sağlanmış olur. - Teknoloji Özgürlüğü Birbirinden bağımsız sistemler, birbirleri ile haberleşme konusunda entegre olabildikleri sürece farklı teknolojileri kullanmakta özgürdürler. Bu da servis ile alakalı en uygun teknolojilerin seçilmesi ve daha iyi performansın alınabilmesini sağlar.
- Anlaşılabilirlik
Bütün sistem daha küçük parçalara bölündüğü için her bir servis kendi içerisinde daha kolay kavranabilir hale gelir. Ayrıca her bir servis için atanan küçük takımlar bütün sistem yerine sadece bu servise özgü mantıkları daha doğru ve kolayca kavrayabilir. - Bakım ve Geliştirme
Her servis birbirinden bağımsız geliştirildiği ve deploy edildiği için, yeni özellikler eklenmek istendiğinde veya hata çözümlerinde bütün sistemin deploy edilmesi gerekmez. Aynı şekilde hatalı bir sürümde rollback işlemini de sadece belirli serviste yapma imkanı sunar.
Dezavantajları
- Komplekslik
Her bir servis tek başına monolitik mimariden daha basit bir yapıya sahip olsa da servislerin birbiriyle iletişimi de düşünüldüğünde bütün sistem daha kompleks bir yapıya sahiptir. - Geliştirme ve Test
Servislerin geliştirilmesi ve test edilmesi, diğer servislere bağımlılığı bulunduğu durumlarda, monolitik yaklaşıma kıyasla daha zor bir hal almaktadır. Senaryoya dahil olan her bir servisin geliştirme esnasında uygun durumda bulunması gerekir. - Yönetim
Farklı teknolojilerin kullanılması proje genelinde bir standart oluşmasını zorlaştırabilir. Her bir servis kendi standartlarını oluşturur ise servisler arası tutarsızlıklar söz konusu olabilir. - Monitörleme
Her bir servis çalışma süresince kendi loglarını üretir ve bü loglar servislere özgü bir şekilde monitör edilir. Bu durum servis sayısı çoğaldıkça log takibini zorlaştırabilir. - Ağ Problemleri
Servisler arası iletişim ve zincirleme servis çağrıları çoğaldıkça, gecikmeler performansa olumsuz etki edebilir. - Veri Bütünlüğü Her bir servis kendi veri tabanından sorumlu olduğu için servisler arası kullanılan verilerin tutarlılığını korumak bir zorluk yaratır. Bu durumda genellikle eventual consistency prensibi benimsenir.
- Versiyonlama
Her bir servis birbirinden bağımsız versiyonlanabilir olduğundan, diğer servisler ile entegrasyonuna yan etkileri olmamasına dikkat edilmelidir.
Uygulama Mimarisi
Yukarıda örnek bir serverless mikroservis mimarisi gösterilmiştir. Son kullanıcı tek bir endpoint üzerinden 3 farklı mikroservise ulaşabilmekte ve bu servislerde işlem yapabilmektedir. Product servisi satın alınacak ürünleri yönetmektedir. Basket servisinde ise satın alınan ürünler yönetilir. Ordering servisi ise siparişin alınmasından ve iletilmesinden sorumludur. Bir ürün satın alındığında Basket servisi, Ordering servisine asenkron olarak haber vermektedir.
API Gateway
Amazon API Gateway kullanıcılardan gelen istekleri almak ve bu istekleri çeşitli konfigürasyonlar, kurallara göre ilgili product, basket, ordering servislerine yönlendirmekle görevlidir (mikroservisler için bir giriş noktası). Uygulamada RESTful API geliştirilmesi ve senkron isteklerin, cevapların paylaşılmasında AWS API Gateway kullanılmakta. Gateway mikroservislerde bulunan Lambda fonksiyonlarına sunucusuz bir API Proxy sağlar, bu sayede CRUD isteklerini ilgili mikroservislere iletir.
Lambda
AWS Lambda, sunucu sağlama ve yönetme ihtiyacı olmadan yazılan kodu çalıştırmaya yarayan sunucusuz event-driven programming ve serverless computing platformudur. Koldar sadece ihtiyaç duyulduğunda çalıştırılır ve işlem süresine göre ücretlendirilir, kod çalışmadığı durumlarda herhangi bir ücretlendirme olmaz. İhtiyaca göre otomatik olarak ölçeklendirme yaparak performansta herhangi bir kayıp yaşanmasını önler. Yazılan kod yüksek kullanılabilirliğe sahip bir altyapıda çalıştırılır, sistem bakımı, kapasite ve otomatik ölçeklendirme, monitoring, loglama gibi işlemlerin tümünü kendi gerçekleştirir. Öğrenilmesi gereken yeni dil, araç veya çerçeve yoktur. Yerel olanlar dahil olmak üzere istenilen üçüncü taraf kitaplık kullanılabilir. Ayrıca herhangi bir kod (entegrasyonlar, SDK’lar, kitaplıklar ve daha fazlası) bir Lambda Katmanı olarak paketlenebilir.
Örnek iş akışı ise şu şekildedir:
- Kullanıcı, bölgesindeki hava durumunu öğrenmek için linke tıklıyor.
- Amazon API Gateway, ilgili endpointe REST API çağrısı yapıyor. Lambda burada tetikleniyor.
- Lambda fonksiyonu, DynamoDB’den kullanıcının istediği bölgeye ait hava durumu bilgisini istiyor ve kullanıcıya dönüş yapıyor.
AWS Lambda, bulut üzerinde birçok farklı etkinliği gerçekleştirmek için kolay bir yöntem sunar. Örneğin AWS Lambda’yı Amazon DynamoDB’den veri alıp dönüştüren mobil arka uçlar oluşturma, Amazon S3’e yüklenen nesneleri sıkıştıran veya dönüştüren işleyiciler tasarlama, herhangi bir Amazon Web Service için yapılan API çağrılarını denetleme ve raporlama ve Amazon Kinesis kullanarak akış verilerinin sunucusuz işlenmesi gibi amaçlarla kullanılabilir.
EventBridge
Mikroservis mimarisinde her servisin birbirinden olabildiğince bağımsız olabilmesi önemli noktalardan biridir. Bu sebeple de servisler arası event tabanlı iletişim ile asenkron bir haberleşme sağlamak en mantıklı hareket olacaktır. Bu noktada da uygulamamızda AWS EventBridge kullandık ve her bir servisimizin birbirinden haberi dahi olmadan haberleşebiliyor olmasını amaçladık. EventBridge kaynaklardan aldığı eventleri, bu eventleri dinleyen hedeflere dağıtarak haberleşmeyi sağlar.
DynamoDB
Uygulamamızda mikroservis mimarisinin önerdiği üzere her servisin kendi verilerini saklamasını sağlamak için AWS DynamoDB kullanıldı. DynamoDB her boyuttaki servis için iyi bir performans verebiliyor olması dolayısıyla mikroservis mimarisi için iyi bir tercih. Ayrıca DynamoDB sahip olduğu özellikler ile, örneğin kolayca ölçeklenebilir olması gibi, mikroservislerin bağımsız bir şekilde geliştirilebilmesini kolaylaştırıyor.
SQS
Başka herhangi bir servise ihtiyaç olmadan mikroservisler arasındaki iletişimin asenkron şekilde, mesaj kuyrukları yardımıyla kurulmasını sağlar. Örnek uygulamada mesaj kuyrukları yardımıyla servisler arası iletişim (Basket – Ordering Mikroservisleri) kurmak için AWS SQS kullanılmakta.
Amazon Event Bridge, Basket mikroservisinden gelen checkout isteğini AWS SQS’deki mesaj kuyruğu ile paylaşır ve paylaşılan bu mesaj Order mikroservisi tarafından asenkron olarak işlenmek üzere kuyruktan alınır. Bu sayede daha esnek ve dayanıklı bir yapı oluşmasını sağlar.
Cloud Development Kit (CDK)
Cloud Development Kit, AWS kaynaklarını programlama dilleriyle yönetebilmeyi sağlar. Örnekte belirtilen uygulama mimarisinin tamamı AWS CDK ile oluşturulabilir. Detaylı bilgi: Cloud Development Kit (CDK)
CloudWatch
Mikroserviste izlenmesi gereken birçok servisi vardır. Servislerdeki kaynak kullanımı, uygulama performansı ve operasyonel işlem hakkında sistem çapında görünürlük elde etmek için CloudWatch kullanılabilinir. Geliştiriciler her servis için ayrı kriterler yazarak istenilen verilerin izlenmesi sağlayabilir. Loglar sorunları gidermek ve sorunları belirlemek için kritik öneme sahiptir. Amazon EC2 bulut sunucularında çalışan uygulamalar için, günlük dosyalarını CloudWatch Logs’a göndermek için bir arka plan programı mevcuttur. Lambda ve Amazon ECS, logları CloudWatch Logs’a gönderir.
Şekilde, bazı hizmetlerin log günlüğüne kaydetme özelliklerini göstermektedir. Geliştiriciler daha sonra Amazon OpenSearch Service ve Kibana gibi araçları kullanarak bu logları arayabilir ve analiz edebilir. Amazon Athena, Amazon S3’teki merkezi günlük dosyalarına karşı tek seferlik bir sorgu çalıştırmak için kullanılabilir.
CloudFormation
CloudFormation, Infrastructure as Code tekniğini kullanarak AWS kaynaklarını konfigürasyon dosyalarında tutarak yönetmeyi amaçlamaktadır. Örnekte belirtilen uygulama mimarisinin tamamı CloudFormation ile oluşturulabilir. Detaylı bilgi: Cloudformation
Sonuç
Mikroservis ile serverless mimarisi kullanıldığında maaliyet daha düşüktür, verimliliği yüksektir ve serverless fonsiyonları diğer servislerle kolayca entegre olunabilir. Fonsiyonlar, farklı kullanım durumları için veritabanları, mesaj kuyrukları ve API yönetim araçlarıyla entegre edilebilir. Bu sayede kodu diğer fonksiyonlar için yeniden kullanılabilir hale getirmeyi sağlar. Uygulamanın ölçeğini genişletirken yazılması gereken ilk kod miktarının azaltılmasına yardımcı olur. Serverless mikroservisler karmaşık ve gelişen uygulamalar için uygundur. Servisleri kolayca yönetilip ölçeklenebilmelerini sağlar. Mikroservisler ve serverless mimariler aynı yapısal ilkeleri izler. Her ikisi de ölçeklenebilirliğe ve esnekliğe öncelik veriyor. Amazon API Gateway, entegrasyon ek yükünü azaltmak için bir dizi popüler programlama dilinde programatik olarak oluşturulmuş istemci SDK’ları sağlıyor.