---
title: 'Mimari Geçiş Stratejileri'
source: 'https://academia.sh/tr/kurslar/servis-mimarileri/mimari-gecis-stratejileri'
course: 'Servis Mimarileri'
language: tr
updated: '2026-08-17T18:06:53+00:00'
license: 'CC BY-SA 4.0'
---

# Mimari Geçiş Stratejileri

Çalışan bir tek parçadan aşamalı ayrıştırmaya geçiş: boğucu incir kalıbının kod tarafındaki ölçüsü — iki kod tabanında tutulan ortak mantık, tek bir oran değişikliğinin iki dosyaya dokunması, yolların ayrışması ve yönlendirme anahtarıyla tek adımda geri alınabilirlik.

Beş biçim kuruldu ve her biri kendi üç sütununu yazdı. Elde çalışan bir tek parça varken bu
biçimlerden birine nasıl geçileceği ise hiç ele alınmadı. Bu ders geçişin kendisini ölçer.

Tek seferde bütün sistemi yeni bir biçime taşımak, ölçülen bütün maliyetleri aynı anda
üstlenmek demektir. Bunun yerine yol yol ayrıştırılır: bir iş akışının tek bir adımı yeni
bir birime taşınır, geri kalan tek parçada kalır ve trafiğin hangi yola gideceğine bir
anahtar karar verir. Taşınan yollar arttıkça eski gövde küçülür. Bu düzene **boğucu incir
geçişi** (strangler fig) denir; Vaka Çalışmaları kursunda trafiğin ölçüldüğü bu kalıbın
burada ölçülen yanı **kod tarafıdır**.

**MS7.** Yeni yol tek bir adımı taşır: gecikme ücreti hesabı. Ödünç iş akışının geri kalanı
tek parçada kalır. Ölçülen şey trafik payı değil, aynı mantığın iki kod tabanında tutulmasının
bedelidir.

## Anahtar

Eski yol, birinci dersteki ücret kuralının kendisidir.

```js
// tekparca/ucret.mjs — eski yoldaki ucret kurali
// KURAL BASI
export const GUNLUK = 2;
export const ucret = (gun) => (gun > 0 ? gun * GUNLUK : 0);
// KURAL SONU
```

Yönlendirici iş akışıyla ücret adımı arasına girer. Anahtar kapalıyken çağrı yerel kalır,
açıkken ağ üzerinden yeni birime gider.

