Geri qayıt
Go 1.27 HTTP/1 cavab body-lərini avtomatik təmizləyir ki, əlaqə daha sürətli yenidən işə düşsün
SiTech AI Team3 dəq oxu

Go 1.27 HTTP/1 cavab body-lərini avtomatik təmizləyir ki, əlaqə daha sürətli yenidən işə düşsün

Go 1.27 HTTP/1 əlaqələrinin yenidən istifadəsini yaxşılaşdırır və oxunmamış cavab body-lərini avtomatik təmizləyir. index.golang.org üzərindəki benchmark göstərir ki, eyni proqram Go 1.26 ilə müqayisədə təxminən beş dəfə daha sürətli işləyir.

Oxunmamış cavab body-ləri HTTP/1 əlaqəsinin yenidən istifadəsinə mane olurdu

Go-nun net/http paketi HTTP/1.0, HTTP/1.1 və HTTP/2 protokollarını dəstəyir; bunlar TCP üzərində işləyir, HTTPS ünvanlarında isə adətən TLS üzərində. Yeni əlaqə qurma bahadır: TCP həndşeyki üçün bir tam gediş-gəliş müddəti (RTT) lazımdır, TLS 1.2 həndşeyki üçün 2 RTT, və yalnız 3 RTT-dən sonra ilk HTTP sorğusu göndərilə bilər. Reqionlar arası gecikmə tez-tez 50 ms-ə çatır və ya onu aşır, buna görə də əlaqə qurma kiçik cavabın göndərilməsindən əhəmiyyətli dərəcədə bahalı ola bilər.

Buna görə HTTP müştəriləri və serverlər mövcud əlaqələri yenidən istifadə etməyə çalışırlar. HTTP/1.1-də əlaqələr susmaya görə davamlıdır, lakin cavablar eyni bayt axını üzərində ardıcıl göndərilir. Bu o deməkdir ki, net/http növbəti cavabın başlanğıcını yalnız cari body Content-Length və ya Transfer-Encoding başlığı ilə müəyyən edilən yerdən sonra qədər oxunanda tapacaq.

Go-nun bloq yazısında Nicolas Hussin və Demien Nili tez-tez rast gəlinən bir səhvi qeyd edirlər: funksiya http.Get-i çağırır, defer ilə resp.Body.Close icra edir və yalnız status kodunu qaytarır, body isə ümumiyyətlə oxunmur. Go 1.26-dan başlayaraq, əgər Close zamanı body oxunmamış qalarsa, net/http əlaqəni ləğv edir və növbəti sorğu üçün yeni birini açaraq yenidən qurulma xərclərini ödəyir. Problem body-ni oxuyan, lakin sonuna qədər az qalan baytları oxumayan proqramları da əhatə edir. Məsələn, encoding/json.Decoder JSON obyektini bağlayan aşırı hərfə kəsir, buna görə server cavabı newline ilə bitirsə, həmin baytı oxunmamış saxlayır və əlaqə yenidən istifadə edilə bilməz. HTTP/2-də bu problem yoxdur, çünki freymləri bir əlaqədə multipleksləşdirir və cavabları ciddi şəkildə ardıcıl göndərmir.

Go 1.27 body-ləri avtomatik təmizləyir

Go 1.27-dən etibarən net/http.Transport bunu avtomatik həll edir. Oxunmamış HTTP/1 cavab body-sini asinxron şəkildə 50 millisaniyəyə və ya 256 kilobayta qədər təmizləyir — hansı həddən əvvəl çatarsa, o qədər. Əgər təmizləmə növbəti sorğunun göndərilməsinə qədər bitərsə, əlaqə yenidən istifadə olunur; əks halda yeni əlaqə yaradılır, köhni isə işləməyən əlaqələr hovuzuna düşür və gələcək sorğu üçün yenidən işə düşə bilər. Tətbiq cavabda Connection: close başlığı olduqda təmizləmədən ümumiyyətlə imtina edir, çünki bu halda təmizləmə boş əmək olardı.

Müəlliflər qeyd edirlər ki, bu davranış Go-nun gələcək versiyalarında dəyişə bilər, əgər başqa potensial yaxşılaşdırmalar açıqırsa.

Benchmark nəticələri və tövsiyə

Yaxşılaşdırma əhəmiyyətlidir. index.golang.org üzərində TLS 1.3 dəstəkləyən dünya üzrə paylanmış sayta sadə status yoxlama funksiyasını 100 dəfə çağırılan test proqramı Go 1.26-da təxminən 710 millisaniyə sərf edir, Go 1.27-də isə yalnız təxminən 150 millisaniyə — demək ki, təxminən beş dəfə daha sürətli.

Yeni davranışı ilə Go komandası geliştiricilərə HTTP cavab body-lərini artıq lazım olmadıqca tanıdığı defer resp.Body.Close() şablonu ilə bağlamalarını tövsiyə edir. Uzun illər ərzində çox geliştiricinin istifadə etdiyi əl ilə yazılmış body təmizləmə üsulları — məsələn, body-lərin io.Copy ilə təmizlənməsi, təmizlənmiş baytların məhdudlaşdırılması və ya təmizləmənin timeout ilə yarışdırılması — artıq lazım deyil. Müəlliflər bunu Go-nun sadəlik fəlsəfəsinin hissəsi kimi təqdim edir: kod təzə və sadə qalsın, mürəkkəb hissə isə net/http sizin əvəziniz həll etsin.

Mənbələr: Hacker News

SSiTech

SiTech — AI ilə gücləndirilmiş veb hazırlanması

Sürətli və müasir saytlar qurur, AI-ı real biznes proseslərinə gətiririk. Layihəniz və ya sualınız var? Kömək etməyə hazırıq.