---
title: 'Kurumsal Servis Veri Yolu'
source: 'https://academia.sh/tr/kurslar/kurumsal-baglam/kurumsal-servis-veri-yolu'
course: 'Kurumsal Bağlam ve Tümleştirme'
language: tr
updated: '2026-08-17T18:10:34+00:00'
license: 'CC BY-SA 4.0'
---

# Kurumsal Servis Veri Yolu

Aynı akış kümesinin ikili bağlarla ve merkezî bir noktayla kurulup karşılaştırılması: yazılan çevirici ve uyarlayıcı sayısı, bir kuralın kaç yerde geçtiği, merkezin işlediği ileti sayısı, merkez düştüğünde kopan akış oranı, yeni bir sistem eklemenin dokunduğu sahip sayısı ve merkezde biriken iş mantığının sahipliği.

Önceki ders tek bir bağı dört kalıpla kurdu ve bir kalıbın neye mal olduğunu gösterdi. Kurumda ise
her sistem her sistemle kendi seçtiği yoldan konuşuyor. Bu ders aynı veri akışı kümesini iki
düzende kurar — her akış için doğrudan bir bağ, ya da bütün akışların geçtiği tek bir merkezî
nokta — ve ikisini aynı ölçülerle karşılaştırır.

**TM4 — kurum kurgudur, akış kümesi `node` içinde bir dizi olarak yazılır.** Ölçülen her nicelik
ya bu diziden ya çalışan süreçlerden ya da tümleştirme kodunun kendi metninden okunur.

**TM5 — alıcı sistemler tek bir süreçte, her biri kendi portunda modellenir.** Gerekçe: ölçülen
nicelikler (yazılan birim, geçilen atlama, işlenen ileti, kopan akış) sistemlerin ayrı makinelerde
durup durmamasından bağımsızdır; ayrı portlar sistem sınırını korumaya yeter.

**TM6 — merkezî nokta bir ürün değil, bir konumdur.** Ölçülen şey merkezin hangi yetenekleri
taşıdığı değil, bütün akışların tek bir noktadan geçmesinin bağ sayısına, arıza yüzeyine ve
sahipliğe ne yaptığıdır.

## Akış Kümesi

Bölgesel kütüphane ağında altı sistem, dokuz veri akışı ve beş ayrı sahip vardır. Ödünç servisi
her ödüncü dört sisteme bildirir, üyelik sistemi üye değişikliğini üç sisteme, katalog nüsha
durumunu iki sisteme. Dokuz akış, altı sistemin kurabileceği otuz yönlü çiftin küçük bir alt
kümesidir; graf seyrektir ve bu seyreklik ilerideki sayıların çoğunu belirler.

```js
// kurum.mjs — kurgu kurum modeli: sistemler, sahipleri ve aralarindaki veri akislari
export const SAHIP = { katalog: "katalog birimi", odunc: "ic gelistirme",
  ucretlendirme: "ic gelistirme", uyelik: "uyelik birimi", raporlama: "yonetim birimi",
  "sube-arayuzu": "sube birimi", ayirtma: "sube birimi", merkez: "tumlestirme birimi" };
export const ALICI = ["ucretlendirme", "raporlama", "katalog", "sube-arayuzu", "odunc"];
export const AKIS = [                            // [kaynak, hedef]; her satir bir bag
  ["odunc", "ucretlendirme"], ["odunc", "raporlama"], ["odunc", "katalog"],
  ["odunc", "sube-arayuzu"], ["uyelik", "odunc"], ["uyelik", "ucretlendirme"],
  ["uyelik", "raporlama"], ["katalog", "sube-arayuzu"], ["katalog", "raporlama"],
];
export const YENI = [                            // yedinci sistem eklenince dogan akislar
  ["odunc", "ayirtma"], ["uyelik", "ayirtma"], ["katalog", "ayirtma"],
  ["ayirtma", "odunc"], ["ayirtma", "sube-arayuzu"],
];
export const derece = (a) => AKIS.filter((b) => b.includes(a)).length;

if (process.argv[1].endsWith("kurum.mjs")) {
  const s = [...new Set(AKIS.flat())];
  console.log(`${s.length} sistem, ${AKIS.length} akis, ${new Set(s.map((a) => SAHIP[a])).size} sahip; ` +
    `olasi yonlu cift ${s.length * (s.length - 1)}`);
  console.log(`en cok akisa dokunan sistem: ` +
    `${s.map((a) => `${a} ${derece(a)}`).sort((x, y) => y.split(" ")[1] - x.split(" ")[1])[0]}`);
  console.log(`yedinci sistem eklenince akis ${AKIS.length} -> ${AKIS.length + YENI.length}`);
}
```

