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 constraint-ləri təsadüfi olanlardan ayıra bilməsi üçün kifayət edəcək qədər yazmaqdan bəhs edir.
Architecture Decision Record
ADR 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 ADR 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 ADR-in həll etdiyi problem, yəni database-ə və broker-ə eyni anda yazmaq, dual write 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ı, authentication model-i, API style-ı, tenancy model-i, deployment 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 ADR on dəqiqəyə, çatışmayan ADR 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. Deployment 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 modulemarketing-dən import edə bilməz." - "Hər HTTP endpoint-in configure olunmuş timeout-u olmalıdır."
- "Gecə load test-ində checkout path-ində p99 latency 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. Fitness function ADR-i arzudan constraint-ə çevirir.
Qeydləri canlı saxlamaq
- ADR-ləri 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 ADR-ləri kod kimi pull request-lərdə review edin.
- ADR-lərə təsir etdikləri koddan link verin;
// bax: ADR-0007comment-i gələcəyə hədiyyədir. - Rübdə bir dəfə accepted ADR-ləri 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
- Sisteminizdəki ən qəribə struktur seçimini götürün. On dəqiqədən az vaxtda onun niyə edildiyini tapa bilirsinizmi?
- Artıq mövcud olan, amma sənədləşdirilməmiş bir qərar üçün bir ADR yazın.
- Hamının razılaşdığı hansı bir qayda bu həftə fitness function-a çevrilə bilər?