---
title: 'Bağımlılık Riski'
source: 'https://academia.sh/tr/kurslar/backend-uretim/bagimlilik-riski'
course: 'Sunucu Güvenliği ve Üretime Alma'
language: tr
updated: '2026-08-17T18:06:49+00:00'
license: 'CC BY-SA 4.0'
---

# Bağımlılık Riski

Sürüm politikası bir yapılandırma kararıdır: beş politika aynı bağımlılık ağacında koşturulur ve biriken açık günü ile kırılan yükseltme sayısı sayılır; gevşek sürüm aralığının sessiz sonucu, aynı kaynak sürümünün iki dağıtımı arasında ayrışan paket sayısıyla ölçülür.

Önceki dersin bütün ölçümleri kendi yazdığımız kodun içindeydi. Ödünç servisinin süreci ayağa
kalktığında yüklenen dosyaların çoğu ise ekibin yazdığı satırlar değildir; ağaçta yirmi dört paket
vardır ve bunların yalnız sekizinin adı bildirim dosyalarında geçer. Kalan on altısı **aktarımlı**
gelir: bir paketin bağımlılığının bağımlılığıdır, kimse onu seçmemiştir ve sürümünü kimse
yazmamıştır.

Bu bağımlılıkların **taranması** Bağımlılık Taraması dersinde ölçülmüştü; oradaki soru aracın neyi
bulduğuydu. Burada aracın bulduğu varsayılır ve bir sonraki soru sorulur: bulgu geldiğinde ne
yapılacağı hangi kurala bağlıdır. O kural **sürüm politikasıdır** ve bir yapılandırma kararıdır —
yazıldığı yer bir bildirim dosyasındaki sürüm kısıtıdır, sonucu ise ekibin hiç görmediği bir
takasta ortaya çıkar: yükseltmeyi sıklaştırmak biriken riski azaltır ve kırılan sürüm sayısını
artırır.

**Gerçek paket adı, sürüm numarası ve zayıflık kaydı kullanılmaz.** Ağaç, yayın çizelgesi ve kayıt
kümesi aşağıda kendi üreticimizle üretilir; tohum görünürdür ve koşum yinelenebilir.

## Ağaç ve Kayıt Kümesi

**BG13 — ağaç 24 paketten oluşur; sekizi doğrudan, on altısı aktarımlıdır ve ufuk 360 gündür.**
Her paketin bir yayın aralığı ve bir kırıcılık oranı vardır: yayınlarının ne kadarı bizim kodumuzu
kırar. **BG15 — bir zayıflık kaydının bize ulaşması 0 ile 90 gün arasında sürer.** Kayıt, zayıflığın
var olmaya başladığı günde değil, bildirildiği günde elimize geçer; açık penceresi ise var olduğu
günden kapandığı güne kadar sayılır.

