Oturum Yönetimi ve Stateless Ölçekleme
Önce şunu oku: Spring Security Filter Chain
30 saniyede özet
Kullanıcının oturumunu sunucunun belleğinde tutarsan, o sunucu kapanınca kullanıcı da düşer. Sticky session bunu sadece erteler. JWT kimseyi düşürmez ama 'çıkış yap' demeyi zorlaştırır.
Bir alışveriş merkezinde emanet dolabına çantanı bıraktın. Ertesi gün o bina tadilat için kapandı.
Adım adım oku
- Kullanıcının oturumu pod A'nın belleğinde, onun emanet dolabında duruyor.
- Sticky session, yük dengeleyicinin bu kullanıcıyı hep A'ya göndermesidir.
- Yeni sürüm çıkınca A yeniden başlar ve belleği boşalır: oturum gider, kullanıcı çıkış yapmış olur.
- Oturum Redis gibi ortak bir depoya taşınınca her pod aynı dolabı açabilir; A yeniden başlasa da oturum yerindedir.
-
Bayt: Uygulamayı iki kopyaya çıkardım, kullanıcılar rastgele çıkış yapmaya başladı.
-
Sen: Yük dengeleyicide sticky session açsan?
-
Bayt: Açtım, düzeldi! Sonra yeni sürüm çıktım ve herkes yine çıkış yaptı.
-
Bayt: Emanet dolabı hep aynı şubedeyse, şube kapanınca eşya da gider.
Uygulamayı iki pod’a çıkardın ve kullanıcılar rastgele düşmeye başladı. Yük dengeleyiciye sticky sessionBir kullanıcının isteklerini hep aynı sunucuya yönlendirmek. Sorunu çözmez, erteler: o sunucu ölünce veya deploy olunca oturum kaybolur.Sözlükte gör → açtın, sorun bitti. Sonra bir sürüm çıktın.
Oturum nerede duruyor?
Uygulama iki pod'a çıktı, oturumlar her pod'un belleğinde. Kullanıcı A pod'unda giriş yaptı, sonraki istek B pod'una gitti. Ne olur? Cevabı göster
Oturum bulunamaz; B pod’u onu hiç görmedi, kullanıcı yeniden giriş yapar.
HTTP durumsuzdur. “Oturum” dediğimiz şey, bir çerezle (JSESSIONID) anahtarlanan sunucu tarafı durumdur.
Birden fazla pod olunca tek soru kalır: isteği alan pod oturumu bulabilir mi?
Kafam karıştı, daha basit anlat
Oturum, vestiyerdeki paltoya benzer: fiş sende, palto bir sunucuda. Birden çok vestiyer varsa, fişini gösterdiğin vestiyerde paltonun olması gerekir.
Bir servisin "stateless" olması tam olarak ne demek?
Kendin gör
Oturum nerede duruyor — sticky session neden deploy’u atlatamaz
Tohum 11Sticky session (oturum yapışkanlığı) · 3 pod
- pod 0
- pod 1
- pod 2
Yeniden giriş
0
kullanıcı kaç kez düştü
Sorunsuz istek
0/ 5
Rolling deploy — tüm podlar yenilendi
Çıkış gerçek mi
—
anında iptal
Şu an ne oldu?
3 pod, Sticky session (oturum yapışkanlığı)
HTTP durumsuzdur; oturum, bir çerezle anahtarlanan sunucu tarafı durumdur. Asıl soru o durumun nerede tutulduğu.
Aklında kalsın: Ölçekleme sorularında ilk bakılacak şey uygulamanın hangi durumu kendi belleğinde tuttuğudur.
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
Varsayılan kurulum sticky + rolling deploy — yani dersin ana senaryosu. Şunları karşılaştır:
Sticky+Hiçbir şey. Sıfır yeniden giriş.Sticky+Trafik arttı, pod eklendi. Yine sıfır.Sticky+Rolling deploy. Kullanıcı düştü: yapışkanlık pod’un ömrünü uzatmaz.Pod belleğinde, olayHiçbir şey. Hiçbir şey olmadan bozuk.Redis. Her senaryoda sıfır.JWT. Yine sıfır, ama çıkış gerçek değil.
Kafam karıştı, daha basit anlat
Sunucu yeniden başlarken vestiyer boşalır. Fiş hâlâ elinde olsa bile palto artık yoktur.
İki pod'lu bir serviste bu controller'a arka arkaya üç istek gidiyor. Sayaç ne gösterir?
Dört yol
| Strateji | Pod eklenince | Pod ölünce | Deploy’da | Anında çıkış |
|---|---|---|---|---|
| Pod belleğinde | ❌ bozuk | ❌ | ❌ | ✅ |
| Sticky session | ✅ | ❌ | ❌ | ✅ |
| Redis session | ✅ | ✅ | ✅ | ✅ |
| JWT | ✅ | ✅ | ✅ | ❌ |
Tabloda okunması gereken şey, sticky satırının yarısının çalışıyor olması. Bu onu tehlikeli yapan şeydir: test ortamında sorun görünmez.
Sticky session neden yeterli değil. Yapışkanlık, yük dengeleyiciye “bu çerezi taşıyan istekleri hep aynı pod’a yolla” der. Pod ayaktayken kusursuz çalışır.
Ama pod ortadan kalktığında yapacak bir şeyi yoktur. Ve pod’lar ortadan kalkar:
- Rolling deploy — tanımı gereği her pod’u yenisiyle değiştirir
- Otomatik ölçek daraltma — trafik düşünce pod silinir
- Node bakımı, OOM, liveness probe hatası — Kubernetes’in normal işleyişi
Günde iki kez deploy eden bir ekipte sticky session, günde iki kez tüm kullanıcıları düşürmek demektir.
Ayrıca yükü de bozar: yapışkanlık nedeniyle bir pod’a birikmiş oturumlar, yeni pod’lar boşta dururken o pod’u zorlar.
Aşağıdaki örnek bir bankanın internet şubesinden: oturum Redis’te, iki adımlı transferin taslağı küçük ve serileştirilebilir, kredi belgesi nesne depolamada, sticky session gerekmiyor.
Derinleş · İnternet şubesi: pod'a bağlı hiçbir şey 6 dosya · ~112 satır · ilk okumada atlayabilirsin
Sticky session ne yapar ve asıl bedeli nedir?
Sticky session açık, 4 pod var ve her şey sorunsuz çalışıyor. Ekip rolling deploy yapıyor. Ne olur?
Durumu dışarı almak
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId></dependency>spring.session.store-type=redisspring.session.timeout=30mSpring Session, HttpSession’ı bir filtre ile değiştirir. Uygulama kodu değişmez — session.setAttribute(...) aynı kalır, arkada Redis’e yazılır.
Kazanç yalnızca “oturum kaybolmuyor” değil. Pod’lar gerçekten değiştirilebilir hâle gelir: ölebilir, eklenebilir, yenilenebilir. Deploy ve ölçekleme sıradan işlemlere dönüşür.
Bedeli: Redis artık kritik bir bileşendir. Düşerse tüm kullanıcılar düşer — yani yüksek erişilebilirlik ve yedekleme gerektirir.
JWT — ve neden bedava değil. JWT ile sunucuda hiçbir şey tutulmaz. Token imzalıdır; her pod onu tek başına doğrular, hiçbir yere bakmaz.
Simülatörde JWT her senaryoda sıfır yeniden giriş verir. Ama son iki adımı oku: çıkış yapan kullanıcının token’ı hâlâ kabul edildi.
Sebep basit: iptal edebilmek için bir yerde kayıt tutmak gerekir, ve kayıt tutmak zaten sunucu durumudur. Bu, JWT’nin bir hatası değil, doğrudan sonucudur:
Sunucu durumunu kaldırmak, o durumu iptal edebilme yeteneğini de kaldırır.
Sonuçları:
- Çıkış anlık değildir. Token süresi dolana kadar geçerli.
- Yetki değişikliği gecikir. Eski rol token’da kalır.
- Token büyür. Her bilgi her istekte taşınır.
Yaygın çözüm: kısa ömürlü access token + sunucuda tutulan, iptal edilebilir refresh token. Yani tam statelessSunucunun istekler arasında istemciye özel durum saklamaması. Sınavı tek soru: rastgele bir pod'u öldürdüğünde kullanıcı bir şey kaybeder mi?Sözlükte gör → değil — “az stateful”.
Kafam karıştı, daha basit anlat
Paltoları ortak bir depoya koyarsan hangi vestiyere gittiğinin önemi kalmaz. Redis bu ortak depodur.
Oturumu Redis'e taşımak servisi gerçekten stateless yapar mı?
Her durumu, pod belleğinde tutulmasının sorun olup olmadığına göre sınıflandır.
Tuzaklar ve seçim
- Tarayıcı tabanlı web uygulaması → Redis session: anında iptal, basit kod.
- Mobil istemci, çok mikroservis → kısa ömürlü JWT + refresh token.
- Pod belleğinde → yalnızca tek örnekte; deploy’da yine düşürür.
- Sticky session → geçici köprü; “şimdilik” diye eklenir, kalıcı olur.
Asıl ilke stratejiden bağımsız: uygulama kendi belleğinde kullanıcıya özel durum tutmamalıdır. Oturum bunun en görünür örneği; dosya yüklemeleri, önbellek ve zamanlanmış görev kilitleri de aynı kurala tabidir.
Kendini sına
HTTP kendi başına durumsuzdur.
Bu durumda ne yaparsınız?
Aklında kalacak üç şey
- 1 Sticky session sunucunun ömrünü uzatmaz. Yeni sunucu eklemeyi atlatır, sunucunun kapanmasını ve yeni sürümü atlatamaz.
- 2 Oturumu sunucunun dışına almanın asıl kazancı: sunucular gerçekten değiştirilebilir olur, yayına alma ve büyüme sıradan işlere dönüşür.
- 3 JWT'nin bedeli: sunucudaki kaydı kaldırmak, o oturumu iptal edebilmeyi de kaldırır. Anında çıkış istiyorsan bir yerde kayıt tutman gerekir.
5 kart sonraki derste seni bekliyor
Bu dersin üstüne kurulanlar
Bunlar bu dersi temel alıyor; hazır olduğunda devam edebilirsin.