Kendi kodunuz küçük, tek işe odaklı fonksiyonlar olarak çalışır. Bir olayla tetiklenir, işini yapar ve durur. AWS Lambda, Cloud Functions ve Azure Functions bu biçimdedir.
Serverless'ta sunucu yok olmaz; siz sunucu yönetmekten kurtulursunuz. Kodunuzu küçük fonksiyonlar halinde yazar, bir olaya (event) bağlarsınız; sağlayıcı bu fonksiyonu yalnızca çağrıldığında çalıştırır, talebe göre saniyeler içinde ölçekler ve hiçbir istek gelmediğinde sıfıra (scale-to-zero) iner. Fatura da çalışan süre ve çağrı sayısı kadar gelir. Bu sayfada serverless'ın ne olduğunu, bir fonksiyonun nasıl tetiklenip çalıştığını, cold start'ın neden ortaya çıktığını, faturalandırma ve ölçekleme modelini, hangi işlere uygun olduğunu ve sık düşülen tuzakları birlikte adım adım ele aldık.
Serverless, sunucu olmayan bir model değil, sunucuyu sizin yönetmediğiniz bir modeldir. Kapasite planlama, işletim sistemi yaması, ölçekleme ve boştaki kaynak yönetimi sağlayıcıya geçer; siz yalnızca çalışacak kodu ve onu tetikleyen olayı tanımlarsınız. İki ana biçimi vardır: FaaS (Function as a Service), kendi kodunuzu kısa ömürlü fonksiyonlar olarak çalıştırmanızı sağlar; BaaS (Backend as a Service) ise kimlik doğrulama, veritabanı veya dosya depolama gibi hazır arka uç servislerini yönetilmiş olarak sunar. Bu sayfanın odağı, kendi kodunuzu çalıştıran FaaS tarafıdır.
# bir olay fonksiyonu çağırır
handler(event, context):
# işi yap, yanıtı döndür
return { ok: true }
# altyapı görünmez:
# sunucu yok, ölçekleme otomatik,
# boştayken maliyet sıfır
Kendi kodunuz küçük, tek işe odaklı fonksiyonlar olarak çalışır. Bir olayla tetiklenir, işini yapar ve durur. AWS Lambda, Cloud Functions ve Azure Functions bu biçimdedir.
Auth, veritabanı, depolama gibi arka uç parçaları kod yazmadan, yönetilmiş servis olarak kullanılır. Kendi sunucunuzu işletmeden tam bir backend kurabilirsiniz.
Ölçekleme, yama ve kapasite kararları sağlayıcıdadır. "Sunucu yok" değil; sunucunun sizin sorumluluğunuzda olmaması anlamına gelir.
Serverless'ın kalbinde tek bir döngü vardır: bir olay (event) olur, bu olay bir tetikleyiciye (trigger) bağlı fonksiyonu uyandırır, sağlayıcı fonksiyon için anlık bir çalışma ortamı ayağa kaldırır, kod çalışır, yanıt döner ve ortam bir süre sonra söner. Tetikleyici bir HTTP isteği, bir kuyruğa düşen mesaj, bir dosya yüklemesi ya da zamanlanmış bir görev olabilir. Önemli olan: fonksiyon yalnızca tetiklendiğinde yaşar; arada boşta bekleyen bir süreç yoktur.
event HTTP / kuyruk / dosya / zaman
trigger olayı fonksiyona bağlar
init ortam ayağa kalkar # cold start ise
invoke handler() çalışır
response yanıt döner
idle ortam bir süre sıcak tutulur
sonra söner # boşta maliyet yok
Bir fonksiyon her zaman bir olaya bağlıdır: API Gateway üzerinden gelen HTTP isteği, bir message queue mesajı, bir dosya yükleme ya da cron benzeri zamanlanmış görev. Aynı kod farklı tetikleyicilere bağlanabilir.
Her çağrı kendi başına, bellekte hiçbir kalıcı durum varsaymadan çalışmalıdır. Oturum, sayaç ve dosya gibi durum dışarıda — veritabanı, cache ya da nesne deposunda tutulur.
Çalışma ortamı geçicidir; işini bitirince kaybolur. Sağlayıcı ortamı bir süre sıcak tutup yeniden kullanabilir ama bu garanti değildir — kod buna güvenmemelidir.
Bir fonksiyon uzun süre çağrılmadıysa veya talep aniden arttıysa, sağlayıcı yeni bir çalışma ortamı sıfırdan kurmak zorunda kalır: runtime başlatılır, kod yüklenir, bağımlılıklar hazırlanır. İlk çağrıdaki bu ek gecikmeye cold start denir. Ortam zaten ayaktaysa fonksiyon doğrudan çalışır — buna warm start denir ve neredeyse anlıktır. Cold start, kullanıcının doğrudan beklediği senkron yollarda (örneğin bir API isteği) hissedilir; arka plan işlerinde çoğu zaman önemsizdir.
Cold start'ta ortam sıfırdan kurulur; warm start'ta hazır ortam yeniden kullanılır. Fark milisaniyelerden saniyelere kadar çıkabilir.
Daha hızlı başlayan runtime'lar (ör. JavaScript, Go) ve küçük paket boyutu cold start'ı kısaltır. Ağır framework'ler ve büyük bağımlılıklar uzatır.
Sağlayıcılar belli sayıda ortamı önceden sıcak tutma (provisioned concurrency) seçeneği sunar. Cold start'ı yok eder ama scale-to-zero avantajından ödün verdirir.
Edge runtime'lar (ör. V8 isolate tabanlı) cold start'ı milisaniyelere indirir ve fonksiyonu kullanıcıya en yakın noktada çalıştırır; CDN ile birlikte düşünülür.
Serverless'ın ekonomisi tek bir ilkeye dayanır: yalnızca çalıştığı sürece para öder, hiç çalışmadığında hiçbir şey ödemezsiniz. Talep arttığında sağlayıcı her eşzamanlı istek için ayrı bir fonksiyon örneği başlatır (concurrency); talep düştüğünde örnek sayısı azalır ve sıfıra (scale-to-zero) iner. Fatura, çağrı sayısı ile her çağrının çalışma süresi (ve ayrılan bellek) üzerinden hesaplanır. Bu, ani ve düzensiz trafikte sürekli açık duran bir sunucudan çok daha verimlidir; ama sabit ve yoğun yükte tersine dönebilir.
# trafik arttıkça örnek sayısı artar
0 istek → 0 örnek # maliyet: 0
5 istek → 5 örnek # eşzamanlı
500 istek → 500 örnek # otomatik ölçek
fatura = çağrı sayısı × süre × bellek
# boştaki süre faturaya girmez
Serverless her iş için doğru araç değildir. Olaya dayalı, kısa süren, durumsuz ve trafiği düzensiz işlerde parlar; uzun süren, durum yoğun ya da sabit yüksek yüklü işlerde zorlanır. Doğru kararı vermek için işin doğasına bakın: tetikleyici net mi, çalışma süresi kısa mı, durum dışarıda tutulabilir mi?
Tek bir fonksiyon nadiren tek başına çalışır; gerçek bir sistem, fonksiyonları başka yönetilen servislerle örerek kurulur. HTTP isteklerini bir API Gateway karşılar ve doğru fonksiyona yönlendirir; ağır işler bir message queue üzerinden asenkron tetiklenir; durum bir veritabanı veya nesne deposunda tutulur. Bu parçaları kodla tanımlamak (IaC) ve aralarındaki olay akışını standart bir biçimde taşımak, serverless mimariyi yönetilebilir kılar.
client → API Gateway → fn:handler
│
fn:handler → queue → fn:worker
│
fn:worker → DB / storage
# senkron yol kısa; ağır iş asenkron kuyrukta
HTTP isteklerini karşılar, kimlik doğrulama, hız sınırlama ve yönlendirmeyi üstlenip uygun fonksiyonu çağırır. Ayrıntı için API Tasarımı & Entegrasyon başlığına bakabilirsiniz.
Ağır işler bir message queue'ya bırakılır; fonksiyon mesajı alıp işler. Bu, ani yükü yumuşatır ve yeniden deneme imkânı verir. Message Queues & Event başlığı bu deseni ayrıntılandırır.
Fonksiyonlar, tetikleyiciler ve izinler kodla (IaC) tanımlanır; olaylar CloudEvents gibi ortak bir biçimde taşınır. Böylece mimari tekrarlanabilir ve sağlayıcıdan daha bağımsız olur.
Serverless operasyon yükünü azaltırken yeni türden zorluklar getirir. Çoğu, durumu yanlış yerde tutmaktan, görünürlüğü kaybetmekten ya da tek bir sağlayıcıya farkında olmadan kilitlenmekten doğar. Aşağıdaki tuzakları baştan bilmek, ileride pahalıya patlayacak sürprizleri önler.
Senkron, kullanıcının beklediği yollarda ilk çağrı yavaş gelebilir. Hafif runtime, küçük paket veya provisioned concurrency ile yönetilmezse kullanıcı deneyimini bozar.
Bellekte tutulan durum bir sonraki çağrıda kaybolur. Oturum, sayaç ve dosya dışarıda — veritabanı, cache ya da nesne deposunda saklanmalıdır.
Yüzlerce kısa ömürlü fonksiyon arasında bir isteği izlemek zordur. Dağıtık izleme (tracing) ve merkezi loglama olmadan hata ayıklamak körlemesine olur; Observability & Loglama başlığına bakın.
Asenkron tetiklemede aynı olay birden çok kez işlenebilir. Fonksiyon idempotent değilse mükerrer kayıt ya da çift işlem oluşur; tekrar güvenliği baştan tasarlanmalıdır.
Tetikleyiciler ve yönetilen servisler sağlayıcıya özgüdür; taşınma maliyetlidir. İş mantığını sağlayıcı API'lerinden ayırmak ve açık standartları tercih etmek bağımlılığı azaltır.
Düşük trafikte ucuz olan model, yüksek ve sabit yükte ya da kontrolsüz tekrar döngülerinde hızla pahalılaşır. Concurrency sınırı ve bütçe alarmı koymak şarttır.
Serverless sunucuyu sizin yönetmediğiniz geniş bir modeldir; veritabanı, depolama ve auth gibi yönetilen servisleri de kapsar. FaaS bunun yalnızca kendi kodunuzu fonksiyon olarak çalıştıran alt kümesidir. Her FaaS serverless'tır ama her serverless servis FaaS değildir.
Cold start, ortamın sıfırdan kurulması gereken ilk çağrının ek gecikmesidir. Warm start ise hazır bekleyen bir ortamın yeniden kullanılmasıdır ve neredeyse anlıktır. Cold start, scale-to-zero'nun kaçınılmaz takasıdır.
Container, çalışan bir süreci paketler ve siz onu (genelde) sürekli ayakta tutarsınız. Serverless fonksiyon ise yalnızca tetiklenince yaşar ve boşta sıfıra iner. İkisi zıt değildir: serverless container (ör. Knative) ikisini birleştirir. Konteyner & Kubernetes başlığı diğer tarafı anlatır.
Serverless fonksiyon stateless olmalıdır: hiçbir kalıcı durumu kendi belleğinde varsaymaz. Durum (state) varsa dışarıda — veritabanı, cache ya da nesne deposunda — tutulur. Stateful işler, kalıcı bağlantı ya da bellek isteyen yükler bu modele zorlanır.
Concurrency aynı anda işlenen çağrı sayısıdır; her biri ayrı bir örnekte koşar. Throughput ise birim zamanda tamamlanan toplam iş hacmidir. Concurrency sınırını yükseltmek throughput'u artırır ama aşağı akıştaki veritabanını da o oranda zorlar.
CNCF'in sağlayıcıdan bağımsız serverless tanımı, başlıca FaaS platformlarının resmi dokümantasyonu ve serverless mimariyi kavramsal olarak çerçeveleyen kaynaklar.
Hangi işin fonksiyona, hangisinin sürekli açık bir servise uygun olduğunu seçmek, maliyet ve performansı baştan belirler. İş yükünüzü birlikte inceleyip doğru sınırı çizelim.