```
6 sistem, 9 akis, 5 sahip; olasi yonlu cift 30
en cok akisa dokunan sistem: odunc 5
yedinci sistem eklenince akis 9 -> 14
```

Alıcı sistemler tek bir süreçte, beş ayrı portta durur ve aldıkları kaydı kendi kütüklerine
yazarlar; iki düzenin sonucu bu kütüklerden karşılaştırılır.

```js
// sistemler.mjs — bes alici sistem, her biri kendi portunda; <taban-port>; uzun omurlu surec
import { createServer } from "node:http";
import { appendFileSync } from "node:fs";
import { ALICI } from "./kurum.mjs";
const [taban] = process.argv.slice(2);
if (!taban) { console.log("kullanim: node sistemler.mjs <taban-port>"); process.exit(1); }
ALICI.forEach((ad, i) => createServer(async (istek, yanit) => {
  let s = "";
  for await (const p of istek) s += p;
  appendFileSync(`alinan-${ad}.log`, `${s}\n`);
  yanit.end("tamam");
}).listen(Number(taban) + i));
```

## İkili Bağlar

İkili düzende her akış için bir çevirici yazılır ve çevirici kaynak sistemin içinde durur. Her
sistemin kendi sözcük dağarcığı vardır: ödünç servisi `uyeId` der, üyelik sistemi `uye_no`,
ücretlendirme `uyeNo`. Çevirici bu farkı kapatır ve hedefin beklediği alanları üretir. Dört kural
(gecikme ücreti, rapor dönemi, şube bölgesi, üye sınıfı) çeviricilerin içinde çağrılır.

```js
// ikili.mjs — ikili tumlestirme: her akis icin bir cevirici; cevirici kaynak sistemde durur
export const ucret = (g) => g * 5;                          // gecikme ucreti kurali
export const donem = (z) => z.slice(0, 7);                  // rapor donemi kurali
export const bolge = (k) => (k <= 2 ? "kuzey" : "guney");   // sube bolgesi kurali
export const sinif = (d) => (d === 1 ? "tam" : "kisitli");  // uye sinifi kurali
export const CEVIRICI = {
  "odunc->ucretlendirme": (o) => ({ uyeNo: o.uyeId, nusha: o.nushaId, borc: ucret(o.gecikmeGunu) }),
  "odunc->raporlama": (o) => ({ olay: "odunc", anahtar: o.nushaId, donem: donem(o.zaman) }),
  "odunc->katalog": (o) => ({ nushaId: o.nushaId, uygun: false }),
  "odunc->sube-arayuzu": (o) => ({ nusha: o.nushaId, bolge: bolge(o.subeKodu) }),
  "uyelik->odunc": (o) => ({ uyeId: o.uye_no, sinif: sinif(o.durum_kodu) }),
  "uyelik->ucretlendirme": (o) => ({ uyeNo: o.uye_no, sinif: sinif(o.durum_kodu) }),
  "uyelik->raporlama": (o) => ({ olay: "uye", anahtar: o.uye_no, donem: donem(o.zaman) }),
  "katalog->sube-arayuzu": (o) => ({ nusha: o.nushaId, bolge: bolge(o.subeKodu) }),
  "katalog->raporlama": (o) => ({ olay: "nusha", anahtar: o.nushaId, donem: donem(o.zaman) }),
};
```

## Merkezî Nokta

Merkezî düzende üretici sistem kendi biçimini tek bir yere verir. Merkez o biçimi ortak biçime
çevirir, akış tablosuna bakarak hedefleri bulur ve her hedef için o sistemin biçimine çevirip
yollar. Sistem başına iki uyarlayıcı vardır: içeri ve dışarı. Dört kural artık tek bir yerde durur
ve `KURAL` dizisi her kuralın işini kimin sahiplendiğini yazar.

