Interaktyvus apvalkalas per tunelį trumpam sustingsta kelioms sekundėms, kol vyksta failo kopijavimas, o paskui tęsia taip, lyg nieko nebūtų nutikę. Problema yra tik atsisiuntime, tačiau ir apvalkalas laukia, ir abu atsigauna tuo pačiu metu. Šis modelis yra vieno patikimo srauto, nešančio daug pokalbių, parašas, ir jis išgyvena beveik kiekvieną derinimą, kurį žmonės išbando pirmiausia.

Simptomą verta skaityti atidžiai, nes jis nurodo mechanizmą, o ne nuostatą: pauzė yra bendra, todėl priežastis bendra, o bendras objektas yra išorinis ryšys. Visa kita žurnale tuo metu atrodo normaliai.

Simptomas: viskas sustoja vienu metu

Du vidiniai ryšiai, užstringantys kartu, yra užuomina. Lėtas atsisiuntimas ir lėtas apvalkalas yra atskiri TCP pokalbiai su atskirais sekos numeriais ir atskira perkrovos būsena, todėl vieno gedimas neturėtų liesti kito. Kai jie sustoja tuo pačiu ritmu, kažkas virš jų tvarko jų baitus.

Tas kažkas yra tunelio transporto sluoksnis. TCP režimu OpenVPN įrašo inkapsuliuotus paketus į vieną TCP ryšį partneriui, o TCP sutartis yra vieno baitų srauto pristatymas iš eilės. Vėlesni baitai neperduodami programai prieš trūkstamus, nesvarbu, kuriam vidiniam pokalbiui jie priklauso.

Atkreipkite dėmesį, ko simptomas nesako. Jis nesako, kad kelias sugedęs, kad serveris perkrautas ar kad šifravimas lėtas. Jie duoda kitas formas: tolygiai mažą pralaidumą, laiko limitus ar gedimus, paliečiančius vieną kryptį. Bendra pauzė, kuri baigiasi prarastą segmentą persiuntus, yra būtent tvarkos efektas.

Vienas išorinis baitų srautas, daug vidinių pokalbių

Įsivaizduokite tunelį, nešantį atsisiuntimą ir apvalkalą tuo pačiu metu. Vienas išorinio ryšio segmentas prarandamas. Kiti segmentai gali pasiekti priimantįjį mazgą, ir priimantis TCP stekas juos patvirtins, bet negalės perduoti aukščiau, kol spraga nebus užpildyta. Todėl OpenVPN neturi ko skaityti apvalkalui, nors paties apvalkalo baitai atkeliavo seniai.

Tai yra blokavimas eilės priekyje viename ryšyje, ir jam nereikia, kad dvi programos dalytųsi vidiniu ryšiu. Jos dalijasi išoriniu, ir to pakanka.

Antros eilės efektas tai blogina. Vidinis siuntėjas, nematantis patvirtinimų, gali persiųsti duomenis, kuriuos išorinis sluoksnis jau bando pristatyti. Tas persiuntimas tampa papildomu tunelio srautu kelyje, kuris ką tik įrodė galįs prarasti segmentus, todėl atkūrimo darbas konkuruoja su svarbiu atkūrimu.

Niekas iš to negarantuoja žlugimo. Švariame kelyje su trumpais kelionės pirmyn ir atgal laikais bei plačiomis eilėmis ši tvarka gali būti visiškai tinkama daugelį metų. Gedimas pasirodo, kai nuostoliai, vėlavimas ir eilės gylis sutampa, todėl ataskaitos telkiasi apie perkrautas išsiuntimo linijas ir mobiliuosius ryšius, o ne apie gerai aprūpintus biurus.

Kodėl ilgesnis vidinis laikmatis negali padėti

Mažiausio persiuntimo laiko padidinimas maršrute su rto_min atideda laikmačiu grindžiamą persiuntimą vietoje sukuriamam TCP srautui, kuris naudoja tą maršrutą. Tai tikra rankenėlė su tikru poveikiu, ir ji sprendžia antros eilės problemą, o ne pirmąją.

