---
title: 'Sunucu Durumu Yönetimi'
source: 'https://academia.sh/tr/kurslar/frontend-mimarisi/sunucu-durumu-yonetimi'
course: 'Uygulama Mimarisi: Yönlendirme, Durum ve Veri'
language: tr
updated: '2026-08-17T18:09:21+00:00'
license: 'CC BY-SA 4.0'
---

# Sunucu Durumu Yönetimi

Uzak verinin istemcideki kopyası; önbellek anahtarı, tazelik penceresi, uçuşta birleşme, bayat sunup arkada yenileme, yazma sonrası geçersizleştirme, saklama süresi ve yeniden getirme tetikleyicileri.

Merkezî depo ve atom çizgesi aynı varsayımı paylaşıyor: durumun sahibi uygulamadır, yazılan
değer doğrudur. Kuzey Yamaç Ölçüm İstasyonu uygulamasının en büyük durum kütlesi bu
varsayımı karşılamıyor. İstasyon listesi ve ölçüm kayıtları uzaktaki bir kaynağın
kopyası; başka bir kullanıcı yeni istasyon eklemiş, biri bir ölçümü düzeltmiş olabilir.

Durum Türleri dersinde bu türün dört ayrı soru doğurduğu söylenmişti: kopya ne kadar süre
güncel sayılır, eskiyince ne zaman yenilenir, aynı veriyi iki bileşen isterse kaç istek
yapılır, yerel değişiklik yazılırken ekranda ne görünür. İlk üçü bu dersin, dördüncüsü bir
sonrakinin konusudur.

## Anahtar

Sunucu durumu katmanının birinci kararı, bir kopyanın neyle anılacağıdır. **Önbellek
anahtarı**, isteği tümüyle belirleyen değerlerden üretilir: kaynağın yolu ve isteği
farklılaştıran her parametre.

Anahtarın eksik olması iki kopyayı birbirine karıştırır: süzgeci hesaba katmayan bir
anahtar, sıcaklık ölçümleriyle nem ölçümlerini aynı girdide tutar. Anahtarın gereğinden
geniş olması ise paylaşımı engeller; isteği etkilemeyen bir değer anahtara girerse her
görünüm kendi kopyasını indirir.

Rota Parametreleri ve Sorgu dersindeki kanonik biçim burada karşılığını bulur. Aynı görünüm
tek bir adresle anıldığı için, adresten türetilen anahtar da tektir; parametre sırası
değiştiğinde ikinci bir önbellek girdisi oluşmaz.

## Tazelik ve Saklama

İkinci karar, kopyanın ne kadar süre sorgusuz kullanılacağıdır. İki ayrı süre gerekir ve
karıştırılmaları sık görülen bir kusurdur.

**Tazelik penceresi**, kopyanın yeniden istenmeden kullanılabileceği süredir. Pencere
içindeki bir okuma ağa hiç çıkmaz. **Saklama süresi** ise kopyanın bellekte tutulacağı
süredir; bu süre dolduğunda kayıt düşürülür.

İkisinin arasında kalan aralıkta kopya **bayattır**: kullanıcıya hemen gösterilir, aynı anda
arka planda yenilenir. Ekran boş kalmaz, veri de eskimiş kalmaz.

```js
// sunucu-durumu.mjs — tazelik penceresi, ucusta birlesme, gecersizlestirme, saklama suresi
const TAZELIK = 30;      // saniye: bu sure icinde kopya taze sayilir
const SAKLAMA = 120;     // saniye: bu sureden sonra kayit dusurulur

const onbellek = new Map();   // anahtar -> { veri, alindi, gecersiz }
const ucusta = new Map();     // anahtar -> istek numarasi
let istekNo = 0;

function iste(anahtar, saat) {                 // saat: disaridan verilen sanal zaman
  const kayit = onbellek.get(anahtar);
  const yas = kayit ? saat - kayit.alindi : null;
  if (kayit && yas > SAKLAMA) { onbellek.delete(anahtar); }
  const gecerliKayit = onbellek.get(anahtar);

  if (gecerliKayit && !gecerliKayit.gecersiz && saat - gecerliKayit.alindi <= TAZELIK)
    return { sonuc: "onbellek isabeti", yas: saat - gecerliKayit.alindi, istek: "-" };

  if (ucusta.has(anahtar))
    return { sonuc: "ucusta birlestirildi", yas, istek: `#${ucusta.get(anahtar)}` };

  ucusta.set(anahtar, ++istekNo);
  const sonuc = gecerliKayit
    ? "bayat sunuldu + yenileniyor"
    : (kayit ? "kayit dusuruldu, bekleme" : "veri yok, bekleme");
  return { sonuc, yas, istek: `#${istekNo}` };
}

function tamamla(anahtar, saat, veri) {
  onbellek.set(anahtar, { veri, alindi: saat, gecersiz: false });
  const n = ucusta.get(anahtar);
  ucusta.delete(anahtar);
  return { sonuc: "yanit yazildi", yas: 0, istek: `#${n}` };
}

