İçeriğe geç
academia.sh

Ders 05 / 20

Zaman Aşımı Bütçeleri

Yavaşlayan bir bağımlılıkta bütçenin nasıl tükendiği: kola kalan payın ardışık alt çağrılara açgözlü, eşit ve ağırlıklı bölüştürülmesi, açgözlü dağıtımın sağlam adımı suçlu göstermesi, çağıranın tuttuğu yuva ile bağımlılıkta terk edilen işin ayrı ayrı sayılması ve sıkı bölüştürmenin ancak iptal sinyaliyle birlikte kazanç yazması.

İçindekiler

Yeniden deneme politikası artık kararlaştırılmış durumda: kaç kez denenecek, denemeler arasında ne kadar beklenecek, sarsıntının genişliği ne olacak. Politikanın açıkta bıraktığı tek bir sayı var ve o sayı politikanın kendisinden daha belirleyici — çağıran, vazgeçmeden önce toplam ne kadar bekleyecek. Bu süre konmadıkça geri çekilme bir sınıra doğru değil, boşluğa doğru büyür.

Uygulama Katmanı ve Servis Etkileşimi kursu bu sürenin bir bütçe olduğunu kurdu: uçtan uca eşik zincirin adımlarına bölüştürülür, kalan süre çağrıyla birlikte geçirilir ve deneme sayısı bütçeyi çarpar. O hesap burada girdidir, tekrarlanmaz. Bu dersin sorusu bir basamak sonrasıdır. Zincirdeki bir adım yavaşladığında bütçe nerede tükenir, kalan pay alt çağrılara nasıl bölünür, ve çağıran vazgeçtikten sonra bağımlılığın hâlâ yaptığı iş ne kadardır.

Arıza Kipi

Zincir bu kursun ortak yapısından gelir. Takip sorgusu ağ geçidinden girer ve iki kolu paralel çağırır. Teslimat operasyonu kolu kendi deposundan tek bir kayıt okur; ücretlendirme kolu iki kayıt okur — önce tarife, sonra gönderinin ölçüsü — ve ücreti ikisinden hesaplar. Uygulama Katmanı kursu bir dış istek için dört adım çağrısı saymıştı; ücretlendirme kolunun depo basamağı iki ardışık okumaya ayrıldığında sayı beşe çıkar.

AY10 — tarife deposu yavaşlıyor. Durmuyor, yanlış yanıt vermiyor, ağ bölünmesi yaşamıyor; yalnız yanıt süresi olağan altı milisaniyelik ortancasının onlarca katına çıkıyor. Süre 12 dakika, sıklık ayda bir kez. Gerekçe: yavaşlama bir bakım penceresiyle ya da bir sorgu planı değişikliğiyle başlar ve fark edilip geri alınana kadar sürer; on iki dakika, K01’in on dakikalık kurtarma süresi varsayımının biraz üstündedir. Duyarlılığı aşağıda hesaplanmıştır. Bu varsayım K01’in tablosuna eklenmez.

Yavaşlama, durmadan daha zor bir kiptir. Durmuş bir bağımlılık bağlantıyı hemen reddeder ve çağıran bunu milisaniyenin altında öğrenir. Yavaşlayan bağımlılık hiçbir şeyi reddetmez, yalnız bekletir — ve bekleme, hiçbir sınır konmadıysa çağıranın kaynağıyla ödenir. Bütçe bu beklemenin ne kadarının kabul edileceğine karar veren tek mekanizmadır.

Kalan Payın Bölünmesi

Kola düşen pay bellidir: K01’in 200 milisaniyelik okuma eşiğinden Uygulama Katmanı kursunun U3 varsayımı olan 20 milisaniyelik ağ geçidi payı çıkınca 180 milisaniye kalır. Ücretlendirme kolu bu 180 milisaniyeyi iki ardışık okumaya dağıtmak zorundadır ve üç politika vardır.

Açgözlü dağıtım kalanın tamamını her çağrıya verir: ilk okuma 180 milisaniyeye kadar bekleyebilir, ikincisi geriye ne kalırsa onu alır. Eşit dağıtım payı ikiye böler. Ağırlıklı dağıtım payı olağan sürelerin oranında paylaştırır; tarife 6, ölçü 12 milisaniye olduğuna göre oran bire ikidir.

