Serverless Architecture — Sunucusuz bir dünya mümkün mü?

Merhaba,

Cloud servisler giderek hayatımızda önemli bir yer tutmaya başladı. Geleneksel mimariler (ki bunlar 7–8 sene öncesinin state-of-the-art mimarileri) yavaş yavaş mikroservis mimarilerine doğru evriliyorlar. Mikroservislerin ne olduğunu, kavramsal olarak ne anlama geldiğini anlatan bir sürü makale, video bulmak münkün. Hatta Uber, Spotify, Netflix gibi şirketlerin bu yolda ne sıkıntılar yaşadıklarını ve bunları nasıl aştıklarıyla ilgili konferans video’ları da mevcut. Fakat mikroservisleşme süreci her şirketin gerçekliği ve ihtiyaçları farklı olduğundan dolayı, her şirket bunun için kendine özel farklı süreçler işletiyor, olay sadece teknik alt yapı meselesi değil. Yazılım geliştirme süreçleri, takımların nasıl organize olacağı ve DevOps gibi üzerinde düşünülmesi gereken bir çok konu var. Mikroservisleşme yolunda kullanılabilecek oldukça fazla yaklaşım, teknoloji ve mimari pratik var. Ama bugün üzerinde durmak istediğim konu Serverless Architecture yani Sunucusuz Mimari.

Gerçekten bir sunucu yok mu?

Sunucusuz mimari olarak adlandırılmasının sebebi bizim herhangi bir şekilde bir sunucuyu ve ya bir sanal makinayı ayağa kaldırılmak, konfigure etmek (Provision, Configuration) gibi işlerle uğraşmıyor olmamız. Yani PaaS’ın (Platform as a Service) olduça evrimleşmiş bir versiyonu diyebiliriz. Serverless Architecture, BaaS(Back-end as a Service) ve ya FaaS (Function as a Service) olarak da ifade ediliyor, FaaS’dan da anlaşılacağı üzere özünde tamamen Function’larla ilgili. Yani siz function’larınızı yazıyorsunuz, kullandığınız provider bu function’ları belli event’lere göre çalıştırıyor. Sizin altyapı, network yapısı gibi konular hakkında endişe etmenize gerek kalmıyor.

Developer’lar olarak geliştirdiğimiz uygulamalarımızın büyük bir kısmı aslında event bazlı çalışıyor, bir etkileşim olmadan, bir yerden bir Request gelmeden birşeyleri çalıştırmıyoruz. Yani çoğu zaman sürekli çalışan kod parçacıklarımız yok, biz de uygulamalarımızı event bazlı yazıyoruz.

Peki neler yapabiliriz? Teorik olarak çoğu uygulamayı tamamen sunucusuz bir mimariye taşımamız mümkün. Üç büyük cloud platformu Amazon AWS, Microsoft Azure ve Google Cloud Platform yazdığınız Fuction’ları API endpoint’lerine map etmenize imkan sağlıyor, yani mevcut API’lerinizi pekala sunucusuz bir mimariye taşımanız mümkün.

Daha önce de bahsettiğim gibi belli event sonucu çalışmasını da sağlayabilirsiniz. Örneğin belli bir dosya alanına bir resim atıldığı zaman, yazdığınız function tetiklenir ve atılan resim üzerine bir Resim Tanıma (Image Recognition) algoritması çalıştırabilirsiniz ve istemediğiniz tipte bir içerikse bunun yayınlanmamasını sağlayabilirsiniz. Bunun gibi örnekleri çoğaltmak mümkün.

Mesela biz yakın zamanda Codefiction’ın web sitesini Amazon’un Lambda ve S3 alt yapısına geçirdik. Angular 4 ile yazdığımız sitemizi Amazon S3'de bir bucket’a upload ediyoruz, böylece hosting gibi bir ihtiyacımız ortadan kalkmış oluyor, çünkü Amazon’un bucket’ları HTTTP request’lerini karşılıyabiliyor. Ayrıca back-end servislerimizi de AWS Lambda’ya taşıdık. Yani codefiction.tech tamamen Serverless Architecture üzerinde çalışıyor. Mert’in bu geçişi nasıl yaptığımızı anlatan detaylı bir yazısı var.

Amazon Lambda, Azure Functions ve Google Cloud Functions

