Hardadır Potensial Bottleneck-lər? Gələcək Improvement-lər
Bir sistem ilk qurulanda onun əsas problemi adətən performans olmur.
Əsas məqsəd sistemin düzgün işləməsidir: request gəlir, backend onu emal edir, database-dən məlumat oxunur və cavab geri qaytarılır.
Amma sistem böyüdükcə vəziyyət dəyişir.
İstifadəçi sayı artır, eyni anda daha çox request gəlir, database daha çox sorğu qəbul edir, üçüncü tərəf servislərdən asılılıqlar yaranır və əvvəllər heç hiss olunmayan bəzi hissələr artıq sistemin sürətini müəyyən etməyə başlayır.
Məhz burada bottleneck anlayışı ortaya çıxır.
Bottleneck sistemin ən yavaş və ya ən çox yüklənən hissəsidir. Maraqlısı isə odur ki, bottleneck həmişə gözlədiyimiz yerdə olmur.
Bəzən problem CPU deyil, database connection pool olur. Bəzən database özü yox, bir neçə servisin eyni cədvələ yazması olur. Bəzən isə bütün sistem çox sürətli işləsə də, xarici API 2 saniyə cavab verdiyi üçün istifadəçi gecikmə hiss edir.
Bu səbəbdən gələcək improvement-lərə baxarkən yalnız “serveri gücləndirək” yanaşması kifayət etmir.

1. Database ən böyük namizədlərdən biridir
Backend sistemlərdə ən çox rast gəlinən bottleneck-lərdən biri database-dir.
Başlanğıcda, məsələn, bir request üçün 2–3 SQL query kifayət edə bilər. Lakin sistem böyüdükcə həmin endpoint daha çox istifadə olunur və database-ə düşən yük sürətlə artır.
100 request/saniyə × 5 SQL query = 500 database query/saniyə
Əgər həmin query-lərdən biri ağır JOIN, böyük table scan və ya düzgün index olmadan işləyirsə, problem artıq application serverində deyil.
Burada ilk improvement database-i dəyişmək deyil.
Əvvəlcə:
slow query-lər müəyyən edilməlidir
execution plan analiz olunmalıdır
lazımsız query-lər azaldılmalıdır
index-lər optimallaşdırılmalıdır
connection pool düzgün konfiqurasiya edilməlidir
pagination tətbiq olunmalıdır
eyni məlumatın təkrar-təkrar database-dən oxunmasının qarşısı alınmalıdır
Xüsusilə shared database istifadə olunan microservice sistemlərində bir servisin database-də yaratdığı yük digər servislərə də təsir göstərə bilər. AWS də shared-database yanaşmasında “hot tables” və servislər arasında runtime coupling riskinə diqqət çəkir.

2. Cache olmadan hər şeyi database-dən oxumaq
Digər potensial bottleneck isə çox oxunan məlumatların hər dəfə database-dən gətirilməsidir.
Məsələn, bir məlumat saniyədə minlərlə dəfə oxunur, amma həmin məlumat hər saniyə dəyişmir.
Belə vəziyyətdə hər request-in database-ə getməsi əvəzinə cache istifadə etmək daha məntiqli ola bilər.

Before: database hər request-i daşıyır.
After: cache database yükünün böyük hissəsini öz üzərinə götürür.
AWS də cache-in application server ilə database arasında yerləşdirilməsinin database read load-unu azaltmaq və latency-ni yaxşılaşdırmaq üçün istifadə olunduğunu qeyd edir.
Cache-aside modeli də buna uyğundur: əvvəl cache yoxlanılır, cache miss olduqda database-ə müraciət edilir.
3. Synchronous communication gələcəkdə gecikmə yarada bilər
Microservice arxitekturasında başqa bir potensial bottleneck servislər arasındakı communication-dır.
Client → Order Service → Customer Service → Payment Service → Notification Service
İlk baxışda burada heç bir problem görünmür.
Amma Order Service response qaytarmazdan əvvəl bütün servislərdən cavab gözləyirsə, ən yavaş servis bütün request-in sürətini müəyyən edir.
Customer Service → 50 ms
Payment Service → 100 ms
Notification Service → 800 ms
Bu halda notification əməliyyatının 800 ms çəkməsi istifadəçinin bütün request üçün gözləməsinə səbəb ola bilər.
Halbuki notification istifadəçiyə response qaytarmaq üçün mütləq lazım olmaya bilər.

