Թունելի վրայով աշխատող ինտերակտիվ shell-ը մի քանի վայրկյան սառչում է ֆայլի պատճենման ընթացքում, ապա շարունակում է այնպես, կարծես ոչինչ չի եղել։ Խնդիրը միայն ներբեռնման մեջ է, սակայն shell-ը նույնպես սպասում է, և երկուսն էլ վերականգնվում են նույն պահին։ Այդ օրինաչափությունը մեկ վստահելի հոսքի ստորագրությունն է, որը կրում է բազմաթիվ զրույցներ, և այն դիմանում է գրեթե բոլոր այն կարգաբերումներին, որոնք մարդիկ առաջինն են փորձում։

Ախտանիշն արժե ուշադիր կարդալ, որովհետև այն մատնանշում է մեխանիզմ, ոչ թե կարգավորում. դադարը համատեղ է, ուրեմն պատճառը համատեղ է, և համատեղ օբյեկտը արտաքին կապն է։ Այդ ընթացքում մատյանի մնացած մասը նորմալ է թվում։

Ախտանիշը. ամեն ինչ դադարում է միաժամանակ

Երկու ներքին կապերի միասին կանգնելը հենց ակնարկն է։ Դանդաղ ներբեռնումը և դանդաղ shell-ը առանձին TCP զրույցներ են՝ առանձին հաջորդականության համարներով և առանձին գերբեռնվածության վիճակով, ուստի մեկի խափանումը չպետք է դիպչի մյուսին։ Երբ նրանք կանգնում են նույն ռիթմով, նրանցից վերև ինչ-որ բան դասավորում է նրանց բայթերը։

Այդ ինչ-որ բանը թունելի տրանսպորտային շերտն է։ TCP ռեժիմում OpenVPN-ը փաթեթավորած փաթեթները գրում է մեկ TCP կապի մեջ դեպի զուգընկերը, իսկ TCP-ի պայմանագիրը մեկ բայթային հոսքի հերթական հանձնումն է։ Հետագա բայթերը չեն հանձնվում հավելվածին բացակայողներից առաջ, անկախ նրանից, թե որ ներքին զրույցին են պատկանում։

Ուշադրություն դարձրեք, թե ախտանիշը ինչ չի ասում։ Այն չի ասում, որ ուղին կոտրված է, սերվերը ծանրաբեռնված է, կամ գաղտնագրումը դանդաղ է։ Դրանք այլ ձևեր են տալիս՝ հավասարաչափ ցածր թողունակություն, ժամկետանցումներ կամ մեկ ուղղության վրա ազդող խափանումներ։ Համատեղ դադարը, որն ավարտվում է կորած սեգմենտի վերահաղորդմամբ, հենց հերթականության ազդեցություն է։

Մեկ արտաքին բայթային հոսք, բազմաթիվ ներքին զրույցներ

Պատկերացրեք թունելը, որը միաժամանակ կրում է ներբեռնում և shell։ Արտաքին կապի մեկ սեգմենտ կորչում է։ Հաջորդ սեգմենտները կարող են հասնել ընդունող հոսթին, և ընդունող TCP կույտը կհաստատի դրանք, բայց չի կարող դրանք վերև հանձնել, քանի դեռ բացը լցված չէ։ Ուստի OpenVPN-ը shell-ի համար կարդալու ոչինչ չունի, թեև shell-ի սեփական բայթերը վաղուց են հասել։

Սա հերթի գլխի արգելափակումն է մեկ կապի ներսում, և այն չի պահանջում, որ երկու հավելվածները կիսեն ներքին կապը։ Նրանք կիսում են արտաքինը, և դա բավական է։

Երկրորդ կարգի ազդեցությունը վատթարացնում է այն։ Ներքին ուղարկողը, որը հաստատումներ չի տեսնում, կարող է կրկին ուղարկել տվյալներ, որոնք արտաքին շերտն արդեն փորձում է հանձնել։ Այդ վերահաղորդումը դառնում է լրացուցիչ թունելային երթևեկություն մի ուղու վրա, որն հենց նոր ապացուցեց, որ կարող է կորցնել սեգմենտներ, ուստի վերականգնման աշխատանքը մրցում է կարևոր վերականգնման հետ։

Այս ամենից ոչինչ չի երաշխավորում փլուզում։ Մաքուր ուղու վրա՝ կարճ շրջադարձային ժամանակներով և լայն հերթերով, այս դասավորությունը կարող է տարիներով լիովին պիտանի լինել։ Խափանումը ի հայտ է գալիս, երբ կորուստը, ուշացումը և հերթի խորությունը միասին համընկնում են, և դրա համար էլ հաշվետվությունները կուտակվում են գերբեռնված վերին ուղիների և բջջային կապերի շուրջ, այլ ոչ թե լավ սարքավորված գրասենյակների։

Ինչու ավելի երկար ներքին ժամաչափը չի կարող օգնել

Ուղու վրա rto_min-ով վերահաղորդման նվազագույն ժամկետի բարձրացումը հետաձգում է ժամաչափային վերահաղորդումը տեղական արտադրված TCP երթևեկության համար, որն օգտագործում է այդ ուղին։ Դա իսկական բռնակ է իսկական ազդեցությամբ, և այն լուծում է երկրորդ կարգի խնդիրը, ոչ թե առաջինը։

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