Şuan üç büyük cloud paltformu sunucusuz mimari kullanabilmemiz için gerekli alt yapıyı bize sağlıyorlar. Sunucusuz Mimari denildiği zaman aklınıza sadece function’larınızı host edebilceğiniz bir ortam gelmesin. Cloud Platform’ların en büyük gücü, bize bir uygulama geliştirirken ihtiyacımız olan diğer servisleri de sağlıyor olmaları. Bugün bir uygulama geliştirirken ;

  • Database (Sql veya NoSql)
  • Security, Identity (Authentication, Authorization)
  • Storage
  • Notification (Sms, Email, Push Notification)
  • Logging
  • Caching

Gibi bir çok farklı şeye ihtiyaç duyuyoruz. Cloud Platform’ların en büyük avantajı bu alt yapıları size sunuyor olmaları. Zaten sunucusuz mimarinin güce de cloud platform’ların size sağladı bu çevre alt yapılarla entegre çalışabiliyor olmasından geliyor. Elbette ki Cloud Platform’ların size sağladı bu yapıları kullanmak zorunda değilsiniz. Yazdığınız function’ları mevcut alt yapılarınızla da entegre etmeniz mümkün. Örneğin yazdığınız bir function’ın SQL veritabanınıza erişmesi yönünde bir engel yok.

Cloud Platform’ların bir diğer avantajı da Monitoring, Alerting gibi konularda size hazır yapılar sunması.

Bu noktada function’ımızı hangi dillerle yazıyoruz sorusu aklınıza gelmiştir sanırım. Özellikle Amazon ve Azure bir çok farklı dilde geliştirme yapmanıza imkan sağlıyor. Google şu an sadece Node.js (javascript) destekliyor.

Amazon Lambda

Yaklaşık üç hafta önce bir haftasonu büyük bir hevesle Aws Lambda’ya daldım. Bir prototip çıkartma imkanım oldu, oldukça güzel bir tecrübeydi. Hatta sonrasında bu konuyu Codefiction olarak yaptığımız bir podcast’de de tartıştık.

AWS Lambda .Net Core 1.0'ı desteklemesi ilk duyduğunuzda sizi şaşırtabilir ama Microsoft’un Linux Foundation’a, Google’ın .Net Foundation’a girdiği daha güzel bir dünyadayız artık :)

Ayrıca Azure’un AWS Lambda’dan da fazla dil destekliyor olması sizi daha da şaşırtabilir.

Lambda, .Net Core 1.0 C#, node.js (javascript), Java ve Python destekliyor. Ben .Net Core ve C# kullanarak bir prototip geliştirdim, o yüzden biraz işin o tarafından bahsedeceğim.

Amazon Visual Studio için en az Azure kadar güzel bir Toolkit geliştirmiş, function’larınızı deploy edip, test etmenizi oldukça kolaylaştırıyor. Bu adresten indirip kurabilirsiniz ;

https://aws.amazon.com/visualstudio/

Toolkit kullanmadan da geliştirme yapmanız mümkün. Örneğin .Net Core CLI (Command Line Interface) kullanarakta, function’larınızı deploy edebilirsiniz. Zaten yazdığınız function’ları CI/CD pipeline’ınıza entegre etmek istiyorsanız bir anlamda CLI kullanmaya mecbursunuz. Desteklenen diğer diller için de benzer CLI komutları var.

Visual Studio toolkit’ini kurduktan sonra VS’e yeni proje tipleri ekleniyor, aslında bu proje tiplerinin tek olayı, gerekli SDK’ların proje eklenmesini ve ön konfigurasyonlarını hazır yapılıyor olması. Dediğim gibi VS toolkit’ini kurmak zorunda değilsiniz, SDK’ları nuget’ten kendiniz de indirip hemen geliştirmeye başlayabilirsiniz ama toolkit geliştirme sürecinizi oldukça kolaylaştıracaktır.

AWS Lambda içerisinde Lambda Application diye bir kavram da var. Bunun anlamı aslında belli bir işi yapmak için bundle’ladığınız function’lar topluluğu. Buna verilebilecek en iyi örnek bir API olurdu heralde. Mesela bir e-ticaret sisteminde ürünlerden sorumlu bir API olduğunu düşünelim, haliyle çeşitli işler için birden fazla endpoint olacaktır, ayrıca yine security, caching, database gibi yapıları da kullanıcaktır. AWS Lamda bu nokta da size API Gateway diye bir yapı sağlıyor, bu yapı sayesinde belirlediğiniz HTTP endpoint’lerinin Application içerisinde yazdığınız function’ları tetiklemesini sağlayabiliyorsunuz.