```js
// tekparca/yonlendirici.mjs — bogucu incir anahtari; adim eski ya da yeni yola gider
import { ucret as eskiUcret } from "./ucret.mjs";
export async function ucretHesapla(gun) {
  const p = process.env.YENI_UCRET;
  if (!p) return { ucret: eskiUcret(gun), yol: "eski" };
  return (await fetch(`http://127.0.0.1:${p}/hesapla?gun=${gun}`)).json();
}
```

```js
// tekparca/uygulama.mjs — odunc is akisi; yalniz ucret adimi yonlendiriciden gecer
import { ucretHesapla } from "./yonlendirici.mjs";
const durum = { kitap: "rafta", acikOdunc: 1, sinir: 5 };
const gun = Number(process.argv[2] ?? 3);
if (durum.acikOdunc >= durum.sinir) { console.log("odunc siniri asildi"); process.exit(0); }
durum.kitap = "odunc";
durum.acikOdunc += 1;
const { ucret, yol } = await ucretHesapla(gun);
console.log(`odunc verildi: kitap 1 -> uye 4, gecikme ${gun} gun, ucret ${ucret} (ucret yolu: ${yol})`);
```

Yeni birim, kuralı kendi kod tabanında taşır. Taşımak zorundadır: ayrı bir dağıtım birimi
olması, tek parçanın dosyalarını ithal edememesi demektir.

```js
// ucret-servisi.mjs — yeni yol; ayni kural ikinci kod tabaninda
import { createServer } from "node:http";
const port = Number(process.argv[2]);
if (!port) { console.log("kullanim: node ucret-servisi.mjs <port>"); process.exit(0); }
// KURAL BASI
export const GUNLUK = 2;
export const ucret = (gun) => (gun > 0 ? gun * GUNLUK : 0);
// KURAL SONU
createServer((istek, yanit) => {
  const gun = Number(new URL(istek.url, "http://y").searchParams.get("gun"));
  yanit.end(JSON.stringify({ ucret: ucret(gun), yol: "yeni" }));
}).listen(port, () => console.log(`ucret ${port}`));
```

```sh
node tekparca/uygulama.mjs 3
```

```
odunc verildi: kitap 1 -> uye 4, gecikme 3 gun, ucret 6 (ucret yolu: eski)
```

```sh
# baslat.sh — yeni ucret sureci ayaga kalkar, ayni istek anahtar acikken kosar
node ucret-servisi.mjs 8797 >ucret.log 2>&1 & echo $! >ucret.pid
for i in $(seq 40); do curl -s -o /dev/null "http://127.0.0.1:8797/" && break; sleep 0.2; done
YENI_UCRET=8797 node tekparca/uygulama.mjs 3
```

```
odunc verildi: kitap 1 -> uye 4, gecikme 3 gun, ucret 6 (ucret yolu: yeni)
```

İki yol da aynı sonucu verdi. Geçişin istenen durumu budur: yeni yol açıldığında dışarıdan
hiçbir fark görünmez. Fark yalnız `ucret yolu` alanında.

## İki Kod Tabanı

Ölçülecek şey bu iki koşumun eşitliğinde değil, o eşitliği sürdürmenin bedelinde.

```js
// cift.mjs — ayni is kuralinin iki kod tabaninda tutuldugunu olcer
import { readFileSync } from "node:fs";
const kural = (yol) => {
  const s = readFileSync(yol, "utf8").split("\n");
  return s.slice(s.indexOf("// KURAL BASI") + 1, s.indexOf("// KURAL SONU"))
    .map((x) => x.trim()).filter(Boolean);
};
const eski = kural("tekparca/ucret.mjs"), yeni = kural("ucret-servisi.mjs");
const ayni = eski.filter((s) => yeni.includes(s));
console.log(`kural satiri: eski ${eski.length}, yeni ${yeni.length}, birebir ayni ${ayni.length}`);
console.log(`ayni mantigin tutuldugu kod tabani: 2   bir oran degisiminde dokunulacak dosya: 2`);
console.log(`yonlendirme anahtari: YENI_UCRET   geri alma adimi: 1   yeniden dagitim: 0`);
```

```sh
node cift.mjs
```

```
kural satiri: eski 2, yeni 2, birebir ayni 2
ayni mantigin tutuldugu kod tabani: 2   bir oran degisiminde dokunulacak dosya: 2
yonlendirme anahtari: YENI_UCRET   geri alma adimi: 1   yeniden dagitim: 0
```

Kuralın iki satırı da iki kod tabanında birebir duruyor. Geçiş süresince bu bir seçim değil,
zorunluluktur: eski yol hâlâ trafik alıyorsa mantığı taşımak zorundadır, yeni yol da kendi
kopyasını taşımak zorundadır çünkü ötekinin dosyalarına erişemez.

## Çift Bakım

Bedel, kural değiştiğinde ortaya çıkar. Günlük oran yalnız yeni kod tabanında güncellensin.

```sh
# ayrik.sh — oran yalniz yeni kod tabaninda degisir; iki yol ayrisir
kill "$(cat ucret.pid)"
sleep 0.3
sed -i.y 's/export const GUNLUK = 2;/export const GUNLUK = 5;/' ucret-servisi.mjs
rm -f ucret-servisi.mjs.y
node ucret-servisi.mjs 8797 >>ucret.log 2>&1 & echo $! >ucret.pid
for i in $(seq 40); do curl -s -o /dev/null "http://127.0.0.1:8797/" && break; sleep 0.2; done
YENI_UCRET=8797 node tekparca/uygulama.mjs 3
node tekparca/uygulama.mjs 3
```

```
odunc verildi: kitap 1 -> uye 4, gecikme 3 gun, ucret 15 (ucret yolu: yeni)
odunc verildi: kitap 1 -> uye 4, gecikme 3 gun, ucret 6 (ucret yolu: eski)
```

Aynı üye, aynı kitap, aynı gecikme — iki farklı ücret. Hangi tutarın uygulanacağını iş
kuralı değil, isteğin hangi yola düştüğü belirliyor. Bu, geçiş dönemine özgü bir arıza
kipidir ve hiçbir sürecin çökmesini gerektirmez: iki kod tabanı da çalışıyor, ikisi de
kendince doğru.

Ölçü şudur: geçiş süresince ücret kuralına dokunan her değişiklik **iki dosyaya** yazılmak
zorundadır. Bu maliyet taşınan yol sayısıyla değil, taşıma süresinin uzunluğuyla çarpılır.
Yarım kalmış bir geçiş, kalıcı olarak iki katı bakım demektir.

## Geri Alınabilirlik

Buna karşılık kalıbın asıl kazancı da aynı yerdedir.

```sh
# geri-al.sh — yonlendirme anahtari kapatilir; yeni servis durdurulmaz
echo "anahtar kapali, yeniden dagitim yok"
node tekparca/uygulama.mjs 3
echo "yeni servis hala ayakta: $(curl -s 'http://127.0.0.1:8797/hesapla?gun=3')"
```

```
anahtar kapali, yeniden dagitim yok
odunc verildi: kitap 1 -> uye 4, gecikme 3 gun, ucret 6 (ucret yolu: eski)
yeni servis hala ayakta: {"ucret":15,"yol":"yeni"}
```

Eski davranış tek adımda geri geldi: bir ortam değişkeni verilmedi, o kadar. Yeni servis
durdurulmadı, hiçbir şey yeniden dağıtılmadı, hiçbir dosya değişmedi. Eski kod silinmiş
olsaydı bu adımın karşılığı eski kod tabanını yeniden yayına çıkarmak olurdu.

Geri alınabilirliğin bedeli, eski yolun **silinmemiş** olmasıdır. Geçişin bitmiş sayılması,
anahtarın kalıcı olarak açılması ve eski kuralın silinmesiyle olur; o ana kadar çift bakım
sürer. İki maliyet aynı madalyonun iki yüzüdür.

```sh
# esitle.sh — ayni degisiklik eski kod tabanina da tasinir; iki yol yeniden ayni
sed -i.y 's/export const GUNLUK = 2;/export const GUNLUK = 5;/' tekparca/ucret.mjs
rm -f tekparca/ucret.mjs.y
echo "dokunulan dosya: 2 (tekparca/ucret.mjs, ucret-servisi.mjs)"
YENI_UCRET=8797 node tekparca/uygulama.mjs 3
node tekparca/uygulama.mjs 3
kill "$(cat ucret.pid)" 2>/dev/null
```

```
dokunulan dosya: 2 (tekparca/ucret.mjs, ucret-servisi.mjs)
odunc verildi: kitap 1 -> uye 4, gecikme 3 gun, ucret 15 (ucret yolu: yeni)
odunc verildi: kitap 1 -> uye 4, gecikme 3 gun, ucret 15 (ucret yolu: eski)
```

## Üç Sütun

| | Aşamalı geçiş |
|---|---|
| Ucuzlattığı | Geri alma 1 adım, yeniden dağıtım 0; yeni biçimin maliyeti tek yolda sınanıyor, sistemin tamamı taşınmıyor |
| Pahalılaştırdığı | Aynı kural 2 kod tabanında; her değişiklik 2 dosyaya yazılıyor; yönlendirici bir ek dolaylılık katmanı |
| Doğan arıza kipi | Yalnız bir kod tabanı güncellendiğinde aynı istek iki farklı sonuç veriyor; hiçbir süreç çökmüyor, iki yol da kendince doğru |

## Özet

- Boğucu incir geçişi bir iş akışının tek adımını yeni bir birime taşır, geri kalanı yerinde
  bırakır ve trafiği bir yönlendirme anahtarına bağlar.
- Yeni birim ayrı bir dağıtım birimi olduğu için kuralı kendi kod tabanında taşımak zorunda;
  ölçümde aynı iki satır iki kod tabanında birebir duruyor.
- Çift bakımın ölçüsü, oran değişikliğinin 2 dosyaya yazılmak zorunda olmasıdır; yalnız
  birine yazıldığında aynı istek 15 ve 6 gibi iki farklı sonuç verdi.
- Geri alma 1 adımdır ve yeniden dağıtım gerektirmez, çünkü eski yol hâlâ duruyor; bu kazancın
  bedeli çift bakımın sürmesidir.
- Geçiş, anahtarın kalıcı olarak açılması ve eski kuralın silinmesiyle biter; yarım kalmış bir
  geçiş kalıcı iki katı bakım demektir.

## Sonraki Adım

Bu konu boyunca aynı ödünç iş akışı beş biçimde kuruldu — tek parça, modüler tek parça,
servis yönelimli düzen, mikroservisler, sunucusuz işlevler — ve altıncı derste bunlardan
birine geçmenin bedeli ölçüldü. Her ölçümde bir sayı değişti: ithal kenarı, sınır ihlali,
ortak modele bağlı birim, süreç, uç, ağ atlaması, depo çağrısı, dokunulan dosya.

Bütün bu ölçümlerin ortak bir varsayımı vardı ve hiçbir yerde sorgulanmadı: **sınırın nereden
geçtiği** verili kabul edildi. Katalog, üyelik, ödünç, bildirim ve ücretlendirme daha ilk
derste beş ayrı modül olarak çizildi; sonraki beş ders o çizgiyi olduğu gibi devraldı ve
yalnız çizginin hangi biçimde gerçekleştirileceğini tartıştı. Oysa asıl karar biçim değil,
çizginin yeridir. Ücretlendirme neden üyeliğin içinde değil? Bildirim neden ödünçten ayrı?

Bu soru şimdiye kadar hiçbir ölçüte bağlanmadı. Sonraki konu tam olarak bunu ele alır: bir
sınırın nereden geçmesi gerektiğine kodda ve koşumda görünen hangi kanıtla karar verilir.
