- API kimlik doğrulama hizmeti sunan Unkey, Cloudflare Workers tabanlı serverless mimariden Go tabanlı durum tutan sunuculara geçerek performans ve mimari karmaşıklık sorunlarını çözdü
- Yeni yapı, 6 kat daha hızlı yanıt süreleri sağlarken karmaşık cache bypass yöntemlerini ve veri hattı ek yükünü ortadan kaldırdı
- Serverless ortamında fonksiyon çağrıları arasında kalıcı bellek garantisi olmadığından her cache okuması ağ isteği gerektiriyordu ve p99 düzeyinde 30 ms'nin üzerinde cache gecikmesi oluşuyordu
- Dağıtık sistemden daha basit bir uygulama mimarisine geçiş sayesinde self-hosting mümkün hale geldi, platform bağımsızlığı kazanıldı ve geliştirici deneyimi büyük ölçüde iyileşti
- Serverless, düzensiz iş yükleri veya basit request/response kalıpları için uygun olsa da, tutarlı düşük gecikme ya da kalıcı durum yönetimi gerektiğinde durum tutan sunucular daha etkili oluyor
Serverless sınırları ve performans darboğazları
- Unkey'de API kimlik doğrulama, istek yolunun merkezinde yer alıyordu; bu yüzden milisaniye düzeyindeki gecikmeler bile kullanıcı deneyimini doğrudan etkiliyordu
- Cloudflare Workers'ın küresel edge dağıtımı ve otomatik ölçeklenmesi cazipti, ancak cache kalıcılığının olmaması ve ağ isteği gecikmeleri sorun olarak ortaya çıktı
-
Cache sorunu
- Serverless fonksiyonlarda çağrılar arasında kalıcı bellek olmadığından, her cache sorgusu için harici bir ağ isteği gerekiyordu
- Cloudflare cache sorgularında p99 gecikmesi 30 ms'nin üzerinde ölçüldü
- Birden fazla cache katmanı (SWR, Redis vb.) eklemek de temelde "0 ağ isteğinden" daha hızlı olamazdı
- Sonuç olarak hedeflenen 10 ms altı yanıt süresine ulaşılamadı
-
SaaS bağımlılığı sorunu
- Serverless, altyapı yönetimi yükünü azaltıyor gibi görünse de pratikte ek SaaS araçlarını zorunlu hale getiriyordu
- cache → Redis, batch işleme → Queue, log → Durable Objects gibi
- Her servis gecikme, maliyet ve hata noktaları ekliyordu
- Cloudflare Durable Objects, Queues ve Workflows birlikte kullanılsa da gerçek karmaşıklık aslında daha da arttı
-
Veri hattı sorunu
- Serverless geçici bir ortam olduğundan her çağrıda verinin anında flush edilmesi gerekiyordu
- Event, log ve metric işlemek için karmaşık buffering ve ara servisler doğrudan inşa edilmek zorunda kalındı
- Örneğin:
chproxy üzerinden ClickHouse'a toplu log gönderimi
- Axiom'a log gönderirken rate limit'i aşmak için ayrı bir buffering sunucusu kurulması
- Sonuçta basit bir analitik özelliği bile dağıtık event işleme sistemi düzeyinde karmaşıklık yarattı
Durum tutan sunuculara geçiş
- Go tabanlı durum sunucusu (v2) devreye alınınca bellek içi batch işleme ve periyodik flush mümkün hale geldi
- Ek servisler ya da karmaşık veri hatları gerekmiyor
- Bakım, debugging ve yerel test büyük ölçüde sadeleşti
-
Performans sonuçları
/v1/keys.verifyKey ile /v2/keys.verifyKey karşılaştırmasında gecikme 6 kat azaldı
- Cloudflare'ın 300 küresel POP'undan daha az altyapıyla bile kullanıcıların algıladığı performans belirgin biçimde iyileşti
Performans dışındaki kazanımlar
-
Self-Hosting
- Cloudflare runtime'ına bağımlı yapı nedeniyle müşteriler Unkey'i self-host edemiyordu
- Workers runtime teknik olarak open source olsa da yerelde çalıştırmak (geliştirme modunda bile) son derece zordu
- Standart bir Go sunucusuna geçilince self-hosting basitleşti
docker run -p 8080:8080 unkey/api komutuyla çalıştırmak yeterli
- Özel bir runtime veya karmaşık yapılandırma gerekmiyor
- Geliştiriciler artık tüm Unkey stack'ini birkaç saniyede yerelde çalıştırabildiği için debugging ve test çok daha kolaylaştı
- Yerel geliştirme ve debugging hızı ciddi biçimde arttı
-
Geliştirici deneyiminin iyileşmesi
- Serverless tarafında yaşanan sınırlamalar:
- fonksiyon çalışma kısıtlarını hesaba katma zorunluluğu
- çağrılar arasında durum korumanın zorluğu
- dağıtık log debugging'inin karmaşıklığı
- yerel test ortamının elverişsizliği
- Durum tutan sunuculara geçişle bu karmaşıklık vergisi (Complexity Tax) ortadan kalktı
-
Platform bağımsızlığı
- Artık Cloudflare ekosistemine bağımlı değil
- Her yere deploy edilebilir
- İstenen herhangi bir veritabanı kullanılabilir
- Runtime uyumluluğu kaygısı olmadan üçüncü taraf servislerle entegre olabilir
Migrasyon stratejisi ve çıkarılan dersler
- Migrasyon, zaman içinde birikmiş API tasarım sorunlarını düzeltmek için bir fırsat olarak kullanıldı
- Yeni v2 API, mevcut v1 ile birlikte çalışıyor; böylece müşteriler destekten kaldırma süresi boyunca iki sürümü de kullanabiliyor
- Serverless'ı korumanın bir avantajı da kullanım sıfıra inse bile v1 API'yi çalıştırmanın çok maliyetli olmaması, böylece ücretsiz bir migrasyon dönemi sağlanabilmesi oldu
-
Korunanlar
- Serverless yaklaşımın her yönü terk edilmedi
- Küresel edge dağıtım: AWS Global Accelerator kullanılarak dünya genelinde düşük gecikme korunuyor
- Otomatik ölçekleme: Fargate, serverless kısıtları olmadan ölçeklemeyi üstleniyor
-
Rate limiter performansındaki artış
- Serverless modelde hız, doğruluk ve maliyet arasında ciddi ödünleşmeler gerekiyordu; dağıtık yapı nedeniyle üçünü birden sağlamak neredeyse imkânsızdı
- Durum tutan sunucular ve bellek içi durum sayesinde daha hızlı, daha doğru ve işletme maliyeti daha düşük bir rate limiter kuruldu
Serverless ne zaman uygun, ne zaman değil?
-
Serverless'ın uygun olduğu durumlar
- Düzensiz iş yükleri: Sürekli çalışmayan sistemlerde sıfıra ölçeklenebilmenin ekonomisi çok güçlüdür
- Basit request/response kalıpları: Kalıcı durum veya karmaşık veri hatları gerekmiyorsa
- Event-driven mimariler: Altyapı yönetmeden event'lere yanıt vermek için çok uygundur
-
Serverless'ın uygun olmadığı durumlar
- Tutarlı düşük gecikme gerektiğinde: Harici ağ bağımlılıkları performansı düşürür
- Kalıcı durum gerektiğinde: Stateless yapıyı aşmaya çalışmak karmaşıklığı artırır
- Yüksek frekanslı iş yükleri: Çağrı başı ücretlendirme modeli ekonomik olmayabilir
- Ayrıntılı kontrol gerektiğinde: Platform soyutlaması kısıta dönüşebilir
-
Karmaşıklığın maliyeti
- Migrasyondaki en büyük ders, platform kısıtlarını aşmak için yapılan işlerin karmaşıklık maliyetini anlamak oldu
-
Serverless üzerinde inşa edilenler
- stateless yapıyı aşmak için gelişmiş cache kütüphaneleri
- veriyi batch işlemek için birden fazla yardımcı servis
- metric toplamak için karmaşık log hatları
- yerel geliştirme için gelişmiş geçici çözümler
-
Durum tutan sunucularda
- bunların tamamı ortadan kalktı
- çok sayıda hareketli parçaya sahip dağıtık bir sistemden basit bir uygulama mimarisine geçildi
- Bazen kısıtları aşmaya çalışmak yerine başka bir temel seçmek en iyi çözümdür
Sonraki adımlar
- Şu anda Global Accelerator arkasında AWS Fargate üzerinde çalışıyor, ancak bu geçici bir çözüm
- Gelecek yıl, müşterilerin (ve Unkey'in kendisinin) istediği her yerde Unkey çalıştırmasını sağlayacak kendi dağıtım platformu "Unkey Deploy" piyasaya sürülecek
- Durum tutan Go sunucularına geçiş, Unkey'i gerçek anlamda taşınabilir ve self-host edilebilir hale getirmenin ilk adımı
- Uygulama ayrıntıları GitHub deposunda open source olarak yayımlandı
3 yorum
Ben de bir zamanlar neredeyse serverless inananı gibi serverless mimariyi her yere uyguluyordum ama bugünlerde
ec2bir tane verdsbir taneden oluşan yapıyı daha çok tercih ediyorum. Sonra da ihtiyaç oldukça gerekenleri teker teker ayırıyorum. Serverless’i devreye almak için de çok düşündüm.Bunun çeşitli nedenleri var ama ekipte serverless bilgisi olmayan tek bir kişi bile olsa iletişim/bakım maliyeti epey artıyordu. Ayrıca tekrar sunucu işletmeye başlayınca, serverless’in düşündüğüm kadar ucuz ya da düşündüğüm kadar rahat olmadığını bir kez daha fark ettim.
Hacker News görüşleri
Birkaç yıldır serverless ortamlarıyla (çoğunlukla Amazon Lambda, ama başka şeylerle de) çalışmış biri olarak, yazarın görüşüne güçlü biçimde katılıyorum
serverless bazı alanlarda işi azaltıyor ama eşzamanlı olarak "yapay biçimde ortaya çıkan sorunları" çözmek için başka alanlarda işi artırıyor
Benim yaşadığım örneklerden biri yükleme boyutu sınırı meselesiydi
Mevcut uygulamayı serverless'a taşıdığımızda, büyük müşteri verilerini içe aktarmak için bir API endpoint'i oluşturup arka planda bir worker bağlamanın yeterli olacağını düşünmüştüm
Ama "API Gateway" (kodu çağıran proxy) üzerinden 100MB'tan büyük yüklemeler mümkün değildi ve sınırın değiştirilebilir olup olmadığını sorduğumuzda, bize sadece müşterilere dosyaları daha küçük parçalara bölüp yüklemelerini söylememiz gerektiği yanıtı verildi
Teknik olarak makul gelebilir ama gerçek dünyada müşterilerin yükleme yöntemlerini değiştirmeyeceği de bir gerçek
Bu daha çok "vakumda iyi çalışıyor" hissi veriyor; teoride havalı görünüyor ama iş pratiğe gelince, serverless'a geçerek tasarruf ettiğiniz zaman ve maliyeti sonunda serverless'a özgü sorunları çözmek için geri harcıyorsunuz
Bunu çözmek için presigned S3 URL vermek gerekir
Kullanıcının doğrudan S3'e yükleme yapıp sonra yükleme sonucunu size göndermesi ya da dosya adını request id ile ayırmak gibi yöntemlerle entegre olunabilir
AWS ile uzun süre çalışmış biri olarak bunun can sıkıcı olduğunu düşünüyorum ama rastgele dosya yükleme API'si açmanın DoS saldırısı riski büyük olduğu için 100MB sınırını da anlaşılır buluyorum
Yine de günümüz internet hızlarını düşününce 100MB eşiği biraz çağın gerisinde kalmış gibi geliyor
Ama bir noktada sınır konması gerektiğini de düşünüyorum
Şirketimiz bir zamanlar AWS SSL sertifika ekibinin en büyük müşterilerinden biriydi
Vanity URL (özel alan adı) desteği vermek istediğimiz için her alan adı için bir SSL sertifikası gerekiyordu ve bunlardan binlerce tane lazımdı
AWS'nin sertifika yönetim aracı ancak yüzler seviyesine kadar rahat çalıştığı için bu sorunun çözülmesi yaklaşık 3 ay sürdü
AWS'deki bazı servislerin çok az sayıdaki müşterinin ihtiyaçlarına hızlı yanıt verememesi şaşırtıcıydı
Başta Lambda çok umut verici görünüyordu ve bu yüzden kullanmaya başladık ama sonunda tüm Lambda projelerini bıraktık ve ihtiyaca göre container ortamlarına geçtik
Lambda'da da Node runtime'ını 1-2 yılda bir yükseltmek gerekiyor; container kullandığınızda bu döngüyü kendiniz belirleyebildiğiniz için daha esnek oluyor
Bilgisayar bilimindeki en zor problem, bir dosyayı bir bilgisayardan başka bir bilgisayara kopyalamaktır
Gelecekte okuyacaklar için bir kaynak bırakayım
"tus" uploader ve endpoint kullanılırsa yükleme sırasında parçalama, kaldığı yerden devam etme gibi özellikler sağlandığından bu tür sınırları aşmak için uygundur
https://tus.io/
Makalede anlatıldığı gibi, serverless'ın elbette kendine göre kullanım alanları var
Ama çoğu uygulama için uygun olduğunu düşünmüyorum
Özel bir durum yoksa serverless'ı çekirdek altyapı olarak kullanmayı planlamam
Pratikte altyapı yönetimini daha zahmetli hale getirdiği izlenimini veriyor
Her platformun gereksinimleri farklı, test/geliştirme biçimleri de birbirinden farklı; bu yüzden her şey muğlaklaşıyor ve lokalde test etmek zorlaşıyor
Soyutlama katmanlarının her platformda ayrı tuzakları var ve ortada gerçek bir standart da yok
Çalıştırılabilir dosyayı Docker image olarak paketlemek daha rahat ve ortam kurulumunu da yeterince soyutlayabildiği için bana daha doğal bir geliştirme ortamı sunuyor
Linux ortamı ve dosya sistemi düzeyindeki asgari soyutlamanın en verimli yaklaşım olduğunu düşünüyorum
Gerekirse aynı image'ı sunucu olarak ayağa kaldırıp on-demand ya da sürekli hazır bekleyen biçimde de çalıştırabilirsiniz
Son 10 yıldaki çeşitli teknoloji trendlerine bakınca, büyük şirketlerin yalnızca kendi ölçeklerinde gerçekten var olan problemleri çözmek için kullandığı teknolojilerin popülerleştiğini sık sık gördük
GraphQL, React, Tailwind, NextJS ve daha birçok şey buna örnek
Hiçbir araç her problem için sihirli çözüm değildir; önemli olan kendi durumunuzu ve probleminizi deneyim ve anlayışla değerlendirip seçim yapmaktır
Şu anda Amazon Lambda uygulamasını lokalde çalıştırmayı denemenin ne kadar "eğlenceli" olduğunu anlatamam bile
Dağıtımdan önce test etmeye çalışınca başlı başına bir meydan okumaya dönüşüyor
Knative (Kubernetes için Serverless) container'ı doğrudan kabul ediyor
Standart bir paketleme formatı olduğu için farklı platformlara taşımak kolaylaşıyor
O ekip aslında uygulamanın kendisini değil, durum tutan bir sunucu uygulamasına entegre edilecek bir kütüphane geliştiriyordu
Performans avantajı da serverless'ın kendisinden değil, authentication'ı müşterinin ortamına yakın yerde işleyebilmelerinden geliyordu
Aslında tüm "serverless" platformları Docker image kabul etmiyor mu?
Cloud Run'ın desteklediğini biliyorum
Benim asıl kaygım, “serverless function” yaklaşımının fazla şeyi soyutlamasından kaynaklanan sorunlar
ClickHouse binlerce küçük insert'ten hoşlanmıyor; biz de bu yüzden event'leri toplayıp büyük batch'ler halinde gönderen
chproxyadlı bir Go servisi kullanıyoruzHer Cloudflare Worker analitik event'lerini
chproxy'ye gönderiyor, o da bunları toplayıp ClickHouse'a toplu halde iletiyorSadece ClickHouse verisi için neden ayrı bir servis yapmayı seçtiklerini merak ediyorum; asenkron insert özelliği de vardı
https://clickhouse.com/docs/optimize/asynchronous-inserts
Geliştiriciler "işi kolaylaştırdığı" söylenen araçların altında kalmış gibi görünüyor
Oysa çoğu problem en temel araçlarla bile kolayca çözülebilir: derleyici, bash script'leri, kütüphaneler
Araçlara bu kadar takılmak bazen hem şirketlere hem de geliştiricilere zarar verebiliyor
Bence 2013'teki Docker, gerçekten evrensel ve olumlu bir değişim yaratan son araçtı
Ondan sonra gelenlerin bazı şirketlere faydası olsa da, herkese uydurulmaya çalışıldığında üretkenliği bozduğu ya da sistemleri çökerttiği çok örnek gördük
Bugünlerde Cloudflare gibi yerlerde v8 isolates sanki 'bir sonraki Docker' olacakmış gibi pazarlanıyor ama bazı iş yükleri için isabetli olsa da her yere uymaz
"Docker image'ını alıp internete açmak" kalıbı o kadar güçlü ki, 2040'ta bile hâlâ en güçlü yaklaşım olacağını düşünüyorum
Temelleri bilen insanların giderek azalması da ayrı bir sorun
İşlerin çoğu stack'in büyük kısmını üçüncü taraf servislere dış kaynak olarak vermek şeklinde ilerliyor ve doğrudan sizin yaptığınız şey sadece çekirdek uygulamanın bir kısmı oluyor
Yakında onu bile AI yazabilir
Tüm sektör adeta "öğrenilmiş çaresizlik" üretiyor
Düşündüğünüzden çok daha fazla insan derleyiciler, bash script'leri ve kütüphaneler konusunda zayıf
AWS Lambda aşırı ucuz
Görünürlük kazanmak için işe yarıyor!
bash script yazarak Staff seviyesine yükselmiş birini hiç görmedim
"vercel security checkpoint"e sormak istiyorum
iPhone'da Proton VPN ve Firefox Focus kombinasyonuyla Kaliforniya ve Kanada çıkış düğümleri üzerinden bağlandığımda sürekli code 99 "Failed to verify your browser" hatası alıyorum
Sorun ne?
Bu başlık beni düşüncemde daha da netleştiriyor
"serverless" teriminin kendisi o kadar belirsiz tanımlanıyor ki, adının baştan anlamsız olduğunu düşünüyorum
Sonuçta ortada hâlâ sunucular var
Bu, "elektriksiz" deyip aslında elektrik kullanmaya benziyor
Yalnızca adı değişmiş ama gerçekte ne olduğunu anlatmıyor gibi
Bence buradan çıkarılacak ders sadece "serverless kötüdür" değil
Asıl daha önemli ders şu: bir servisin bağımlılıkları varsa, o servisi istemciye yaklaştırsanız bile bağımlılıkları da beraber taşımıyorsanız uçtan uca deneyim beklenmedik şekilde yavaşlayabiliyor
Doğal olarak bağımlılıkların yakınında inşa etmek daha iyi; bu yetmiyorsa ya tüm bağımlılıkları istemciye yaklaştırmak ya da senkronize etmek gerekir ama pratikte bu süreç çoğu zaman aşırı karmaşık hale geliyor
Bağımlılıkların nasıl ve ne sıklıkta kullanıldığına göre değişir; bir DB'nin sunucuya mı istemciye mi yakın olması gerektiği de kullanım amacına bağlıdır
Bazı kullanım senaryolarında hızlı yanıt gerekir, bazılarında ise gecikme sorun değildir
Sunucuda ya da istemcide neyi cache'leyebildiğinize göre sistemi bölebilirsiniz
Bunun ille de ikili bir ayrım olarak görülmesi gerektiğini düşünmüyorum
En iyi fiyat/performansı istiyorsanız, kendi instance'larınızı kurup gereken işleri kendiniz yapmanız en doğru yol
Bulut sağlayıcılarını abartılı faturalama sihirbazlarına çevirmeye gerek yok
Şu anda ulaştığımız "local maximum", Docker container'ı standart ortam/dağıtım birimi olarak kullanıp gerekirse sadece secret'ları enjekte etmek gibi görünüyor
Bu sayede lokal test kolay oluyor ve altyapı otomasyonu, yeniden üretilebilirlik gibi ana avantajların çoğu korunabiliyor
serverless çoğu uygulama için gereğinden fazla bir yaklaşım ama bazıları için gerçekten uygun
Özellikle kendi altyapısına ihtiyaç duymayan basit araçlar, on-demand servisler ya da büyük ölçekli stateless uygulamalar serverless'a daha iyi uyabiliyor
serverless'ın mutlaka sadece basit kullanım için olduğu söylenemez ama "geleneksel web uygulaması" modeli ile serverless platformlar arasında temel bir uyumsuzluk olduğunu düşünüyorum
Sanırım artık misterio almaya hazırsınız
https://github.com/daitangio/misterio
Basit bir stateless Docker cluster wrapper'ı
Benim homelab'imde başladı ama beklenenden büyük ilgi gördü
Docker biraz microservices gibi
Bazı uygulamalar için uygun ama sektör standardıymış gibi fazla parlatıldı
Docker'ı aşırı kullanmak güvenlik yaması ve operasyon yükü doğuruyor; her projeye düşünmeden uygulandığında risk yönetimi başarısız oluyor
Bağımlılık sorunlarını da bugün geliştiricilerin büyük bölümü artık global kurulum yapmama alışkanlığıyla çözüyor
Docker eskisi kadar vazgeçilmez değil ama hâlâ baskın
Hosting sağlayıcıları açısından bakınca, Docker kullanımının marjları en az %10 artıracağını tahmin ediyorum
Aşağıda birinin değindiği "araç takıntısı"na Docker'ın da dahil olduğunu hissediyorum
Mesele serverless'ın işe yaramaması değil; yazarlar kurdukları altyapıyı yeterince iyi bilmiyordu
Gecikmeye duyarlı bir API'yi stateless edge runtime üzerine koymak acemi seviyesi bir hata ve ortaya çıkan acı da gayet öngörülebilirdi
Benim deneyimime göre bulut servislerindeki sorunların çoğu mimarinin yanlış kullanılması ya da yanlış anlaşılmasından kaynaklanıyor
Daha dikkatli tasarımla kaçınılabilecek insan kaynaklı problemler bunlar
Ama sorun şu ki, çoğu bulut sağlayıcısı ürünlerini parlak pazarlama söylemleriyle tanıtıyor ve gerçek performans metriklerini saklıyor
Lambdas benim iş yüküm için gerçekten yeterince hızlı mı, AWS RDS external replication uygun mu; bunları test etmeden bilemiyorsunuz
AWS'nin gerçek performansını doğrudan benchmark etmeniz gerektiğini deneyimle öğrendim
Asıl nokta yazarların anlayamamış olması değil; birinin bu bilgiyi paylaşmış olması değerli
Bunu sadece "acemi hatası" olarak görmek doğru olmayabilir
Gerçekte mühendisler belli bir yaklaşımın pratikte uygun olmadığını biliyor olabilir ama yöneticiler "modern yöntem bu" diyerek bunu kolayca dayatabiliyor
Ya da zaman ve maliyet kısıtları yüzünden "daha kötü seçeneği" kabul etmek zorunda kalabiliyorsunuz
Elbette gerçekten ilk uygulayan ekip ne yaptığını bilmiyor da olabilir ama her durumda bu tür hikâyeleri paylaşmanın tüm topluluğun gelişimine büyük katkı sağladığını düşünüyorum
Benim deneyimime göre, bir konuda gerçekten kesinlik istiyorsanız (hızlı autoscaling, düşük gecikme, CPU, disk, ağ hızı vb.) EC2 instance'larını kendiniz yönetmek en güvenli yol
Kontrolü başkasına bırakıp performans iyileşmesi beklemek, sonradan düzeltemeyeceğiniz darboğazlara yol açabiliyor
Sonunda yazarların "bugünün 10.000 kişisinden biri" olduğunu kabul ediyoruz
https://xkcd.com/1053/
Kişisel olarak bu bilgi ve hataları paylaştıkları için minnettarım
Mühendislik her zaman bir maliyet savaşıdır
Başlangıçta prototipleme ya da iş kurma süresini azaltmak için kullanılır
Daha sonra ise optimize ederek maliyeti düşürmek gerekir
Böyle yazılar, kişinin ne kadar mühendis olmadığını bizzat kanıtlıyor
Böyle böyle