```js
// merkez.mjs — merkezi nokta; <port> <taban-port>; uzun omurlu surec
import { createServer } from "node:http";
import { AKIS, ALICI } from "./kurum.mjs";
const [port, taban] = process.argv.slice(2);
if (!taban) { console.log("kullanim: node merkez.mjs <port> <taban-port>"); process.exit(1); }
const ucret = (g) => g * 5, donem = (z) => z.slice(0, 7);   // kurallar merkezde toplandi
const bolge = (k) => (k <= 2 ? "kuzey" : "guney"), sinif = (d) => (d === 1 ? "tam" : "kisitli");
export const KURAL = [                           // merkezde duran kural ve isin asil sahibi
  { ad: "ucret", sahip: "ic gelistirme" }, { ad: "donem", sahip: "yonetim birimi" },
  { ad: "bolge", sahip: "sube birimi" }, { ad: "sinif", sahip: "uyelik birimi" },
];
const GIRIS = {                                  // sistem bicimi -> ortak bicim
  odunc: (o) => ({ tur: "odunc", uye: o.uyeId, nusha: o.nushaId, sube: o.subeKodu,
    gecikme: o.gecikmeGunu, zaman: o.zaman }),
  uyelik: (o) => ({ tur: "uye", uye: o.uye_no, durum: o.durum_kodu, zaman: o.zaman }),
  katalog: (o) => ({ tur: "nusha", nusha: o.nushaId, sube: o.subeKodu, zaman: o.zaman }),
};
const CIKIS = {                                  // ortak bicim -> sistem bicimi
  ucretlendirme: (c) => (c.tur === "odunc"
    ? { uyeNo: c.uye, nusha: c.nusha, borc: ucret(c.gecikme) }
    : { uyeNo: c.uye, sinif: sinif(c.durum) }),
  raporlama: (c) => ({ olay: c.tur, anahtar: c.nusha ?? c.uye, donem: donem(c.zaman) }),
  katalog: (c) => ({ nushaId: c.nusha, uygun: false }),
  "sube-arayuzu": (c) => ({ nusha: c.nusha, bolge: bolge(c.sube) }),
  odunc: (c) => ({ uyeId: c.uye, sinif: sinif(c.durum) }),
};
let gelen = 0, giden = 0;                        // merkezin isledigi ileti sayisi

createServer(async (istek, yanit) => {
  if (istek.url === "/sayac") { yanit.end(`${gelen} ${giden}`); return; }
  if (istek.url === "/kapat") { yanit.end("kapali"); process.exit(0); }
  let s = "";
  for await (const p of istek) s += p;
  const { kaynak, govde } = JSON.parse(s);
  gelen += 1;
  const ortak = GIRIS[kaynak](govde);
  for (const h of AKIS.filter((b) => b[0] === kaynak).map((b) => b[1])) {
    giden += 1;
    await fetch(`http://127.0.0.1:${Number(taban) + ALICI.indexOf(h)}/al`,
      { method: "POST", body: JSON.stringify(CIKIS[h](ortak)) });
  }
  yanit.end("tamam");
}).listen(Number(port));
```

## Ölçüm

Araç aynı altı olayı önce ikili düzende, sonra merkezî düzende geçirir ve alıcı kütüklerini
karşılaştırır. Yazılan birim sayısı ve kuralın geçtiği yer sayısı çalışan süreçlerden değil, iki
tümleştirme dosyasının metninden okunur. Son adımda merkez kapatılır ve aynı altı olay yeniden
gönderilir.

```js
// olc.mjs — iki duzeni ayni akis kumesinde olcer; <taban-port> <merkez-port>
import { existsSync, readFileSync, rmSync } from "node:fs";
import { AKIS, ALICI, SAHIP, YENI } from "./kurum.mjs";
import { CEVIRICI } from "./ikili.mjs";
const [taban, mp] = process.argv.slice(2);
if (!mp) { console.log("kullanim: node olc.mjs <taban-port> <merkez-port>"); process.exit(1); }
const OLAY = [                                   // uretici sistemlerin kendi bicimindeki olaylari
  ["odunc", { uyeId: 7, nushaId: 401, subeKodu: 1, gecikmeGunu: 3, zaman: "2026-04-11" }],
  ["odunc", { uyeId: 9, nushaId: 402, subeKodu: 3, gecikmeGunu: 0, zaman: "2026-04-12" }],
  ["uyelik", { uye_no: 7, durum_kodu: 1, zaman: "2026-04-11" }],
  ["uyelik", { uye_no: 9, durum_kodu: 2, zaman: "2026-04-13" }],
  ["katalog", { nushaId: 401, subeKodu: 1, zaman: "2026-04-11" }],
  ["katalog", { nushaId: 403, subeKodu: 4, zaman: "2026-04-14" }],
];
const TESLIM = AKIS.length * 2;                  // her akis iki olay tasir
const sil = () => ALICI.forEach((a) => rmSync(`alinan-${a}.log`, { force: true }));
const topla = () => ALICI.flatMap((a) => existsSync(`alinan-${a}.log`)
  ? readFileSync(`alinan-${a}.log`, "utf8").split("\n").filter(Boolean).map((s) => `${a} ${s}`) : []);