function gecersizlestir(onEk) {                // yazma isleminden sonra cagrilir
  let sayi = 0;
  for (const [anahtar, kayit] of onbellek)
    if (anahtar.startsWith(onEk)) { kayit.gecersiz = true; sayi += 1; }
  return { sonuc: `${sayi} kayit gecersizlestirildi`, yas: null, istek: "-" };
}

const LISTE = ["kuzey-yamac", "dogu-sirt"];
const ADIMLAR = [
  [0, "Liste acildi", "istasyon/liste", (t, a) => iste(a, t)],
  [1, "OzetKarti ayni veriyi istedi", "istasyon/liste", (t, a) => iste(a, t)],
  [3, "yanit geldi", "istasyon/liste", (t, a) => tamamla(a, t, LISTE)],
  [5, "sekmeye geri donuldu", "istasyon/liste", (t, a) => iste(a, t)],
  [40, "sekmeye geri donuldu", "istasyon/liste", (t, a) => iste(a, t)],
  [42, "yanit geldi", "istasyon/liste", (t, a) => tamamla(a, t, LISTE)],
  [45, "istasyon ayrintisi acildi", "istasyon/kuzey-yamac", (t, a) => iste(a, t)],
  [47, "yanit geldi", "istasyon/kuzey-yamac", (t, a) => tamamla(a, t, { ad: "Kuzey Yamac" })],
  [50, "yeni istasyon kaydedildi", "istasyon/ (on ek)", (t) => gecersizlestir("istasyon/", t)],
  [51, "listeye donuldu", "istasyon/liste", (t, a) => iste(a, t)],
  [53, "yanit geldi", "istasyon/liste", (t, a) => tamamla(a, t, [...LISTE, "bati-vadi"])],
  [200, "ayrintiya geri donuldu", "istasyon/kuzey-yamac", (t, a) => iste(a, t)],
];

console.log("t".padStart(4), "olay".padEnd(30), "anahtar".padEnd(22), "sonuc".padEnd(28), "yas", "istek");
for (const [t, olay, anahtar, calistir] of ADIMLAR) {
  const r = calistir(t, anahtar);
  console.log(String(t).padStart(4), olay.padEnd(30), anahtar.padEnd(22),
    r.sonuc.padEnd(28), String(r.yas ?? "-").padStart(3), r.istek);
}

console.log("-- toplam ag istegi --", istekNo);
```

```
   t olay                           anahtar                sonuc                        yas istek
   0 Liste acildi                   istasyon/liste         veri yok, bekleme              - #1
   1 OzetKarti ayni veriyi istedi   istasyon/liste         ucusta birlestirildi           - #1
   3 yanit geldi                    istasyon/liste         yanit yazildi                  0 #1
   5 sekmeye geri donuldu           istasyon/liste         onbellek isabeti               2 -
  40 sekmeye geri donuldu           istasyon/liste         bayat sunuldu + yenileniyor   37 #2
  42 yanit geldi                    istasyon/liste         yanit yazildi                  0 #2
  45 istasyon ayrintisi acildi      istasyon/kuzey-yamac   veri yok, bekleme              - #3
  47 yanit geldi                    istasyon/kuzey-yamac   yanit yazildi                  0 #3
  50 yeni istasyon kaydedildi       istasyon/ (on ek)      2 kayit gecersizlestirildi     - -
  51 listeye donuldu                istasyon/liste         bayat sunuldu + yenileniyor    9 #4
  53 yanit geldi                    istasyon/liste         yanit yazildi                  0 #4
 200 ayrintiya geri donuldu         istasyon/kuzey-yamac   kayit dusuruldu, bekleme     153 #5