Üçü de arızasız günde neredeyse aynı görünür, çünkü iki okuma da payının çok altında kalır. Ayrım, bir okuma payını aştığı anda çıkar.

// butce/zincir.mjs — takip sorgusu zincirinin MODELI. Mantiksal saat: adim sureleri bir
// donguden okunur, gercek zaman olculmez; servis, ag ya da depo kurulmaz.
export const K01 = { esik: 200, tepeOkuma: 416.67, tepeUc: 513.89, yanitBayt: 480 };
export const GECIT_PAYI = 20;                 // K03 servis-tasarimi/05, varsayim U3
export const ORTANCA = { teslimat: 8, tarife: 6, olcu: 12 };   // model parametresi (ms)

const D = (govde, kuyruk) => [...govde, ...govde, kuyruk];     // 16'da bir uzun kuyruk
export const REJIM = {                        // alt cagrinin suresi (ms), on altilik dongu
  arizasiz: {
    teslimat: D([8, 9, 8, 10, 8, 9, 8, 10], 40),
    tarife: D([6, 7, 6, 8, 6, 7, 6, 8], 80),
    olcu: D([12, 13, 12, 14, 12, 13, 12, 14], 100),
  },
  "tarife yavas": {                           // AY10: yalniz tarife deposu yavasliyor
    teslimat: D([8, 9, 8, 10, 8, 9, 8, 10], 40),
    tarife: D([150, 400, 220, 400, 180, 300, 260, 400], 400),
    olcu: D([12, 13, 12, 14, 12, 13, 12, 14], 100),
  },
};

// Kola kalan payin iki ardisik alt cagriya bolusturulmesi.
export function paylar(politika, kalan) {
  if (politika === "acgozlu") return [kalan, kalan];
  if (politika === "esit") return [kalan / 2, kalan / 2];
  const t = ORTANCA.tarife + ORTANCA.olcu;    // agirlikli: olagan surelerin orani
  return [(kalan * ORTANCA.tarife) / t, (kalan * ORTANCA.olcu) / t];
}

export function kosum({ rejim, politika, iptal, n = 48 }) {
  const R = K01.esik - GECIT_PAYI;            // kola kalan pay
  const s = { yanit: 0, dusen: 0, bosaIs: 0, toplamSure: 0,
    basarisiz: { teslimat: 0, tarife: 0, olcu: 0 }, uctanUca: [] };
  const imlec = { teslimat: 0, tarife: 0, olcu: 0 };
  const sure = (ad) => REJIM[rejim][ad][imlec[ad]++ % REJIM[rejim][ad].length];

  const cagir = (ad, zt) => {                 // tek alt cagri, zaman asimi zt
    if (zt <= 0) return { ok: false, gecen: 0 };
    const su = sure(ad);
    if (su <= zt) return { ok: true, gecen: su };
    if (iptal === false) s.bosaIs += su - zt; // cagiran vazgecti, bagimlilik calisiyor
    return { ok: false, gecen: zt };
  };

  for (let i = 0; i < n; i += 1) {
    const a = cagir("teslimat", R);           // teslimat-op kolu: tek depo cagrisi
    const p = paylar(politika, R);            // ucretlendirme kolu: iki ardisik kayit
    const b1 = cagir("tarife", Math.min(p[0], R));
    const b2 = cagir("olcu", Math.min(p[1], R - b1.gecen));
    for (const [ad, r] of [["teslimat", a], ["tarife", b1], ["olcu", b2]]) {
      if (r.ok === false) s.basarisiz[ad] += 1;
    }
    const gecen = GECIT_PAYI + Math.max(a.gecen, b1.gecen + b2.gecen);
    s.uctanUca.push(gecen);
    s.toplamSure += gecen;
    if (a.ok && b1.ok && b2.ok && gecen <= K01.esik) s.yanit += 1; else s.dusen += 1;
  }
  const sirali = [...s.uctanUca].sort((x, y) => x - y);
  return { ...s, ortanca: sirali[n >> 1], enKotu: sirali[n - 1], ortalama: s.toplamSure / n, n };
}

İki okuma da her istekte denenir; ücretlendirme kolu ikisinin sonucunu topladıktan sonra karar verir. Bu ayrıntı ölçümün taşıyıcısıdır: ilk okuma bütçeyi yerse ikinci okuma bunu kendi başarısızlığı olarak yaşar.