4. Connection pool da bottleneck ola bilər
Bəzən application serverinin CPU-su 30%-dir, memory normaldır, database də normal görünür.
Amma request-lər yenə də gözləyir.
Səbəb connection pool ola bilər.
Məsələn, application yalnız 20 database connection saxlaya bilir, amma eyni anda 200 request database-ə çıxmağa çalışır.
Serverin CPU-su boş ola bilər, amma request-lər connection gözləyirsə sistem yenə də yavaşdır.
Bu, məqaləni sırf “database slow query” mövzusundan çıxarıb daha real production perspektivinə gətirir.

5. Xarici servislər bizim nəzarətimizdə deyil
Production sistemlərdə başqa bir maraqlı bottleneck xarici dependency-lərdir.
Our Backend → Payment API, SMS Provider, Email Provider, External API
Bizim application 50 ms-də işləyə bilər.
Amma external API 1.5 saniyə gec cavab verirsə, istifadəçi bunu bizim sistemin yavaşlığı kimi görəcək.

The slowest dependency can define the user experience.
6. Bir database artıq kifayət etməyəndə
Sistem böyüdükcə database-in yükünü də bölmək lazım gələ bilər.

Məqsəd database-i böyütmək deyil. Məqsəd read workload-u write path-dən ayırmaqdır.
7. Ən vacib improvement: bottleneck-i əvvəlcədən görmək
Əslində gələcək improvement-lərin ən vacib hissəsi konkret texnologiya seçmək deyil.
Əsas məsələ sistemin harada yavaşladığını ölçə bilməkdir.
Bunun üçün observability vacibdir.

Request 900 ms çəkirsə, əsas sual “yavaşdır?” deyil. Əsas sual “niyə?”-dir.
620 ms — database
180 ms — external API
90 ms — connection
qalanı — application logic?
Distributed tracing məhz request-in müxtəlif servislərdə və komponentlərdə nə qədər vaxt keçirdiyini görmək üçün istifadə olunur. AWS-in microservices guidance-ında da monitoring, centralized logging və distributed tracing observability-nin əsas hissələri kimi göstərilir.
Nəticə
Bir sistemin bottleneck-i bu gün database ola bilər, sabah isə database artıq problem olmaya bilər.
İstifadəçi sayı artdıqca problem application serverinə, connection pool-a, network-ə, queue-ya və ya xarici dependency-lərə keçə bilər.
Ona görə gələcək improvement-ləri əvvəlcədən belə düşünmək daha düzgündür:
Measure → Identify → Optimize → Scale
Əvvəlcə ölç.
Sonra problemin harada olduğunu tap.
Daha sonra həmin hissəni optimallaşdır.
Yalnız bundan sonra lazım gəlsə horizontal scaling, caching, queue, read replica, sharding və ya daha mürəkkəb arxitekturalara keç.
Yaxşı arxitektura ən çox texnologiyanın istifadə edildiyi arxitektura deyil.
Yaxşı arxitektura problemin yarandığı yeri görə bildiyin və həmin problemi lazımi qədər mürəkkəbliklə həll etdiyin arxitekturadır.
Bu sistem üçün gələcəkdə əsas improvement istiqamətləri də məhz buradan çıxır:
database optimization → caching → asynchronous processing → connection pool tuning → dependency isolation → observability
Bunların heç birinə yalnız “gələcəkdə böyük sistem olacaq” deyə keçmək lazım deyil.
Sistem böyüdükcə metric-lər bizə növbəti bottleneck-in harada olduğunu göstərəcək.
Və yaxşı engineering-in əsas məqsədi də əslində budur:
Sistemi əvvəlcədən lazımsız dərəcədə mürəkkəbləşdirmək yox, ehtiyac yarandıqda düzgün yeri düzgün şəkildə böyütmək.
Digər yazılara burdan baxa bilərsiniz:
https://aladdinbiyabangerd.site/az/writing
2 nəfər bu məqaləni oxuyub
Şərhlər
Şərh yazmaq üçün daxil ol. Daxil olun