```js
// agac.mjs — kendi bagimlilik agacimiz, kendi yayin cizelgemiz, kendi kayit kumemiz
export const UFUK = 360;              // gun
export const TOHUM = 8617;
let durum = TOHUM;
const rast = () => (durum = (durum * 1103515245 + 12345) % 2147483648) / 2147483648;
const sec = (dizi) => dizi[Math.floor(rast() * dizi.length)];

// derinlik 1: bildirim dosyamizda adi gecen paket; 2 ve 3: aktarimli, adi gecmez.
const DERINLIK = [...Array(8).fill(1), ...Array(10).fill(2), ...Array(6).fill(3)];
const ARALIK = [14, 30, 45, 60, 90];          // yayin araligi (gun)
const KIRICILIK = [0, 0.08, 0.18, 0.35];      // yayinin bizi kirma orani

export const paketler = DERINLIK.map((derinlik, i) => {
  const aralik = sec(ARALIK);
  const kiricilik = sec(KIRICILIK);
  // aktarimli pakette duzeltme, ust paket yeni surum cikarana kadar kurulamaz.
  const ustGecikme = derinlik === 1 ? 0 : Math.round(sec(ARALIK) * rast());
  const yayinlar = [{ gun: 0, kirici: false }];
  for (let g = Math.round(rast() * aralik); g <= UFUK; g += aralik) {
    if (g > 0) yayinlar.push({ gun: g, kirici: rast() < kiricilik });
  }
  return { ad: `p${String(i + 1).padStart(2, '0')}`, derinlik, aralik, ustGecikme, yayinlar };
});

// Kayit: bir pakette var olan zayiflik. gun: var olmaya basladigi gun; duzelten: onu kapatan
// yayin; bilinen: kaydin bize ulastigi gun. erisilebilir: kod yolumuz o yuzeye dokunuyor.
export const kayitlar = [];
for (let k = 0; k < 11; k++) {
  const p = Math.floor(rast() * paketler.length);
  const gun = 20 + Math.floor(rast() * (UFUK - 80));
  const duzelten = paketler[p].yayinlar.findIndex((y) => y.gun >= gun);
  if (duzelten <= 0) continue;
  const bildirim = Math.round(rast() * 90);      // BG15: kayit gecikmesi 0-90 gun
  kayitlar.push({ paket: p, gun, duzelten, bilinen: gun + bildirim, bildirim, erisilebilir: rast() < 0.55 });
}

// Kisit, her servisin kendi bildirim dosyasinda ayri duruyor.
export const SERVISLER = ['katalog', 'odunc', 'uyelik', 'bildirim', 'ceza', 'arama', 'raporlama'];
export const kisitYeri = paketler.map((p) => (p.derinlik === 1 ? 1 + Math.floor(rast() * SERVISLER.length) : 0));
export const hazirGun = (p, i) => paketler[p].yayinlar[i].gun + paketler[p].ustGecikme;
```

## Beş Politika

**BG14 — kod yayını on dört günde bir yapılır.** Politikalar yalnız bir noktada ayrılır: ağacın
hangi günlerde ve hangi paketler için değiştiği. Beşincisi bir politika değil, bir kısıt
biçimidir — sürüm aralığı gevşek bırakıldığında ağaç, kimse bir dosyaya dokunmadan, yayın anında
kendiliğinden değişir.