// butce/kosum.mjs — uc bolusturme politikasinin iki gunde karsilastirilmasi
import { K01, GECIT_PAYI, ORTANCA, paylar, kosum } from "./zincir.mjs";

const R = K01.esik - GECIT_PAYI;
const POLITIKA = ["acgozlu", "esit", "agirlikli"];
const CAGRI = 5;                       // dis istek basina alt cagri: 2 kol + 1 + 2 kayit
const SON_TARIH_BAYT = 8;              // kalan sureyi tasiyan alan
const yuva = (ms) => (K01.tepeOkuma * ms) / 1000;   // L = lambda x W

console.log(`uctan uca esik ${K01.esik} ms (K01), gecit payi ${GECIT_PAYI} ms (K03/U3), kola kalan ${R} ms`);
console.log(`olagan sureler: teslimat ${ORTANCA.teslimat}, tarife ${ORTANCA.tarife}, olcu ${ORTANCA.olcu} ms`);
console.log(`${"politika".padEnd(11)}${"tarife payi(ms)".padStart(16)}${"olcu payi(ms)".padStart(15)}`);
for (const p of POLITIKA) {
  const [a, b] = paylar(p, R);
  console.log(`${p.padEnd(11)}${a.toFixed(1).padStart(16)}${b.toFixed(1).padStart(15)}`);
}

for (const rejim of ["arizasiz", "tarife yavas"]) {
  console.log(`\n-- ${rejim} (48 dis istek, iptal sinyali yok) --`);
  console.log(`${"politika".padEnd(11)}${"yanit".padStart(6)}${"dusen".padStart(6)}${"suc:tarife".padStart(11)}` +
    `${"suc:olcu".padStart(9)}${"ortanca".padStart(8)}${"en kotu".padStart(8)}${"ort.".padStart(7)}` +
    `${"tutulan yuva".padStart(13)}${"bosa is(ms)".padStart(12)}`);
  for (const p of POLITIKA) {
    const r = kosum({ rejim, politika: p, iptal: false });
    console.log(`${p.padEnd(11)}${String(r.yanit).padStart(6)}${String(r.dusen).padStart(6)}` +
      `${String(r.basarisiz.tarife).padStart(11)}${String(r.basarisiz.olcu).padStart(9)}` +
      `${String(r.ortanca).padStart(8)}${String(r.enKotu).padStart(8)}${r.ortalama.toFixed(1).padStart(7)}` +
      `${yuva(r.ortalama).toFixed(1).padStart(13)}${String(r.bosaIs).padStart(12)}`);
  }
}

console.log(`\n-- tarife yavas: sistemin mesgul tuttugu yuva (tepe okuma ${K01.tepeOkuma}/s) --`);
console.log(`${"politika".padEnd(11)}${"cagiran".padStart(9)}${"terk edilen".padStart(12)}` +
  `${"toplam(iptalsiz)".padStart(17)}${"toplam(iptalli)".padStart(16)}`);
for (const p of POLITIKA) {
  const r = kosum({ rejim: "tarife yavas", politika: p, iptal: false });
  const c = yuva(r.ortalama), t = yuva(r.bosaIs / r.n);
  console.log(`${p.padEnd(11)}${c.toFixed(1).padStart(9)}${t.toFixed(1).padStart(12)}` +
    `${(c + t).toFixed(1).padStart(17)}${c.toFixed(1).padStart(16)}`);
}

const bayt = K01.tepeUc * CAGRI * SON_TARIH_BAYT;
const a = kosum({ rejim: "arizasiz", politika: "acgozlu", iptal: false });
console.log(`\n-- arizasiz gunun bedeli (hesap) --`);
console.log(`son tarih alani ${SON_TARIH_BAYT} B x ${CAGRI} alt cagri = ${CAGRI * SON_TARIH_BAYT} B/istek,` +
  ` takip yanitinin (${K01.yanitBayt} B) %${((CAGRI * SON_TARIH_BAYT) / K01.yanitBayt * 100).toFixed(1)}`);