Ama beni can evimden vuran Amazon’un .Net Core ile yazılmış mevcut API’nizi çok ufak kod değişikliğe ile bir Serverless Application haline getirmenize imkan sağlamış olması oldu. Bu noktada belirmeliyim ki Amazon maalesef .Net Standard Library 1.6 (.Net Standard değil, farklı şeyler) destekliyor olması. Nuget’de kullandığımız bir çok popüler library’nin son versiyon’ları .Net Standard Library 1.6.1 ile yazılmış durumda. Prototip uygulamayı geliştirirken bu library’lerin (Autofac, AutoMapper, Newtonsoft Json) .Net Standard Library 1.6 kullanan versiyonlarını da buldum ama mevcut paketleri downgrade etmek oldukça can sıkıcıydı. Ama eminim .Net Core 2.0'ın çıkıp standartlaşmasıyla beraber bu tip sorunlar da ortadan kalkacaktır.

Dediğim gibi ben .Net Core ile geliştirme yaptığım için işin biraz o tarafından anlattım ama codefiction.tech’in backend’i node.js kullanarak geliştirildi mesela, bu noktada tekrardan Mert’in yazısını okumanızı tavsiye ederim.

AWS Lamda oldukça güzel bir platform, her dilin kendine has sıkıntıları ve farklı konfigurasyonları olsa da oldukça hızlı ve kolay bir şekilde bir uygulama geliştirmenize imkan sağlıyor.

AWS Lamda’nın belli limitleri de var. Örneğin function’larınız 300 sn içerisinde yaptığı işi bitirmezse AWS otomatik olarak sonlandırıyor. Aynı şekilde account başına max 1000 Conccurent işlem yapmanıza izin veriyor.

Azure Functions

Öncelikle gönül rahatlığıyla söylemek istiyorum ki, AWS dünyasındaki hemen hemen herşeyin Azure tarafında da bir karşılığı var. Sunucusuz Mimari altyapısı da bir istisna değil. Azure Functions duyrulmadan önce Azure dünyasında WebJobs yapısı vardı. Azure bunu bize PaaS olarak sunuyordu. WebJob’lara zaman bazlı veya başka trigger’lar tanımlanıp çalışması sağlanabiliyordu. Azure Functions aslında bütün bu özelliklere sahip ve daha fazlasını yapıyor. Daha fazla event desteği var ve AWS’dekine benzer olarak HTTP trigger’lar da tanımlanabiliyor. Aslında bu açıdan baktığımız zaman AWS Lambda ile hemen hemen aynı özelliklere ve imkanlara sahip.

Azure Functions C# script ve Full .Net Framework destekliyor. AWS Lambda’nın .Net Core desteklerken Azure Functions’ın Runtime’larını hala .Net Core’a port etmekle uğraşıyor olmaları ilginç gelebilir :D ama .Net Standard 1.3 library’lerinizi çalıştırmanıza imkan veriyor. .Net ile uygulama geliştiriyorsunuz Full .Net Framework’e destek vermesini bir avantaj olarak da yorumlayabilirsiniz, özellikle hala ezici bir çoğunluğun .Net Framework ile uygulama geliştirdiği düşünülürse bu oldukça güzel bir özellik. Ayrıca Azure alt yapısını kullanabileceğiniz gibi Azure, Azure Functions Runtime’ı da ayrı bir ürün olarak veriyor, böylece kendi kuracağınız bir ortamda da (on-premises) function’larınızı çalıştırabiliyorsunuz.

Bunun haricinde Azure F#, node.js (javascript), Python, Batch, PHP ve Powershell’de destekliyor.

Aynı 300 sn limiti Azure Functions için de geçerli fakat AWS’nin aksine Conccurent işlem için bir kısıtlama getirmemişler.

Google Cloud Functions

