Giriş
Java SE biliklərini möhkəmləndirdikdən sonra backend dünyasına Servlet və ardından Spring/Spring Boot ilə addımlamaq çox məntiqli bir yoldur.
Servlet API-sini və Jetty kimi Servlet Konteynerlərinin iş prinsipini başa düşmək, Spring Boot-un bəzən "sehrli" görünən bir çox davranışının arxasındakı təməlləri qavramağa kömək edəcək.
Bu məqalədə, bir backend developer olaraq arxa planda baş verən proseslərə fokuslanacağıq.
Əsas Anlayışlar: Servlet və Servlet Konteyneri
Servlet
- HTTP protokolu üzərindən gələn istəklərə (requests) cavab (response) vermək üçün dizayn edilmiş bir Java sinfidir.
- Dinamik veb məzmun yaratmaq üçün istifadə olunur.
javax.servlet.Servlet
interfeysini və yajavax.servlet.http.HttpServlet
abstrakt sinfini implementasiya edir.
Servlet Konteyneri (Web Konteyner/Web Server)
- Servletlərin həyat dövrünü (lifecycle) idarə edən proqram təminatıdır.
- HTTP istəklərini qəbul edib müvafiq Servlet-ə yönləndirir.
- Şəbəkə əlaqəsi, thread idarəçiliyi və digər aşağı səviyyəli işləri həll edir.
- Jetty, Tomcat, Undertow kimi nümunələr var. Spring Boot default olaraq Tomcat ilə gəlir, lakin Jetty və Undertow da konfiqurasiya edilə bilər.
Jetty
Jetty, Eclipse Foundation tərəfindən hazırlanmış açıq mənbəli bir veb server və Servlet konteyneridir.
Xüsusilə daxili sistemlər və mikroservis arxitekturalarında populyardır:
- Yüngül və sürətli: Aşağı yaddaş istifadəsi və sürətli start-up.
- Embeddable: Java tətbiqinə daxil edilə bilər (
main()
metodu ilə başlatmaq olar). - Çevik və genişləndiriləbilən: Modulları istəyə görə əlavə/sil.
- Asinxron dəstəyi: Servlet 3.0+, WebSocket, NIO dəstəyi mövcuddur.
Request/Response Axışı
Listening
- Jetty başladıqda konfiqurasiya olunmuş portu (məs: 8080) dinləməyə başlayır.
ServerConnector
komponenti TCP soketini açır.
Connection Acceptance
- Klient bağlantı istəyir →
ServerConnector
bağlantını qəbul edir.
Thread Allocation
- Jetty Thread Pool (məs:
QueuedThreadPool
) istifadə edir. - İstək üçün boş bir thread təyin edilir və iş bitdikdən sonra geri qaytarılır.
Data Reading & HTTP Parsing
- TCP soketindən xam HTTP məlumatı oxunur.
- Jetty-nin HTTP Parser komponenti bu məlumatı
method
,URL
,headers
,body
kimi hissələrə ayırır.
Request və Response Obyektləri
- Jetty
HttpServletRequest
vəHttpServletResponse
obyektlərini yaradır. request
→ istək haqqında bütün məlumatresponse
→ cavabın qurulması üçün istifadə olunur
Handler Chain & Routing
Jetty-də gələn istəklər Handler zəncirindən keçir:
ServletContextHandler
və yaWebAppContext
→ URL ilə Servlet-i eşləşdirir.
Eşləşdirmə aşağıdakı yollarla təyin edilə bilər:
web.xml
– XML faylı ilə klassik konfiqurasiya- Annotations –
@WebServlet("/path")
şəklində annotasiyalar
Servlet Lifecycle – init()
- Servlet ilk dəfə çağırıldıqda:
- Yüklənir və obyekti yaradılır.
init(ServletConfig)
metodu yalnız bir dəfə çağırılır.- Servlet-ə konfiqurasiya və
ServletContext
ötürülür.
İstəyin emalı – service()
- Jetty
service(request, response)
metodunu çağırır.
Əgər HttpServlet
sinfi istifadə edilirsə:
service()
→ HTTP metoduna uyğun olaraqdoGet()
,doPost()
,doPut()
və s. metodları çağırır.
Tipik doGet()
və ya doPost()
məntiqi
request.getParameter()
,getHeader()
,getInputStream()
ilə məlumatları alırsan.- İş məntiqi icra olunur (DB sorğusu, API çağırışı və s.).
response
obyektinə:setStatus()
setContentType()
setHeader()
getWriter().println()
ilə cavab yazılır.
Response Commit & Sending
- Servlet
service()
metodunu bitirdikdə:- Jetty
response
dakı məlumatları HTTP formatında klientə göndərir. - Commit baş verdikdə header-lar göndərilir və dəyişdirilə bilməz.
- Jetty
Thread Release
- Thread hovuzuna geri qaytarılır və növbəti istək üçün hazır olur.
Connection Close / Keep-Alive
Connection: keep-alive
varsa, bağlantı saxlanılır.- Əks halda, TCP bağlantısı bağlanır.
Jetty-nin Thread Modeli: Paralel İşləmə
Thread Hovuzu (Thread Pool)
- Jetty performans üçün
QueuedThreadPool
istifadə edir.
Məqsəd
- Hər istək üçün yeni thread yaratmaq əvəzinə, mövcud threadlər təkrar istifadə olunur.
İşləmə Prinsipi
- İstək gəldikdə hovuzdan thread götürülür.
- İş tamamlandıqdan sonra geri qaytarılır.
- Bütün threadlər məşğuldursa, istəklər queueya düşür.
Potensial Problem: Pool Exhaustion
- Uzun sürən çox sayda istək zamanı:
- Thread-lər dolur
- Növbə böyüyür
- Gecikmələr yaranır
➡️ Həll: Hovuz ölçüsünü konfiqurasiya etmək mümkündür.