console.log(`tepe ucta ${K01.tepeUc} istek/s -> ${bayt.toFixed(2)} B/s = ${(bayt / 1024).toFixed(2)} KiB/s`);
for (const p of ["esit", "agirlikli"]) {
  const r = kosum({ rejim: "arizasiz", politika: p, iptal: false });
  const fark = r.dusen - a.dusen;
  console.log(`${p.padEnd(11)}: acgozluye gore ${fark}/${r.n} fazladan dusen istek` +
    ` = %${((fark / r.n) * 100).toFixed(2)} -> tepe okumada ${((K01.tepeOkuma * fark) / r.n).toFixed(2)} istek/s`);
}

console.log(`\n-- AY10'un duyarliligi: tarifenin yavas kaldigi sure --`);
console.log(`${"sure(dk)".padStart(9)}${"ayda".padStart(6)}${"aylik(dk)".padStart(11)}${"ariza payinin(28,2 dk)".padStart(23)}`);
for (const [dk, kez] of [[12, 1], [12, 2], [24, 1]]) {
  console.log(`${String(dk).padStart(9)}${String(kez).padStart(6)}${String(dk * kez).padStart(11)}` +
    `${`%${(((dk * kez) / 28.2) * 100).toFixed(1)}`.padStart(23)}`);
}
uctan uca esik 200 ms (K01), gecit payi 20 ms (K03/U3), kola kalan 180 ms
olagan sureler: teslimat 8, tarife 6, olcu 12 ms
politika    tarife payi(ms)  olcu payi(ms)
acgozlu               180.0          180.0
esit                   90.0           90.0
agirlikli              60.0          120.0

-- arizasiz (48 dis istek, iptal sinyali yok) --
politika    yanit dusen suc:tarife suc:olcu ortanca en kotu   ort. tutulan yuva bosa is(ms)
acgozlu        48     0          0        0      40     200   46.2         19.2           0
esit           46     2          0        2      40     190   45.8         19.1          20
agirlikli      46     2          2        0      40     180   45.3         18.9          40

-- tarife yavas (48 dis istek, iptal sinyali yok) --
politika    yanit dusen suc:tarife suc:olcu ortanca en kotu   ort. tutulan yuva bosa is(ms)
acgozlu         6    42         36       42     200     200  197.8         82.4        5540
esit            0    48         48        2     123     200  126.0         52.5        9700
agirlikli       0    48         48        0      93     180   96.4         40.2       11120

-- tarife yavas: sistemin mesgul tuttugu yuva (tepe okuma 416.67/s) --
politika     cagiran terk edilen toplam(iptalsiz) toplam(iptalli)
acgozlu         82.4        48.1            130.5            82.4
esit            52.5        84.2            136.7            52.5
agirlikli       40.2        96.5            136.7            40.2

-- arizasiz gunun bedeli (hesap) --
son tarih alani 8 B x 5 alt cagri = 40 B/istek, takip yanitinin (480 B) %8.3
tepe ucta 513.89 istek/s -> 20555.60 B/s = 20.07 KiB/s
esit       : acgozluye gore 2/48 fazladan dusen istek = %4.17 -> tepe okumada 17.36 istek/s
agirlikli  : acgozluye gore 2/48 fazladan dusen istek = %4.17 -> tepe okumada 17.36 istek/s

-- AY10'un duyarliligi: tarifenin yavas kaldigi sure --
 sure(dk)  ayda  aylik(dk) ariza payinin(28,2 dk)
       12     1         12                  %42.6
       12     2         24                  %85.1
       24     1         24                  %85.1

Bütün sayılar hesap sınıfındadır: belirlenimli bir süre dizisi üzerinde sayılmışlardır. Süre birimi mantıksal bir saattir, ölçülmüş gecikme değildir; koşum makineden bağımsız aynı çıktıyı verir.

Arızasız Günün Bedeli

Bütçenin iki kalemi arızasız günde de ödenir.

Birincisi taşınan alandır. Kalan süreyi çağrıyla birlikte geçirmek her alt çağrıya sekiz baytlık bir alan ekler; beş alt çağrıda dış istek başına 40 bayt eder. Bu, K01’in 480 baytlık takip yanıtının yüzde 8,3’üdür ve uçtaki tepe hızda saniyede 20,07 KiB’lik bir iç trafiktir. Küçük ama sıfır değil, ve zincir derinleştikçe doğrusal büyür.