```js
// politika.mjs — bes surum politikasi ayni agacta: acik penceresi ile kirilan yukseltme
import { paketler, kayitlar, kisitYeri, hazirGun, SERVISLER, UFUK, TOHUM } from './agac.mjs';

const DAGITIM = 14;   // BG14: yayin gunu; gevsek aralik yalniz bu gunlerde agaci degistirir

const politikalar = {
  'sabit': { gun: () => false },
  'hemen': { gun: () => true },
  'aylik': { gun: (g) => g % 30 === 0 },
  'yalniz guvenlik': { gun: () => true, secici: true },
  'gevsek aralik': { gun: (g) => g % DAGITIM === 0, dosyasiz: true },
};

function kosum(pol) {
  const kurulu = paketler.map(() => 0);
  const acik = kayitlar.map(() => 0);
  let yukseltme = 0, kirilan = 0, mudahale = 0, kirikGun = 0, enCok = 0;
  const anlik = {};
  for (let gun = 1; gun <= UFUK; gun++) {
    let gunlukYukseltme = 0, gunlukKirik = 0;
    if (pol.gun(gun)) {
      for (let p = 0; p < paketler.length; p++) {
        // Secici politika yalnizca kaydi bize ulasmis paketi yukseltir.
        if (pol.secici && !kayitlar.some((k) => k.paket === p && gun >= k.bilinen && kurulu[p] < k.duzelten)) continue;
        let hedef = kurulu[p];
        while (hedef + 1 < paketler[p].yayinlar.length && hazirGun(p, hedef + 1) <= gun) hedef += 1;
        if (hedef === kurulu[p]) continue;
        for (let i = kurulu[p] + 1; i <= hedef; i++) if (paketler[p].yayinlar[i].kirici) gunlukKirik += 1;
        gunlukYukseltme += 1;
        kurulu[p] = hedef;
      }
    }
    yukseltme += gunlukYukseltme;
    kirilan += gunlukKirik;
    if (gunlukYukseltme > 0) mudahale += 1;
    if (gunlukKirik > 0) kirikGun += 1;
    enCok = Math.max(enCok, gunlukKirik);
    kayitlar.forEach((k, i) => { if (gun >= k.gun && kurulu[k.paket] < k.duzelten) acik[i] += 1; });
    if (gun === 180 || gun === 194) anlik[gun] = [...kurulu];
  }
  const erisilebilir = kayitlar.map((k, i) => (k.erisilebilir ? acik[i] : 0));
  return {
    mudahale, yukseltme, kirilan, kirikGun, enCok,
    acikGun: erisilebilir.reduce((a, x) => a + x, 0),
    tumGun: acik.reduce((a, x) => a + x, 0),
    enUzun: Math.max(...erisilebilir),
    dosyasiz: pol.dosyasiz ? yukseltme : 0,
    fark: anlik[180].filter((v, i) => v !== anlik[194][i]).length,
  };
}

const s = (x, n) => String(x).padStart(n);
console.log(`tohum ${TOHUM}: ${paketler.length} paket, ${kayitlar.length} kayit, ufuk ${UFUK} gun`);
console.log(`${'politika'.padEnd(17)}${s('mudahale', 10)}${s('yukseltme', 11)}${s('kirilan', 9)}`
  + `${s('kirik gun', 11)}${s('en cok', 8)}${s('acik gun', 10)}${s('en uzun', 9)}`);
const sonuc = {};
for (const [ad, pol] of Object.entries(politikalar)) {
  const r = (sonuc[ad] = kosum(pol));
  console.log(`${ad.padEnd(17)}${s(r.mudahale, 10)}${s(r.yukseltme, 11)}${s(r.kirilan, 9)}`
    + `${s(r.kirikGun, 11)}${s(r.enCok, 8)}${s(r.acikGun, 10)}${s(r.enUzun, 9)}`);
}

const g = sonuc['gevsek aralik'];
console.log(`\ngevsek aralikta ${g.dosyasiz} yukseltmenin tamami bildirim dosyasina dokunulmadan geldi;`
  + ` ayni kaynak surumunun 180. ve 194. gun dagitimlari ${g.fark} pakette ayrisiyor`);
console.log(`hemen politikasinda ayni ayrisma ${sonuc.hemen.fark} pakette, sabit politikasinda ${sonuc.sabit.fark} pakette`);

const dogrudan = kayitlar.filter((k) => paketler[k.paket].derinlik === 1);
const gecikme = kayitlar.reduce((a, k) => a + paketler[k.paket].ustGecikme, 0);
const bildirim = kayitlar.reduce((a, k) => a + k.bildirim, 0) / kayitlar.length;
console.log(`kayitlarin ${dogrudan.length} tanesi dogrudan pakette, ${kayitlar.length - dogrudan.length} tanesi aktarimli;`
  + ` erisilebilir olan ${kayitlar.filter((k) => k.erisilebilir).length}`);
console.log(`aktarimli kayitlarin ust paket beklemesi toplam ${gecikme} gun; ortalama kayit gecikmesi ${bildirim.toFixed(1)} gun`);
const sirala = (alan) => Object.keys(sonuc).sort((a, b) => sonuc[a][alan] - sonuc[b][alan]).join(' < ');
console.log(`erisilebilirlik suzgeci kaldirilinca acik gun `
  + Object.entries(sonuc).map(([ad, r]) => `${ad} ${r.tumGun}`).join(', '));
console.log(`siralama suzgecli: ${sirala('acikGun')}`);
console.log(`siralama suzgecsiz: ${sirala('tumGun')}`);
console.log(`derinlik 1 paket ${paketler.filter((p) => p.derinlik === 1).length}, `
  + `bildirim dosyalarindaki toplam kisit ${kisitYeri.reduce((a, x) => a + x, 0)} `
  + `(${SERVISLER.length} servis); tek paketin dokundugu dosya sayisi en cok ${Math.max(...kisitYeri)}`);
```

