Fəsil 05 · 4 dəq oxu

Qərarların qeydə alınması: ADR

Qərarların qeydə alınması: ADR

Architecture əsaslandırması olan qərarlar toplusudur. Əsaslandırma buxarlanır. Seçim ediləndən altı ay sonra onu edən insanlar komanda dəyişib, alternativləri unudub və ya əslində baş verəndən daha səliqəli bir hekayəyə inanmağa başlayıb.

Bu fəsil növbəti komandanın niyyətli təsadüfi olanlardan ayıra bilməsi üçün kifayət edəcək qədər yazmaqdan bəhs edir.

Architecture Decision Record

hər qərar üçün bir ədəd olan, kodla birlikdə saxlanılan qısa sənəddir. Kanonik struktur beş hissədən ibarətdir:

# ADR-0007: Domain event-lərinin publish edilməsi üçün outbox cədvəlindən istifadə

## Status
Accepted (2026-10-20). ADR-0003-ü supersede edir.

## Context
Ordering service Postgres-ə yazır və event-ləri Kafka-ya publish edir.
Bir request daxilində hər ikisinə yazmaq, database commit-indən sonra
Kafka publish-i fail olanda event-lərin itməsinə səbəb olur
(sentyabrda 3 dəfə müşahidə edilib).

## Decision
Event-lər biznes dəyişikliyi ilə eyni transaction-da `outbox` cədvəlinə
yazılır. Relay process-i outbox-u oxuyur, Kafka-ya publish edir və
sətirləri göndərilmiş kimi işarələyir. Delivery at-least-once olduğundan
consumer-lər idempotent olmalıdır.

## Consequences
+ İtən event yoxdur; database transaction-ı single source of truth-dur.
+ Publish biznes koduna toxunmadan retry edilə bilər.
- Əlavə latency (relay hər 200 ms-dən bir poll edir).
- Consumer-lər duplicate-ləri handle etməlidir; bu artıq sənədləşdirilmiş tələbdir.
- Outbox cədvəli prune edilməlidir; job hər gecə işləyir.

## Alternatives considered
- Postgres və Kafka arasında two-phase commit: rədd edilib, Kafka
  client-imiz tərəfindən dəstəklənmir və operational baxımdan kövrəkdir.
- Change data capture (Debezium): mümkündür; təxirə salınıb, çünki
  komandanın əvvəllər operate etmədiyi component əlavə edir. Outbox həcmi
  5k sətir/san-dan çox olarsa yenidən baxılsın.

Bu formatı işlək edən nədir:

  • Qərardan əvvəl context. Bir il sonra oxuyan adam hansı problemin mövcud olduğunu bilməlidir. Problem aradan qalxıbsa, qərar geri qaytarıla bilər.
  • Consequence-lərə pis olanlar da daxildir. Yalnız faydaları sadalayan marketinqdir.
  • Alternativlərin adı çəkilir. "X-i nəzərdən keçirdik və Y səbəbinə görə rədd etdik" eyni mübahisənin hər rübdə yenidən aparılmasının qarşısını alır.
  • Status zamanla dəyişir. Qərarlar supersede olunur. Bunun qeydi qərarın özü qədər dəyərlidir.

Bu həll etdiyi problem, yəni database-ə və broker-ə eyni anda yazmaq, adlanır. Ona və saga-lar kimi daha geniş həllərə Fəsil 12-də qayıdırıq.

Nə ADR-ə layiqdir

Fəsil 1-dəki testdən istifadə edin: geri qaytarılması baha başa gəlirmi? Database seçimi, messaging yanaşması, model-i, API style-ı, , topology-si, hamının təklif etməyə davam etdiyi bir şeyi etməmək qərarı. Bunların hamısı uyğun gəlir.

Logging library-sinin seçimi uyğun gəlmir — seçimin qeyri-adi nəticələri olmasa. Şübhə edəndə yazın; qısa on dəqiqəyə, çatışmayan isə bir meeting-ə başa gəlir.

Doğru qalan diaqramlar

Diaqramlar mətndən daha tez çürüyür, çünki onları redaktə etmək daha çətindir. İki praktika çürüməni ləngidir:

Kiçik, ardıcıl view-lar toplusundan istifadə edin. C4 model-i (Context, Container, Component, Code) populyardır, çünki hər level konkret auditoriya üçün konkret suala cavab verir. Əksər komandalara ilk ikisi lazımdır, dördüncüsü nadir hallarda.

Generate oluna biləni generate edin. topology-si, service dependency graph-ları və database schema-ları işləyən sistemdən və ya infrastructure kodundan çıxarıla bilər. Generate olunmuş diaqram heç vaxt köhnəlmir; əllə çəkilmiş diaqram bitdiyi an köhnəlir.

Əllə çəkilmiş view-ları mətn şəklində (Mermaid, PlantUML, Structurizr DSL) repository-də saxlayın ki, təsvir etdikləri qərarlarla yanaşı version olunsunlar.

Fitness function-lar

Yazılmış qərar yenə də səssizcə pozula bilər. Architectural fitness function-lar struktur qaydalarını assert edən avtomatlaşdırılmış yoxlamalardır:

  • "billing-dəki heç bir module marketing-dən import edə bilməz."
  • "Hər HTTP endpoint-in configure olunmuş olmalıdır."
  • "Gecə load test-ində checkout path-ində 400 ms-dən aşağı qalmalıdır."

ArchUnit, dependency-cruiser və custom lint qaydaları kimi alətlər birinci növü ucuz edir. Digərləri CI-da test-lərlə yanaşı yaşayır. arzudan çevirir.

Qeydləri canlı saxlamaq

  • kodun yanında docs/adr/ qovluğunda saxlayın. Wiki sənədlərin unudulmaq üçün getdiyi yerdir.
  • Onları ardıcıl nömrələyin və heç vaxt yenidən nömrələməyin.
  • Yeni kod kimi pull request-lərdə review edin.
  • təsir etdikləri koddan link verin; // bax: ADR-0007 comment-i gələcəyə hədiyyədir.
  • Rübdə bir dəfə accepted oxuyun və hər birinin hələ də doğru olub-olmadığını soruşun. Doğru olmayanları deprecated kimi işarələyin və səbəbini yazın.

Son fikir

Bunların heç biri sənəd istehsal etmək haqqında deyil. Sistemin niyyətini oxuna bilən etmək haqqındadır. Hər qəribə formasının izlənə bilən səbəbi olan codebase insanların dəyişməyə hazır olduğu codebase-dir. Heç kimin heç nəyin niyə belə olduğunu bilmədiyi codebase muzeyə çevrilir: qorunur, uzaqdan heyranlıqla seyr edilir və heç vaxt toxunulmur.

Hazırkı sisteminiz haqqında suallar

  1. Sisteminizdəki ən qəribə struktur seçimini götürün. On dəqiqədən az vaxtda onun niyə edildiyini tapa bilirsinizmi?
  2. Artıq mövcud olan, amma sənədləşdirilməmiş bir qərar üçün bir yazın.
  3. Hamının razılaşdığı hansı bir qayda bu həftə çevrilə bilər?