Ինչ չի կարող անել՝ արտաքին բայթերը հերթականությունից դուրս բաց թողնել, բացակայող սեգմենտն ավելի արագ վերականգնել, կամ հեռավոր հավելվածի սերվերին ստիպել ընդունել նույն ժամաչափը։ Ընդունող կույտը դեռ հերթականությամբ է հանձնում, և հեռավոր ծայրի ուղարկողը դեռ օգտագործում է իր սեփական շրջադարձային չափումները։

Այն նաև չի անջատում կորստի վերականգնման մյուս բոլոր մեխանիզմները։ Այնտեղ, որտեղ իրական կորուստը պահանջում է ժամաչափային վերականգնում, ավելի մեծ նվազագույնը ստիպում է հավելվածին ավելի երկար սպասել նախքան գործելը, ինչը հակառակն է այն բանի, ինչ պետք է ուշացման նկատմամբ զգայուն սեսիային։

Տասներկու վայրկյանի ֆիքսված հատակը հայտնվում է այս թեմայի խորհուրդներում, կարծես TCP թունելի գոյությունը դա ենթադրում է։ RFC 6298-ում նկարագրված վերահաղորդման ժամաչափը բխում է չափված շրջադարձային ժամանակից՝ էքսպոնենցիալ հետընթացով, ուստի հաստատուն հատակը կոնկրետ ուղու համար քաղաքականության ընտրություն է և ոչ թե արձանագրության պահանջ։ Լայնորեն կիրառելիս այն թաքցնում է ախտանիշը և միաժամանակ փոխում է վերականգնումը յուրաքանչյուր հոսքի համար, որն այդ ուղին ընդգրկում է։

Ինչ է անում և ինչ չի անում tcp-nodelay-ը

Թունելի այն ընտրանքը, որը անջատում է Nagle-ի ոճի բուֆերացումը տրանսպորտային սոկետի վրա, նեղ նպատակ ունի. այն թույլ չի տալիս փոքր գրառումներին սպասել ավելի շատ տվյալների նախքան ուղարկելը։ Դա օգնում է ինտերակտիվ երթևեկությանը խուսափել լրացուցիչ ուշացումից այլապես առողջ ուղու վրա։

Այն տրանսպորտը չի դարձնում անկարգ և չի կրճատում կորած սեգմենտից հետո վերականգնումը։ Shell-ը, որը դադարում է վերահաղորդման ժամկետի պատճառով, կդադարի նաև այդ ընտրանքը միացված վիճակում, որովհետև ընտրանքը երբեք չի դիպել հերթականության կանոնին։

Երկուսը շփոթելը հեշտ է, որովհետև երկուսն էլ նկարագրվում են որպես ուշացման ուղղում։ Մեկը հեռացնում է բուֆերացման մտցրած արհեստական սպասումը, մյուսը կպահանջեր փոխել այն, ինչ տրանսպորտը երաշխավորում է, և դա ոչ մի սոկետի ընտրանք չի անում։

Ինչպես արդարացիորեն համեմատել տրանսպորտները

Եթե օպերատորը թույլ է տալիս և երկու ծառայություններն էլ կան, համեմատեք UDP ծառայությունը և TCP ծառայությունը, որոնք կրում են նույն ծանրաբեռնվածությունը նույն սերվերի նույն մուտքի ուղու վրա։ Երկու թեստերի միջև երկիրը, մատակարարը կամ սերվերի սերունդը փոխելը մտցնում է փոփոխական, որը կտիրի արդյունքին։

Հետևեք համատեղ դադարին, ոչ թե թողունակության թվին։ Մի քանի ներքին հավելվածների միասին կանգնելը արտաքին կորստի ընթացքում հենց այն դիտարկումն է, որն առանձնացնում է հերթի գլխի արգելափակումը; արագության թեստի մեկ ցածր թիվը դա չի անում։

Թույլատրված որսումները թունելի ինտերֆեյսի և ֆիզիկական ինտերֆեյսի վրա մաքուր բաժանում են երկու շերտերը, որովհետև ներքին և արտաքին վերահաղորդումները պատկանում են տարբեր հաջորդականության տարածություններ ունեցող տարբեր կապերի։ Ներքին վերահաղորդումներ տեսնելը, մինչ արտաքին հոսքը բաց է ցույց տալիս, ուղիղ ապացույց է։

UDP-ին անցնելը հեռացնում է լրացուցիչ վստահելի հոսքը և թողնում է ներքին TCP-ին անել իր սեփական վերականգնումը։ Այն չի խոստանում զրո կորուստ կամ ցածր ուշացում, և հագեցած վերին ուղին, չափից մեծ հերթերը կամ MTU-ի խնդիրը դեռ պետք է շտկվեն։ Թունելից դուրս երթևեկությունը երբեք չի պահվում թունելի հերթականության բացի հետևում, թեև այն դեռ կարող է տուժել, երբ երկու ուղիները կիսում են մեկ գերբեռնված կապ, և այդ համատեղ խցանումն արժանի է իր սեփական հետաքննությանը, փոխանակ այստեղ ծալվելու։

Առնչվող հոդվածներ