```
tohum 8617: 24 paket, 11 kayit, ufuk 360 gun
politika           mudahale  yukseltme  kirilan  kirik gun  en cok  acik gun  en uzun
sabit                     0          0        0          0       0       860      269
hemen                   237        330       58         54       3       113       43
aylik                    12        214       58         12       8       195       65
yalniz guvenlik          14         15       12          7       6       178       67
gevsek aralik            25        320       56         24       6       147       49

gevsek aralikta 320 yukseltmenin tamami bildirim dosyasina dokunulmadan geldi; ayni kaynak surumunun 180. ve 194. gun dagitimlari 14 pakette ayrisiyor
hemen politikasinda ayni ayrisma 13 pakette, sabit politikasinda 0 pakette
kayitlarin 7 tanesi dogrudan pakette, 4 tanesi aktarimli; erisilebilir olan 5
aktarimli kayitlarin ust paket beklemesi toplam 51 gun; ortalama kayit gecikmesi 42.8 gun
erisilebilirlik suzgeci kaldirilinca acik gun sabit 2181, hemen 349, aylik 520, yalniz guvenlik 534, gevsek aralik 422
siralama suzgecli: hemen < gevsek aralik < yalniz guvenlik < aylik < sabit
siralama suzgecsiz: hemen < gevsek aralik < aylik < yalniz guvenlik < sabit
derinlik 1 paket 8, bildirim dosyalarindaki toplam kisit 39 (7 servis); tek paketin dokundugu dosya sayisi en cok 7
```

## Takasın Okunması

İlk satır yükseltmemenin bedelidir ve kırılan sürüm sütununda sıfır yazar. Ağaç ilk günkü hâliyle
kalır, hiçbir yayın kimseyi uyandırmaz, hiçbir sınama kırılmaz — ve erişilebilir kayıtlar toplam
**860 gün** açık kalır, en uzunu tek başına 269 gün. Bu satır kursun kuralının en pahalı örneğidir:
sabitlenmiş bir ağaç en sessiz yapılandırmadır ve sessizliği risk birikimiyle ödenir.

İkinci satır öteki uçtur. Günlük yükseltme açık günü 860'tan **113'e** indirir, yaklaşık yedi buçuk
kat. Bedeli 237 müdahale günü ve 58 kırılan sürümdür. Kırılmaların dağılımına bakmak gerekir: 54
ayrı güne yayılmışlardır ve tek bir günde en çok üçü birden gelmiştir. Bir kırılmanın hangi
yükseltmeden geldiğini bulmak bu dağılımda ucuzdur.

Üçüncü satır sezginin yanıldığı yerdir. Aylık toplu yükseltme kırılan sürüm sayısını **hiç
azaltmaz** — yine 58. Toplu yükseltme kırılmaları yok etmez, yalnızca on iki güne toplar ve tek bir
günde sekiz kırılma birden gelir. Kazanılan şey müdahale sayısıdır (237 yerine 12), kaybedilen şey
hem açık gündür (113 yerine 195, seksen iki gün fazla) hem de kırılmanın kaynağını bulma kolaylığı.
Yükseltmeyi biriktirmek, kırılma maliyetini azaltmaz; onu tek bir güne yığar.

Dördüncü satır yalnız kaydı olan paketi yükseltir ve müdahaleyi on beş yükseltmeye indirir. Kırılan
sürüm on ikiye düşer, çünkü ağacın çoğuna hiç dokunulmaz. Buna karşılık açık gün 178'dir — günlük
yükseltmeden altmış beş gün fazla — ve en uzun tek pencere 67 günle bütün politikaların en
kötüsüdür. Sebep tablonun altındaki satırdadır: ortalama kayıt gecikmesi **42,8 gündür**. Kayda
göre hareket eden bir politika, kaydın gelmesini beklemek zorundadır; kaydı beklemeyen politika
düzeltmeyi zaten kurmuş olur. Yalnız güvenlik politikası ucuzdur ve tavanı kendi elinde değildir.

## Politikanın Dokunamadığı Günler

Açık günlerin bir bölümü hiçbir politikanın erişemediği yerdedir. On bir kaydın dördü aktarımlı
pakettedir; düzeltme yayımlansa bile üst paket yeni bir sürüm çıkarana kadar kurulamaz ve bu
bekleme toplam **51 gündür**. Bu günler beş satırın hepsinde aynıdır — sürüm kısıtı bildirim
dosyasında olmayan bir paketi bağlamaz. Kayıt gecikmesinin 42,8 günü ile birlikte, tabloda görünen
farkların bir bölümü politikanın değil çizelgenin ürünüdür.