Google Cloud Platformu diğer iki platformla karşılaştırdığımız zaman özellik olarak biraz daha geride ve nispeten daha yeni. Ben önümüzdeki aylarda Google’un bu konuya daha çok eğileceğini düşünüyorum. Zaten istikrarlı olarak bu alana yatırımlar yapıyorlar. Örneğin daha Mayıs ayında umut vaadeden Istio adında bir Microservis altyapısını duyurdular, incelemenizi tavsiye ederim.

Açıkçası Google Cloud Functions’ı diğer iki platformun aksine test etme imkanım olmadı, zaten hala beta durumunda. Google şuan için tek bir dil destekliyor o da javascript. Ben Google’ın önümüzdeki aylarda rakiplerinin durumunu da dikkate alarak hem Sunucusuz Mimari kısmını hem de genel olarak Cloud Platformuna daha çok yatırım yapacağını düşünüyorum. Biraz geç kalmış gibi dursa da Google çapındaki bir firmanın bu alana yapacağı yatırımlarla rakiplerini zorlayacağını tahmin etmek güç değil.

Sunucusuz bir dünya mümkün mü?

Bu soruya cevap vermeden önce Sunucusuz Mimari’nin avantajları ve dezavantajlarından bahsetmek istiyorum.

Bir kere en büyük avantajı Server bizim için soyut bir kavram haline geliyor, herhangi bir şekilde bir Sunucu, VM’i ve ya Container’ı yönetmiyoruz, konfigure etmiyoruz. Alt yapımızı ölçeklendirmek (scalability) oldukça kolay, aslında scale up/down için biz özellikle birşey yapmıyoruz bunu bizim için Cloud Platform’lar yapıyor. Sunucu kullanımıyla karşılaştırırsak çok daha ucuz, Sub-Second ödeme söz konusu ve bu da oldukça ucuz, yazdığınız function çalışmadığı sürece hiç bir ücret ödemenize gerek yok. Göreceli olarak development oldukça kolay, Server gibi konular gündemimizde olmadığı için sadece yazdığımız koda odaklanabiliyoruz. En büyük avantajlarından biri de deployment’ı çok hızlandırıyor olması. Örneğin docker’la karşılaştırırsak herhangi bir şekilde Container build etme, konfigure etme gibi adımlar olmadığından, sadece function’ımızı deploy ettiğimizden dolayı oldukça hızlı. Aynı zamanda resilient (dayanaklı) bir mimariye sahip oluyorsunuz, aldığınız bir exception veya hatanın bütün application’ı etkilemesi mümkün değil, function’ların instance’ları birbirlerinden izole çalışıyorlar. Aslında stateless çalışıyorsunuz herşey çok güzel.

Bu kadar pembe bir tablo çizince Sunucusuz Mimari’nin hiç bir dezavantajı olmadığını düşünüyor olabilirsiniz ama maalesef öyle değil :) Bunlara tam olarak dezavantaj demek ne kadar doğru emin değilim ama dikkate alıp, üzerinde düşünmeniz gereken konular, eğer ödemeniz gereken bedel sizin için sorun değilse bu saydıklarım sizin için dezavantaj da değil. Sunucusuz Mimariye geçiş yapmayı düşünüyorsanız üzerinde düşünmeniz gereken oldukça fazla konu var, özellikle bu yazıyı okuduktan sonra kafanızda “haydi herşeyi Sunucusuz Mimariye geçirelim !!!” şeklinde bir düşünce canlandıysa acele etmeyin. Bunu konuyu ben de ilk araştırdığımda benzer bir düşünceye girip, ofise geldiğimde bir gazla “API’yı tamamen AWS Lambda’ya taşımalıyız !!!” dedim. Ama durum öyle değil, konuyu derinlemesine araştırıp, insanların yaşadıkları sıkıntıları okuyunca, konu üzerinde biraz daha aklı selim düşünmeye karar verdim.

Öncelikle vendor-lock in durumuna düşmeniz çok olası, yani bir Cloud Provider aşırı bağımlılık, sırf function’larınız açısından olaya bakmayın, function’larınız Cloud Provider’ın diğer servislerini de kullanıyorsa daha da bağımlı hale geliyorsunuz. Olayı AWS ve Azure özelinde ele alırsak birbirleri arasında geçiş yapmanız nispeten daha kolay ama bunun için iyi tasarlanmış abstraction’lar yapmanız gerekiyor, bu da sizin geliştirme süreçleriniz için ekstra maliyet demek. Sunucusuz mimarinin en büyük avantajlarından biri hızlı deployment yapabilmeniz ve değişen ihtiyaçlara hızlı ayak uydurabilmeniz, yani kullan at geliştirmeler de yapmanıza imkan sağlıyor. Eğer bu tip bir abstraction işine girerseniz bu avantajdan faydalanma oranınız azalacaktır.