const ikiliKos = async () => {                   // cevirici kaynak sistemde kosar, dogrudan yollar
  for (const [k, g] of OLAY) {
    for (const h of AKIS.filter((b) => b[0] === k).map((b) => b[1])) {
      await fetch(`http://127.0.0.1:${Number(taban) + ALICI.indexOf(h)}/al`,
        { method: "POST", body: JSON.stringify(CEVIRICI[`${k}->${h}`](g)) });
    }
  }
};
const merkezKos = async () => {                  // uretici yalniz kendi bicimini merkeze verir
  let kabul = 0;
  for (const [kaynak, govde] of OLAY) {
    try {
      await fetch(`http://127.0.0.1:${mp}/olay`, { method: "POST",
        body: JSON.stringify({ kaynak, govde }) });
      kabul += 1;
    } catch { kabul += 0; }                      // merkez kapaliysa uretici teslim edemez
  }
  return kabul;
};
sil(); await ikiliKos(); const a = topla().sort();
sil(); await merkezKos(); const b = topla().sort();
const [gelen, giden] = (await (await fetch(`http://127.0.0.1:${mp}/sayac`)).text()).split(" ").map(Number);
const mk = readFileSync("merkez.mjs", "utf8"), ik = readFileSync("ikili.mjs", "utf8");
const kesit = (m, ad) => m.split(`const ${ad} = {`)[1].split("\n};")[0];
const anahtar = (m) => m.match(/^ {2}"?[\w>-]+"?: \(/gm).length;   // kalip basina yazilan birim
const cagri = (m) => ["ucret", "donem", "bolge", "sinif"]          // kuralin gectigi yer sayisi
  .reduce((s, r) => s + (m.match(new RegExp(`\\b${r}\\(`, "g")) || []).length, 0);
const kural = mk.split("KURAL = [")[1].split("];")[0].match(/sahip: "([^"]+)"/g);
const kume = (l) => new Set(l).size;
const MD = ["ayirtma", "merkez"];                // merkezli duzende dokunulan birimler
const satir = (ad, x, y) => console.log(`${ad.padEnd(41)}${String(x).padStart(7)}${String(y).padStart(9)}`);

satir("olcu", "ikili", "merkezi");
satir("akis (bag) sayisi", AKIS.length, AKIS.length);
satir("yazilan cevirici / uyarlayici", anahtar(kesit(ik, "CEVIRICI")),
  anahtar(kesit(mk, "GIRIS")) + anahtar(kesit(mk, "CIKIS")));
satir("kuralin gectigi yer", cagri(ik), cagri(mk));
satir("teslim basina atlama", 1, 2);
satir("en yogun birimin isledigi ileti", 2, gelen + giden);
satir("bir birim dusunce kopan akis", Math.max(...AKIS.flat()
  .map((s) => AKIS.filter((b) => b.includes(s)).length)), AKIS.length);
satir("yedinci sistem: yazilacak birim", YENI.length, MD.length);
satir("yedinci sistem: dokunulan sahip", kume(YENI.map((b) => SAHIP[b[0]])),
  kume(MD.map((s) => SAHIP[s])));
satir("sahibi baska olan, merkezde duran kural", 0,
  kural.filter((s) => !s.includes(SAHIP.merkez)).length);