ip route show
ip route show cache 2>/dev/null | head
ss -tin dst 10.70.0.1

Ko ji negali: išlaisvinti išorinių baitų ne iš eilės, greičiau atkurti trūkstamą segmentą ar priversti nuotolinį programos serverį priimti tą patį laikmatį. Priimantis stekas vis tiek pristato iš eilės, o tolimojo galo siuntėjas vis tiek naudoja savo paties kelionės pirmyn ir atgal matavimus.

Ji taip pat neišjungia visų kitų nuostolių atkūrimo mechanizmų. Kai tikras nuostolis reikalauja laikmačiu grindžiamo atkūrimo, didesnis minimumas priverčia programą ilgiau laukti prieš veikiant, o tai priešingai nei reikia delsai jautriai sesijai.

Fiksuota dvylikos sekundžių apatinė riba pasirodo šios temos patarimuose tarsi TCP tunelio egzistavimas ją numatytų. RFC 6298 aprašytas persiuntimo laikmatis išvedamas iš išmatuoto kelionės pirmyn ir atgal laiko su eksponentiniu atsitraukimu, todėl pastovi apatinė riba yra konkretaus maršruto politikos pasirinkimas, o ne protokolo reikalavimas. Taikoma plačiai, ji slepia simptomą ir kartu keičia atkūrimą kiekvienam srautui, kurį tas maršrutas apima.

Ką daro ir ko nedaro tcp-nodelay

Tunelio parinktis, išjungianti Nagle stiliaus buferiavimą transporto lizde, turi siaurą tikslą: neleidžia mažiems įrašams laukti daugiau duomenų prieš siunčiant. Tai padeda interaktyviam srautui išvengti papildomo vėlavimo kitaip sveikame kelyje.

Ji nepadaro transporto netvarkingu ir nesutrumpina atkūrimo po prarasto segmento. Apvalkalas, sustojantis dėl persiuntimo laiko limito, sustos ir su įjungta parinktimi, nes parinktis niekada nelietė tvarkos taisyklės.

Sumaišyti abu lengva, nes abu aprašomi kaip delsos pataisos. Viena pašalina buferiavimo įvestą dirbtinį laukimą, kita reikalautų pakeisti tai, ką transportas garantuoja, o to nepadaro jokia lizdo parinktis.

Kaip sąžiningai palyginti transportus

Jei operatorius leidžia ir abi paslaugos egzistuoja, palyginkite UDP paslaugą ir TCP paslaugą, nešančias tą patį darbo krūvį tuo pačiu prieigos keliu į tą patį serverį. Šalies, tiekėjo ar serverio kartos pakeitimas tarp dviejų testų įveda kintamąjį, kuris dominuos rezultatui.

Stebėkite bendrą pauzę, o ne pralaidumo skaičių. Kelių vidinių programų užstrigimas kartu per išorinį nuostolį yra stebėjimas, atpažįstantis blokavimą eilės priekyje; vienas mažesnis greičio testo skaičius to nepadaro.

Leisti užfiksavimai tunelio sąsajoje ir fizinėje sąsajoje švariai atskiria du sluoksnius, nes vidiniai ir išoriniai persiuntimai priklauso skirtingiems ryšiams su skirtingomis sekos erdvėmis. Matyti vidinius persiuntimus, kol išorinis srautas rodo spragą, yra tiesioginis įrodymas.

Perėjimas prie UDP pašalina papildomą patikimą srautą ir palieka vidiniam TCP pačiam atlikti atkūrimą. Jis nežada nulinių nuostolių ar mažos delsos, o prisotinta išsiuntimo linija, per didelės eilės ar MTU problema vis tiek turės būti taisomi. Srautas už tunelio niekada nelaikomas už tunelio sekos spragos, nors jis vis tiek gali nukentėti, kai abu keliai dalijasi viena perkrauta linija, ir ta bendra kliūtis nusipelno atskiro tyrimo, o ne sulenkimo į šį.

Susiję straipsniai