Debugging, Monitoring gibi konular da tamamen Cloud Provider’ınıza bağımlısınız, onların sağladığı tool’lara göre kod yazmanız gerekebilir, ayrıca söylemeliyim ki geleneksel uygulamalara göre debug etmek çok daha zor.

Mimarinizi oldukça fazla atomize etmenize imkan sağlıyor, fakat bu süreçte iyi bir tasarım yapmazsanız, kısa zamanda kendinizi yönetmesi oldukça zor olan yüzlerce bağımsız function’la uğraşırken bulabilirsiniz. Aynı şekilde CLI command’lerini kullanarak deployment yapmanız oldukça kolay olsa da bunların versiyonlanması, gerektiğinde roll-back edilmesi gibi CI/CD açısından düşünmeniz gereken bir sürü konu var. O yüzden normalden daha sistematik ve organize bir şekide ilerlemeniz gerekiyor. Bir grup function’ı deploy ederken ve ya roll-back ederken geçici bir süreliğine onları tetikleyen yerleri devre dışı bırakmanız gerekebilir.

Testing konusu da daha fazla efor gerektiriyor, çok atomize function’lar yazdıysanız, Unit Test’den ziyade daha çok Integration Test yazmanız gerekebilir, Cloud Provider’ının size sağladı context nesnelerini mock’lamakta zorlanabilirsiniz.

Limitasyonları dikkate almanız gerekiyor, örneğin 300 sn uzun bir süre gibi gelse de yapacağınız bulk işlemler, arka planda çalışması gereken çeşitli job’lar bu mimariye uygun olmayabilir. Aynı şekilde bazı Provider’ların koyduğu 1000 conccurent işlem limiti duruma göre alt yapınızda DDos etkisi yaratabilir.

Kendinizin sunucu veya container kullandığı bir senaryo ile karşılaştırırsak, performans sıkıntıları mevcut. Yazdığınız function çok sık çağrılmıyorsa ilk çağrımlarda oldukça yavaş çalışabiliyor, sonraki çağrımlar daha hızlı olsa da sunucu modeline göre yine de daha yavaş olabiliyorlar. Performans kritik bir iş yapıyorsanız size uygun olmayabilir.

Peki bütün bu anlattıklarıma rağmen, Sunucusuz bir dünya mümkün mü?

Sunucusuz Mimari halen yeni bir konu sayılır. Cloud Provider’lar istikrarlı bir şekilde bu alana yatırım yapıyorlar. Benim inanıcım bundan birkaç sene sonra ağırlıklı olarak yazılımların bu mimariyle geliştirileceği yönünde. Cloud Provider’ların saydığım kısıtların ortadan kaldırması için çalışacaklarını düşünüyorum, çünkü daha öncede söylediğim gibi çok fazla avantajı var.

Benim tavsiyem, eğer geçmediyseniz, şimdiden denemeler yapmanız ve hatta ufak çevre uygulamalarınızı geçirip, testler yapmanız ve tecrübe kazanmanız yönünde. Ben bir çok şirketin stateless API’larını ufak ufak buraya taşıyabileceğini düşünüyorum, maliyetler olarak bakarsanız büyük avantajları var. Dezavantajlar olarak saydığım şeyler bir çok şirket için kabul edebilir seviyelerde.

Okuduğum bazı makalelerde Docker gibi teknolojilerin, geleneksel mimarilerle, sunucusuz mimari arasında bir geçiş teknolojisi olduğunu ve nihai olarak önümüzdeki yıllarda sunucusuz tarafa doğru gideceğimizden bahsediliyor. Teknolojinin bu kadar hızlı geliştiği ve her gün yeni imkanlar sunduğu bir dönemdeyiz ve geleceğin neler getireceğini kestirmek zor. Benim tavsiyem en azından bireysel olarak bu konuyu araştırıp denemeler yapmanız.

Bir sonraki yazımda görüşünceye dek hepinize sunucusuz günler dilerim.

Kaynaklar