Erişilebilirlik süzgeci ise bir uyarı taşıyor. Süzgeç kaldırıldığında sayılar iki üç katına çıkıyor
(hemen 113 yerine 349, sabit 860 yerine 2181) ve uçlar yerinde kalıyor; ama ortadaki iki politika
yer değiştiriyor. Süzgeçliyken aylık politika yalnız güvenlikten kötü görünür, süzgeçsizken iyi.
Kod yolumuzun gerçekten dokunduğu yüzeyi ayırmak bu yüzden bir ayrıntı değil, sıralamayı çeviren
bir karardır.

## Aralığın Durduğu Yer

Son satır kursun kuralına aittir. Gevşek sürüm aralığı ölçülerde iyi görünür: açık gün 147, kırılan
sürüm 56, müdahale 25. Oysa o 320 yükseltmenin tamamı **bildirim dosyasına dokunulmadan** gelmiştir.
Bunun tek ölçülebilir sonucu tablonun altındaki satırdır: aynı kaynak sürümünün 180'inci ve
194'üncü gün dağıtımları yirmi dört paketin **on dördünde** ayrışır. İki dağıtım aynı kodu taşır,
farklı bir ağaçla çalışır ve aradaki farkın hiçbir kaydı yoktur. Kodu geri almak ağacı geri almaz.

Günlük yükseltme politikasında aynı ayrışma on üç pakettedir; sayı neredeyse aynıdır. Fark, ayrışmanın
kaydıdır: orada her yükseltme bir dosya değişikliğidir, burada hiçbiri değildir. Sabit politikada
ayrışma sıfırdır ve tam da bu yüzden 860 açık gün ödenir.

Kısıtın durduğu yer son satırda sayılıyor: sekiz doğrudan paket, yedi servisin bildirim
dosyalarında toplam **39 kısıt** olarak yazılıdır ve tek bir paket yedi ayrı dosyada birden
görünebiliyor. Tek bir kayda karşılık verirken yedi dosyanın yedisini de bulmak gerekir; altısını
bulup birini atlayan bir yükseltme hata vermez, yalnızca bir servisi eski sürümde bırakır.

## Özet

- Hiç yükseltmemek sıfır kırılma ve 860 açık gün üretti; en uzun tek pencere 269 gün sürdü. Sessiz
  yapılandırmanın bedeli burada birikmiş risktir.
- Günlük yükseltme açık günü 113'e indirdi; bedeli 237 müdahale günü ve 54 güne yayılmış 58 kırılan
  sürümdür.
- Aylık toplu yükseltme kırılan sürüm sayısını azaltmadı (yine 58); onları on iki güne yığdı, tek
  günde sekize çıkardı ve açık günü 195'e yükseltti.
- Yalnız güvenlik politikası on beş yükseltmeyle çalıştı ama 42,8 günlük ortalama kayıt gecikmesi
  yüzünden en uzun pencereyi 67 güne çıkardı; tavanı kendi elinde değildir.
- Aktarımlı paketlerin üst sürüm beklemesi 51 gün, hiçbir politikayla kapanmıyor; erişilebilirlik
  süzgeci ise ortadaki iki politikanın sırasını değiştiriyor.
- Gevşek aralıkta 320 yükseltmenin tamamı dosyaya dokunmadan geldi ve aynı kaynak sürümünün iki
  dağıtımı on dört pakette ayrıştı; ölçüler iyi görünürken ağacın kaydı yoktur.

## Sonraki Adım

İki derste iki yapılandırma kararı ölçüldü ve ikisi de bir soruyu ortada bıraktı. Bir anahtar
döndürüldüğünde bunu kimin, ne zaman, hangi sürümle yaptığı; bir paket yükseltildiğinde ağacın
hangi gün değiştiği; gevşek aralıkta ayrışan on dört paketin hangi dağıtımda geldiği — bu soruların
hiçbirinin yanıtı sistemin içinde durmuyor. Uygulamanın kendi kayıtları isteği ve hatayı yazar,
kararı yazmaz. Sonraki ders bu boşluğu ele alır: hangi olayın kaydedileceğini, kaydın sonradan
değiştirilmediğinin nasıl doğrulanacağını ve kaydın kendisinin ne kadar kişisel veri taşıdığını
sayar.