-- toplam ag istegi -- 5
```

Zaman dışarıdan verildiği için çıktı belirlenimcidir; aynı betik her çalıştırmada aynı
satırları üretir. Gerçek uygulamada bu değerin kaynağı sistem saatidir, ama katmanın kendisi
saati bir bağımlılık olarak alırsa sınanabilir kalır.

## Uçuşta Birleşme

İkinci satır, katmanın en görünmez kazancını gösterir. Liste ile özet kartı aynı veriyi bir
saniye arayla ister; ağa yalnız bir istek çıkar.

Bu davranış olmadan aynı ekrandaki her bileşen kendi isteğini yapar. Ağ Panelinde Tanı
dersinde tanımlanan şelale görünümünde bu, aynı adrese giden yan yana isteklerle görünür.
Çözüm bileşenleri değiştirmek — veriyi yukarı taşımak, tek bir yerden dağıtmak — değil, aynı
anahtara giden istekleri katmanda birleştirmektir. Bileşenler birbirinden habersiz kalır ve
yine tek istek yapılır.

Birleşmenin işleyebilmesi için anahtarın **dizgi eşitliğiyle** karşılaştırılabilir olması
gerekir. Anahtar üretimi kanonik değilse, aynı isteği tanımlayan iki anahtar farklı görünür
ve birleşme kaçırılır.

## Geçersizleştirme

Ellinci saniyedeki adım, tazelik penceresinin çözemediği durumu gösterir. Kullanıcı yeni bir
istasyon kaydetmiştir; listenin kopyası artık yanlıştır, ama yaşı henüz dokuz saniyedir.
Süre bu bilgiyi veremez.

Verebilecek olan yazma işleminin kendisidir. Bir yazma başarıyla tamamlandığında, ondan
etkilenen anahtarlar **geçersizleştirilir**: yaşları ne olursa olsun bayat sayılırlar.
Çıktıda geçersizleştirme ön ekle yapılmış ve iki kaydı birden etkilemiştir.

Etkilenen anahtarların belirlenmesi bir tasarım kararıdır. Dar bir geçersizleştirme —
yalnız değişen kaydın anahtarı — hızlıdır ama listeyi eski bırakır. Geniş bir
geçersizleştirme — tüm ön ek — güvenlidir ama gereksiz istek üretir. Ölçüt, yazmanın hangi
görünümleri gerçekten etkilediğidir; yeni bir istasyon listeyi de özetleri de değiştirir.

Geçersizleştirmenin bir kardeşi vardır: yanıtın **doğrudan yazılması**. Sunucu, yazma
isteğine güncel kaydı geri döndürüyorsa, o kayıt önbelleğe konur ve ek bir istek hiç
yapılmaz. Bu, sözleşmenin sunucu tarafını da ilgilendirir ve Veri Erişimi konusunda ele
alınır.

## Saklama Süresi

Son satır iki yüzüncü saniyede yaşanır. İstasyon ayrıntısının kopyası saklama süresini
aştığı için düşürülmüştür; kullanıcı geri döndüğünde bayat veri bile gösterilemez ve
bekleme görünür.

Saklama süresinin varlık nedeni bellektir. Kullanıcının bir kez açıp bir daha dönmediği
her kayıt bellekte kalırsa, uzun süre açık duran bir sekme büyümeye devam eder.
Eşzamansız JavaScript ve Çalışma Zamanı kursundaki bellek sızıntısı tanısında görülen
tabloyu üreten nedenlerden biri budur.

İki süre birlikte ayarlanır. Tazelik penceresi verinin ne sıklıkta değiştiğine göre
seçilir: nadiren değişen bir istasyon künyesi uzun, sürekli akan bir ölçüm listesi kısa
pencere ister. Saklama süresi ise kullanıcının o görünüme dönme olasılığına göre seçilir.

## Yeniden Getirme Tetikleyicileri

Bayat bir kaydın ne zaman yenileneceği yalnız okumaya bağlı değildir. Katman birkaç dış
işareti de dinler.

Sekmeye geri dönülmesi bunların en etkilisidir: kullanıcı başka bir uygulamada dakikalarca
kalıp geri döndüğünde ekrandaki her şey eskimiştir. Ağ bağlantısının yeniden kurulması
ikinci işarettir. Belirli aralıklarla yenileme ise yalnız gerçekten değişen veriler için
kullanılır ve sekme görünmediğinde durdurulur.

Her tetikleyici bir maliyet üretir. Ölçüt, kullanıcının eski veri görmesinin maliyetiyle
ek isteğin maliyetini karşılaştırmaktır; ölçüm listesinde eskilik pahalıdır, istasyon
künyesinde değildir.

## Özet

- Sunucu durumu kendi katmanında tutulur ve her kopya, isteği tümüyle belirleyen kanonik
  bir anahtarla anılır.
- Tazelik penceresi kopyanın sorgusuz kullanılacağı süredir; saklama süresi bellekte
  kalacağı süredir. Arada kalan kopya bayattır: gösterilir ve arkada yenilenir.
- Aynı anahtara giden eşzamanlı istekler uçuşta birleştirilir; bileşenler birbirinden
  habersizken bile tek istek yapılır.
- Süre tabanlı tazelik, yerel bir yazmanın kopyayı yanlışladığını bilemez; yazma sonrası
  geçersizleştirme etkilenen anahtarları yaşlarına bakmadan bayatlatır.
- Saklama süresi dolan kayıt düşürülür ve dönüşte bayat veri bile gösterilemez; bu süre
  belleği sınırlar.
- Yeniden getirme okuma dışında sekmeye dönüş, bağlantının kurulması ve aralıklı yenileme
  ile de tetiklenir; her tetikleyici eskilik maliyetiyle istek maliyeti karşılaştırılarak
  seçilir.

## Sonraki Adım

Bu katman okumayı çözdü. Yazma tarafında ise ekranda görünen şey hâlâ ağın hızına bağlı:
kullanıcı bir ölçümü siler, düğme beklemeye geçer, satır ancak sunucu yanıt verince
kaybolur. Oysa isteğin başarılı olacağı çoğu durumda bellidir ve sonuç zaten önceden
bilinmektedir. Sonraki ders değişikliği yanıtı beklemeden ekrana yansıtmayı, başarısızlıkta
önceki hâle dönmeyi ve bu dönüşün arada gelen başka değişikliklerle nasıl çakışabileceğini
ele alır.