console.log(`iki duzenin teslimi: ${a.length}/${b.length} kayit, ` +
  `birebir ayni: ${JSON.stringify(a) === JSON.stringify(b) ? "evet" : "hayir"}`);

await fetch(`http://127.0.0.1:${mp}/kapat`).catch(() => 0);        // merkez kapatilir
sil(); const kabul = await merkezKos(); const dusukMerkez = topla().length;
sil(); await ikiliKos();
console.log(`merkez kapali: ${kabul}/${OLAY.length} olay kabul edildi, ` +
  `${dusukMerkez}/${TESLIM} teslim oldu; ikili duzen ayni anda ${topla().length}/${TESLIM} teslim etti`);
```

```bash
node sistemler.mjs 8991 & S=$!
node merkez.mjs 8990 8991 &
sleep 0.8
node olc.mjs 8991 8990
kill $S
```

```
olcu                                       ikili  merkezi
akis (bag) sayisi                              9        9
yazilan cevirici / uyarlayici                  9        8
kuralin gectigi yer                            8        5
teslim basina atlama                           1        2
en yogun birimin isledigi ileti                2       24
bir birim dusunce kopan akis                   5        9
yedinci sistem: yazilacak birim                5        2
yedinci sistem: dokunulan sahip                4        2
sahibi baska olan, merkezde duran kural        0        4
iki duzenin teslimi: 18/18 kayit, birebir ayni: evet
merkez kapali: 0/6 olay kabul edildi, 0/18 teslim oldu; ikili duzen ayni anda 18/18 teslim etti
```

## Bağ Sayısı Ne Kadar Azalıyor

Son satırdan önceki karşılaştırma ölçümün geçerliliğini kuruyor: iki düzen de on sekiz kaydı
teslim ediyor ve teslim edilen kayıtlar birebir aynı. Aradaki fark işin sonucunda değil, işin
nerede durduğunda.

İkinci satır beklenen kazancı vermiyor. Dokuz akış için dokuz çevirici yerine sekiz uyarlayıcı
yazılıyor; kazanç tek birim. Merkezî tümleştirmenin klasik gerekçesi bağ sayısının sistem sayısının
karesi kadar artmasıdır, ama o gerekçe bütün sistemlerin birbiriyle konuştuğu varsayımına
dayanır. Bu kurumda altı sistemin kurabileceği otuz yönlü çiftten yalnız dokuzu gerçekleşmiştir.
Çevirici sayısı akış sayısıyla, uyarlayıcı sayısı sistem sayısıyla büyür; graf seyrek olduğu
sürece ikisi birbirine yakın kalır ve merkezî düzenin bu kolondaki üstünlüğü küçüktür.

Asıl kazanç üçüncü satırdadır. Aynı dört kural ikili düzende sekiz yerde çağrılıyor, merkezde beş
yerde. Rapor dönemi kuralı üç ayrı çeviricide geçiyor, çünkü raporlamaya veri gönderen üç sistem
de o hesabı kendi kodunda yapmak zorunda. Dönem tanımı değişirse ikili düzende üç ayrı sistemin,
merkezde tek bir birimin değişmesi gerekir. Merkezin sattığı şey bağ sayısı değil, tekrarın
ortadan kalkmasıdır.

## Merkezin Bedeli

Beşinci satır darboğazı sayıya çeviriyor. Altı olay için merkez yirmi dört ileti işliyor: altı
giriş, on sekiz çıkış. İkili düzende en yoğun tek bağın işlediği ileti sayısı iki. Merkez, en
yoğun ikili bağın on iki katı iş yapıyor ve bu oran akış sayısıyla büyüyor; üstüne teslim başına
bir atlama ekliyor.

Altıncı satır arıza yüzeyini veriyor. İkili düzende en çok akışa dokunan sistem ödünç servisidir
ve o düştüğünde dokuz akıştan beşi kopar. Merkez düştüğünde dokuzunun dokuzu kopar. Çıktının son
satırı bunu ölçümle gösteriyor: merkez kapatıldığında altı olayın hiçbiri kabul edilmiyor ve on
sekiz teslimden sıfırı gerçekleşiyor; aynı anda ikili düzen on sekiz teslimin on sekizini yapıyor.
Ödünç servisi düştüğünde kurum ödünç veremediği için zaten durmuştur; merkez düştüğünde ise
hiçbir iş yapmayan bir bileşen bütün kurumu durdurur. Tek arıza noktasının rahatsız edici yanı
budur: iş değeri sıfır olan bir bileşenin arıza payı en yüksektir.

## Yeni Sistem ve Merkezde Biriken Mantık

Yedinci ve sekizinci satırlar merkezî düzenin en güçlü savunmasıdır. Ayırtma sistemi eklendiğinde
beş yeni akış doğuyor. İkili düzende bu beş akış için beş çevirici yazılır ve çeviriciler kaynak
sistemlerin içinde durduğu için ödünç, üyelik, katalog ve ayırtma kodlarına dokunulur: dört ayrı
sahiple takvim uzlaştırılır. Merkezî düzende yalnız iki birim yazılır — ayırtmanın giriş ve çıkış
uyarlayıcısı — ve dokunulan sahip sayısı ikiye iner. Yeni sistemin maliyeti sistem sayısından
kopar.

Son satır bunun karşılığını gösteriyor. Merkezde dört kural duruyor ve dördünün de asıl sahibi
başkasıdır: gecikme ücreti ücretlendirmenin, rapor dönemi yönetim biriminin, bölge tanımı şube
biriminin, üye sınıfı üyelik biriminin işidir. Merkezin sahibi olan tümleştirme birimi bu
kuralların hiçbirini yazacak yetkinliğe sahip değildir ama hepsinin kodunu taşır. Bunun iki sonucu
var. Birincisi, üye sınıfı tanımı değiştiğinde değişiklik üyelik biriminin kendi sürümüyle değil,
merkezin sürümüyle çıkar; ikincisi, o sürüm dokuz akışın tamamını birden yeniden dağıtır. Kuralın
tekrarı kalkarken kuralın sahipliği bulanıklaşıyor ve dağıtım birimleri birbirine bağlanıyor.
Seçim akış grafının ne kadar sıkı olduğuna bağlıdır: merkez tekrarı ve yeni sistemin koordinasyon
maliyetini düşürür, karşılığında bir atlama, ortak bir arıza noktası ve sahibi belirsiz bir kural
yığını ekler.

## Özet

- Aynı dokuz akış iki düzende kuruldu ve ikisi de aynı 18 kaydı birebir aynı içerikle teslim etti;
  karşılaştırma bu doğrulamanın üstüne kuruldu.
- Yazılan birim sayısı 9'a karşı 8; altı sistemin 30 olası yönlü çiftinden yalnız 9'u
  gerçekleştiği için merkezin bağ sayısı kazancı tek birimde kaldı.
- Aynı dört kural ikili düzende 8, merkezde 5 yerde geçiyor; rapor dönemi kuralı üç ayrı sistemde
  tekrarlanıyor.
- Merkez altı olay için 24 ileti işliyor, en yoğun ikili bağ 2; merkez kapatıldığında 18 teslimden
  0'ı gerçekleşirken ikili düzen aynı anda 18'ini tamamlıyor.
- Yedinci sistem ikili düzende 5 birim ve 4 sahibe, merkezî düzende 2 birim ve 2 sahibe mal
  oluyor; karşılığında merkezde sahibi başkası olan 4 kural birikiyor.

## Sonraki Adım

İki ders boyunca veri hep tek yönde aktı: bir sistem yazdı, ötekiler okudu. Kaynak belliydi, bağın
yönü belliydi ve çakışma diye bir şey yoktu. Kurumda bu varsayım çoğu varlık için tutmaz. Üye
kaydı üyelik sisteminde de, ödünç servisinde de, belediyedeki kimlik servisinde de durur; üçü de
kendi kullanıcı arayüzünden yazılır ve üçünün adres alanı aynı üye için farklı değerler taşır.
Sonraki ders aynı varlığı üç sistemde tutar ve sayar: kaç sistem yazıyor, kaç alan çakışıyor, bir
uzlaştırma turunda kaç kayıt düzeliyor ve geriye kaç tutarsızlık kalıyor; bir sistem kaynak
seçildiğinde bu sayılar nasıl değişiyor ve o seçim yazma yolunda neyi uzatıyor.
