Oturum kalıcılığı (session persistence), diğer adıyla sticky session (yapışkan oturum), proxy'lerin kullandığı bir yük dengeleme tekniğidir; belirli bir istemciden gelen tüm isteklerin, oturum süresi boyunca tutarlı biçimde aynı arka uç sunucusuna yönlendirilmesini sağlar.
Bu mekanizma, yük dengelemeli bir ortamda durum tutan (stateful) uygulamaların yarattığı sorunu çözer. Birçok web uygulaması, oturuma özgü verileri (örneğin alışveriş sepeti içeriği, kullanıcının kimlik doğrulama durumu, kişiselleştirilmiş ayarlar) sunucuda saklar. Oturum kalıcılığı olmadan, istemcinin sonraki isteği yük dengeleyici tarafından farklı bir arka uç sunucusuna yönlendirilebilir. O sunucuda istemcinin oturum verisi yoksa oturum durumu kaybolur; bu da hatalara, yeniden kimlik doğrulama zorunluluğuna veya istemcinin işleme baştan başlamasına yol açar. Sticky session'lar, ilk bağlantı kurulduktan sonra istemciyi belirli bir sunucuya "yapıştırarak" bunu önler.
Oturum kalıcılığı nasıl çalışır
Proxy'ler oturum kalıcılığını çeşitli yöntemlerle uygular; temelde önce istemciyi tanımlar, ardından bu istemciyi belirli bir arka uç sunucusuyla eşleştirir.
İstemci tanımlama yöntemleri
IP Hash (kaynak IP hash'leme)
Bu yöntem, arka uç sunucusunu belirlemek için istemcinin IP adresini anahtar olarak kullanır. Proxy, istemcinin IP adresinin hash'ini alır ve elde edilen değerle mevcut havuzdan bir sunucu seçer. Böylece aynı IP adresinden gelen tüm istekler aynı sunucuya yönlendirilir.
- Mekanizma:
hash(client_ip) % number_of_servers - Artıları: uygulaması basittir; istemci tarafında çerez ya da uygulamada değişiklik gerektirmez.
- Eksileri:
- Yük dengesizliği: birçok istemci aynı genel IP'yi paylaşıyorsa (örneğin bir NAT ağ geçidinin veya kurumsal ağın arkasında), tek bir sunucu aşırı yüklenebilir.
- Sunucu arızası: atanan sunucu arızalanırsa istemcinin oturumu kaybolur ve sonraki istekler yeni bir sunucuya yönlendirilir (hash hesabı farklı bir sunucuyu işaret ederse ya da proxy dağılımı yeniden değerlendirirse yapışkanlık kaybolabilir).
- Dinamik IP'ler: dinamik IP adresine sahip istemciler, oturum ortasında IP'leri değişirse oturumlarını kaybedebilir.
Çerez tabanlı kalıcılık
Bu, yaygın kullanılan ve daha esnek bir yöntemdir. Proxy ya da uygulama, istemcinin tarayıcısına bir çerez yerleştirir. Bu çerez, proxy'nin sonraki istekleri doğru arka uç sunucusuna yönlendirmek için kullandığı bilgiyi içerir.
Proxy tarafından üretilen çerezler
Proxy'nin kendisi, yanıtı istemciye göndermeden önce HTTP yanıtına bir çerez enjekte eder. Bu çerez genellikle ilk isteği işleyen arka uç sunucusunun tanımlayıcısını taşır. Sonraki isteklerde proxy bu çerezi okur ve istemciyi belirtilen sunucuya yönlendirir.
- Mekanizma: proxy yanıtı yakalar ve
Set-Cookie: PROXY_SESSION_ID=server_idbaşlığını ekler. Sonraki isteklerde proxyCookie: PROXY_SESSION_ID=server_iddeğerini okur ve isteğiserver_idsunucusuna iletir. - Artıları: uygulamada değişiklik gerektirmez, uygulama açısından şeffaftır.
- Eksileri:
- Sunucu arızası: belirtilen sunucu arızalanırsa istemcinin oturumu kaybolur. Proxy'nin isteği yeni bir sunucuya yönlendirip çerezi güncellemesi gerekir; aksi hâlde istemci hata alır.
- Çerez yönetimi: istemci tarayıcılarının çerezleri kabul edip göndermesini gerektirir.
Uygulama tarafından üretilen çerezler
Arka uç uygulamasının kendisi bir oturum çerezi oluşturur ve yönetir (örneğin Java uygulamalarında JSESSIONID, PHP'de PHPSESSID). Proxy, bu uygulamaya özgü çerezi incelemek ve değerini (ya da bir kısmını) kullanarak hedef arka uç sunucusunu belirlemek üzere yapılandırılır. Proxy, çerez değerinin hash'ini alabilir veya içine gömülü sunucu tanımlayıcısını çıkarabilir.
- Mekanizma: uygulama
Set-Cookie: APP_SESSION_ID=unique_session_idbaşlığını ayarlar. ProxyCookie: APP_SESSION_ID=unique_session_iddeğerini okur ve bu değeri bir sunucuyla eşleştirir. - Artıları: uygulamanın mevcut oturum yönetiminden yararlanır; benzersiz oturumları tanımlamada potansiyel olarak daha sağlamdır.
- Eksileri: proxy'nin uygulamaya özgü çerez biçimlerini anlaması için yapılandırma gerektirir. Sunucu arızası oturum kaybına yol açar.
Başlık tabanlı kalıcılık
IP hash veya çerez tabanlı yöntemlere göre daha az yaygın olan bu yaklaşım, oturum ya da sunucu tanımlama bilgisini taşımak için özel bir HTTP başlığı kullanır. Bu başlığı istemci ya da aradaki bir proxy ekleyebilir.
- Mekanizma: proxy
X-Server-ID: server_123veyaX-Client-Session: abcdefbaşlığını okur ve buna göre yönlendirir. - Artıları: belirli API gateway veya mikroservis mimarilerinde faydalı olabilir.
- Eksileri: başlıkların eklenmesi için istemcinin ya da yukarı akış proxy'sinin iş birliği gerekir. İstemci tarafında script olmadan standart web tarayıcıları için uygun değildir.
Sticky session yöntemlerinin karşılaştırması
| Özellik | IP Hash | Proxy tarafından üretilen çerez | Uygulama tarafından üretilen çerez |
|---|---|---|---|
| İstemci kimliği kaynağı | İstemcinin IP adresi | Proxy'nin eklediği çerez | Uygulamanın ürettiği çerez |
| Uygulama değişikliği | Yok | Yok | Yok (proxy mevcut uygulama çerezini okur) |
| Yük dağılımı | Dengesiz olabilir (NAT/proxy'ler) | Genelde iyi | Genelde iyi |
| Sunucu arızası | Oturum kaybolur, yeni sunucuya yönlendirilir | Oturum kaybolur, yeni sunucuya yönlendirilir | Oturum kaybolur, yeni sunucuya yönlendirilir |
| Kalıcılık granülerliği | IP adresi başına | Tarayıcı oturumu başına (çerez süresi) | Uygulama oturumu başına (çerez süresi) |
| İstemci gereksinimi | Yok | Çerez desteği | Çerez desteği |
| Karmaşıklık | Düşük | Orta (çerez yönetimi proxy'de) | Orta (uygulama çerezini okumak için proxy yapılandırması) |
Oturum kalıcılığı neden önemli
- Durum tutan uygulamalara destek: oturum verisini sunucuda yerel olarak saklayan uygulamalar için şarttır (örneğin e-ticaret sepetleri, oturum açma, çok adımlı formlar).
- Kullanıcı deneyimi: oturum kaybını, yeniden giriş yapmayı veya ilerlemenin kaybolmasını önler; daha akıcı bir deneyim sağlar.
- Uygulama tasarımında basitlik: karmaşık dağıtık oturum yönetimi çözümlerine (örneğin Redis veya Memcached gibi harici oturum depolarına) olan ihtiyacı azaltır ve uygulamaların daha yalın kalmasına imkân verir.
Dezavantajlar ve dikkat edilmesi gerekenler
- Yük dengesizliği: başlıca dezavantaj. Bir sunucu orantısız biçimde çok sayıda "yapışkan" istemciyi karşılıyorsa aşırı yüklenebilirken diğer sunucular atıl kalabilir. Bu, yük dengelemenin faydasını ortadan kaldırabilir.
- Sunucu arızasının etkisi: aktif sticky session'lara sahip bir sunucu arızalanırsa, o sunucuya "yapışmış" tüm istemciler oturum verilerini kaybeder. Bu, söz konusu istemciler için deneyimin bozulmasına veya hizmet kesintisine yol açabilir.
- Ölçeklenebilirlik zorlukları: yatay ölçeklemeyi zorlaştırabilir. Arka uç sunucusu eklemek ya da çıkarmak mevcut sticky session'ları bozabilir; ölçekleme işlemleri sırasında dikkatli yönetim gerekir.
- Kaynak tüketimi: yapışkanlık eşleşmesini (örneğin bir arama tablosunda) tutmak proxy üzerinde kaynak tüketir.
- Çerez yönetimi yükü: çerez tabanlı yöntemlerde, her istekte çerez ayarlamanın ve okumanın küçük bir ek yükü vardır.
Yapılandırma örnekleri
Nginx (açık kaynak)
Nginx, sticky session'ları ip_hash yönergesiyle ya da ticari modüller veya nginx-sticky-module-ng gibi üçüncü taraf modüllerle sağlanan daha gelişmiş çerez tabanlı yöntemlerle uygulayabilir.
IP Hash
http {
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
Bu örnekte ip_hash;, aynı istemci IP adresinden gelen isteklerin backend upstream grubundaki aynı sunucuya tutarlı biçimde yönlendirilmesini sağlar.
Çerez tabanlı (sticky modülüyle — genellikle Nginx Plus veya üçüncü taraf)
Nginx Plus ya da uyumlu bir üçüncü taraf modül kullanıyorsanız:
http {
upstream backend {
# "route" adlı, proxy tarafından üretilen bir çerez kullanılıyor
# Değer, Nginx'in sunucuya atadığı rota kimliğidir.
sticky route $cookie_route;
server backend1.example.com route=A;
server backend2.example.com route=B;
server backend3.example.com route=C;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
Burada sticky route $cookie_route;, Nginx'i oturum kalıcılığı için route adlı bir çerez kullanacak şekilde yapılandırır. Nginx bu çereze, başlangıçta seçilen arka uç sunucusuna karşılık gelen bir değer (A, B veya C) atar.
Alternatif olarak, uygulamanın ürettiği çerezleri öğrenmek için sticky learn kullanılabilir:
http {
upstream backend {
# Uygulamanın JSESSIONID çerezinden öğrenir
sticky learn
create=$upstream_cookie_JSESSIONID
lookup=$cookie_JSESSIONID
zone=client_sessions:1m; # Oturum verileri için paylaşımlı bellek bölgesi
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
Bu yapılandırma, arka uç uygulamasının ayarladığı JSESSIONID çerezini öğrenmeye çalışır. Çerez mevcutsa Nginx, sonraki istekleri onu ilk ayarlayan sunucuya yönlendirmek için bu değeri kullanır.
HAProxy
HAProxy güçlü sticky session yetenekleri sunar ve hem IP tabanlı hem de çerez tabanlı yöntemleri destekler.
IP Hash (kaynak IP hash'leme)
frontend http_front
bind *:80
default_backend http_back
backend http_back
balance source # İstemcinin IP adresini kullanır
server backend1 192.168.1.10:80 check
server backend2 192.168.1.11:80 check
server backend3 192.168.1.12:80 check
balance source yönergesi, HAProxy'ye yük dengelemede istemcinin kaynak IP adresini kullanmasını söyler ve fiilen sticky session sağlar.
Proxy tarafından üretilen çerez
frontend http_front
bind *:80
default_backend http_back
backend http_back
balance roundrobin
cookie SERVERID insert indirect nocache # SERVERID adlı bir çerez ekler
server backend1 192.168.1.10:80 cookie S1 check
server backend2 192.168.1.11:80 cookie S2 check
server backend3 192.168.1.12:80 cookie S3 check
Burada cookie SERVERID insert indirect nocache, HAProxy'ye istemciye giden yanıta SERVERID adlı bir çerez eklemesini söyler. Her sunucu satırındaki cookie S1, cookie S2 vb. değerler, HAProxy'nin o sunucu için kullanacağı değeri belirtir. HAProxy sonraki istekleri yönlendirmek için bu çerezi kullanır. indirect, çerezin yalnızca istemcide zaten yoksa ayarlanacağı anlamına gelir; nocache ise önbellekleyen proxy'lerin Set-Cookie başlıklı yanıtları önbelleğe almasını engeller.
Uygulama tarafından üretilen çerez
frontend http_front
bind *:80
default_backend http_back
backend http_back
balance roundrobin
appsession JSESSIONID len 52 timeout 3h # JSESSIONID çerezini kullanır
server backend1 192.168.1.10:80 check
server backend2 192.168.1.11:80 check
server backend3 192.168.1.12:80 check
appsession JSESSIONID len 52 timeout 3h yönergesi, HAProxy'yi JSESSIONID adlı bir çerezi aramak üzere yapılandırır (Java uygulamalarında yaygındır). len 52, dikkate alınacak oturum kimliğinin uzunluğunu belirtir; timeout 3h ise çerez bir istekte yoksa HAProxy'nin oturum–sunucu eşleşmesini ne kadar süre hatırlayacağını ayarlar. Bu yöntem, JSESSIONID çerezinin uygulama tarafından ayarlanmasını gerektirir.