İkincisi daha pahalıdır: sıkı bölüştürme, sağlam istekleri keser. Arızasız rejimde açgözlü dağıtım kırk sekiz isteğin kırk sekizini yanıtlıyor. Eşit ve ağırlıklı dağıtım kırk altısını yanıtlıyor; ikisi de iki isteği düşürüyor. Bunlar hiçbir arızanın olmadığı bir gündeki yanlış pozitiflerdir — modelde on altıda bir gelen uzun kuyruk, adımın payını aşıyor. Oran yüzde 4,17; K01’in tepe okuma hızında saniyede 17,36 istek eder. Hangi adımın kesildiği de politikaya bağlı: eşit dağıtımda ölçü (payı 90, kuyruğu 100), ağırlıklı dağıtımda tarife (payı 60, kuyruğu 80).

Payı adımın kuyruğuna göre seçmek bu bedeli düşürür ama sıfırlamaz. Bütçe bölüştürmesi bir kuyruk kesme kararıdır ve kesilen kuyruk her zaman gerçek isteklerden oluşur.

Arızalı Günde Ne Değişiyor

İkinci tablo AY10 altında koşuyor ve üç politikanın üç ayrı davranış ürettiğini gösteriyor.

Açgözlü dağıtım altı isteği kurtarıyor. Tarife kimi turlarda 150 ya da 180 milisaniyede dönüyor; 180 milisaniyelik payla bunlar başarılı olur ve geriye ölçüye yetecek kadar kalır. Eşit ve ağırlıklı dağıtımda aynı okumalar 90 ve 60 milisaniyede kesilir, kırk sekiz isteğin kırk sekizi düşer. Bu, sıkı bölüştürmenin bedelinin arızalı günde de sürdüğü anlamına gelir — kurtarılabilir istekler kurtarılmaz.

Karşılığı uçtan uca sürede. Açgözlü dağıtımda ortanca 200 milisaniye: her düşen istek bütçenin tamamını yiyor. Eşit dağıtımda 123, ağırlıklı dağıtımda 93 milisaniye. Çağıran, aynı başarısızlığı yarıdan kısa sürede öğreniyor. Bunun kaynak karşılığı tutulan yuva sütunudur: kuyruk kuramının L=λWL = \lambda W bağıntısıyla, K01’in 416,67 istek/s tepe okuma hızında açgözlü dağıtım 82,4, ağırlıklı dağıtım 40,2 eşzamanlı çağıran yuvasını meşgul tutuyor. Bağıntı bu kursun bulgusu değil; arka plan işleri konusunda kurulmuştu ve burada bir çevirici olarak kullanılıyor.

Suç sütunları arıza kipini gizliyor. Açgözlü dağıtımda tarife otuz altı kez başarısız, ölçü kırk iki kez. Ölçünün rejimi hiç değişmedi; kırk iki başarısızlığın tamamı, tarifenin bütçeyi yemesinden geliyor. Ağırlıklı dağıtımda ölçü sıfır kez başarısız. Aradaki fark bir kayıt farkı değil, bir teşhis farkıdır: açgözlü dağıtım, yavaşlayan adımı sağlam adımın arkasına saklar ve zaman aşımı kayıtlarında en çok görünen ad, arızanın yaşandığı yerin adı olmaz.

Bu, bütçe üzerinden bulaşmadır. Adımlar birbirinden yalıtılmış görünür — ayrı depolar, ayrı kayıtlar — ama paylaştıkları tek bir kaynak vardır ve o kaynak süredir. Payı sabitlemek, o tek paylaşılan kaynağı bölmenin adıdır.

Terk Edilen İş

Son sütun buraya kadarki tabloyu tersine çeviriyor. Çağıran vazgeçtiğinde tarife deposu durmaz; başlattığı okumayı bitirir. Bu iş kimsenin beklemediği iştir ve modelde bosa is olarak sayılır: açgözlü dağıtımda 5540, ağırlıklı dağıtımda 11120 milisaniye. Sıkı bölüştürme, terk edilen işi iki katına çıkarıyor — çünkü daha erken vazgeçmek, bağımlılığın önünde daha uzun bir artık bırakmak demektir.

Üçüncü tablo iki tarafı toplayarak kararı veriyor. İptal sinyali yokken sistemin meşgul tuttuğu toplam yuva açgözlüde 130,5, eşitte ve ağırlıklıda 136,7. Neredeyse aynı sayı: bölüştürme, yükü çağırandan bağımlılığa taşımaktan başka bir şey yapmıyor. Sıkı bölüştürmenin kazancı ancak iptal sinyali varken görünür — çağıran vazgeçtiğini bağımlılığa bildirir ve okuma durdurulur. O zaman terk edilen iş sıfırlanır ve toplam yuva 82,4’e karşı 40,2 olur.

Karar cümlesi budur: son tarih aktarımı iptal sinyali olmadan tamamlanmış sayılmaz. Kalan süreyi çağrıyla geçirmek, çağıranın ne zaman vazgeçeceğini söyler; iptal sinyali, vazgeçtiğini söyler. Birincisi olmadan bütçe bölüştürülemez, ikincisi olmadan bölüştürme yalnız yer değiştirir.

Son tablo AY10’un duyarlılığıdır. On iki dakikalık tek bir yavaşlama, K01’in aylık 28,2 dakikalık arıza payının yüzde 42,6’sını harcar. Aynı yavaşlama ayda iki kez olursa ya da bir kez yirmi dört dakika sürerse pay yüzde 85,1’e çıkar ve ayın kalanına 4,2 dakika kalır. Bütçe bölüştürmesi bu dakikaları geri getirmez — istekler yine düşüyor — ama düşen isteğin kaç kaynağı meşgul ettiğini belirler ve arızanın hangi adımda göründüğünü doğrular.

Özet

  • Kola kalan pay (200 ms eşik eksi 20 ms ağ geçidi payı = 180 ms) ardışık alt çağrılara üç biçimde dağıtılır: açgözlü 180/180, eşit 90/90, ağırlıklı 60/120.
  • Arızasız günün bedeli iki kalemdir: son tarih alanı dış istek başına 40 bayt (yanıtın yüzde 8,3’ü, tepe uçta 20,07 KiB/s) ve sıkı bölüştürmenin kestiği geçerli istekler — 48’de 2, yüzde 4,17, tepe okumada saniyede 17,36 istek.
  • AY10 altında açgözlü dağıtım altı isteği kurtarır ama uçtan uca ortancayı 200 ms’de tutar; ağırlıklı dağıtım hiçbirini kurtarmaz ve ortancayı 93 ms’ye indirir, tutulan yuvayı 82,4’ten 40,2’ye düşürür.
  • Açgözlü dağıtımda sağlam adım (ölçü) kırk iki kez başarısız görünür, ağırlıklı dağıtımda sıfır kez; bölüştürme yalnız kaynak değil, arıza kipinin teşhisini de belirler.
  • Sıkı bölüştürme terk edilen işi 5540’tan 11120 milisaniyeye çıkarır; iptal sinyali yokken toplam meşgul yuva 130,5’e karşı 136,7’dir, yani kazanç yoktur. İptal sinyaliyle toplam 82,4’e karşı 40,2 olur — bölüştürme ancak iptalle birlikte kazanç yazar.
  • On iki dakikalık tek bir yavaşlama K01’in aylık 28,2 dakikalık arıza payının yüzde 42,6’sını harcar; ayda iki kez olursa yüzde 85,1.

Sonraki Adım

Bütçe, tek bir isteğin ne kadar bekleyeceğine karar verdi ve bu kararı zincire dağıttı. Sessiz kalan bir varsayım vardı: çağıran her istek için çağrıyı yapabiliyor. Yavaşlayan bağımlılık karşısında bütçe isteği keser, kaynağı geri alır, arızayı doğru adımda gösterir — ama bir sonraki isteğin gelmesini engellemez. İstekler aynı hızla gelmeye devam eder ve her biri aynı bütçeyi aynı yavaş adıma harcar. Aynı sorunun ikinci yüzü yazma yolundadır: taşıyıcıdan gelen durum olayları sabit bir hızla akar, izdüşümü besleyen tüketici yavaşlarsa iş bir yerlerde birikir ve bütçe o birikime dokunmaz. Sonraki ders bu birikimi ele alır ve soruyu tersine çevirir: sistem, artık yetişemediğini kendisine iş veren tarafa nasıl bildirir, o bildirim zincirde nereye kadar yayılır ve bildirim hiç yapılmazsa iş nerede toplanır.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat