Затрымкі OpenVPN праз TCP: rto_min не выпраўляе блакаванне на чале чаргі
Знешні байтавы паток дастаўляецца ў парадку, таму адзін страчаны сегмент можа спыніць кожны ўнутраны паток. Даўжэйшы ўнутраны таймер мяняе гадзіннік, а не гэтае абмежаванне.
Інтэрактыўная абалонка праз тунель замірае на некалькі секунд, пакуль ідзе капіраванне файла, а потым працягвае працу, нібыта нічога не было. Праблема ёсць толькі ў загрузцы, але абалонка таксама чакае, і абедзве аднаўляюцца ў адзін і той жа момант. Гэты ўзор — подпіс аднаго надзейнага патоку, які нясе мноства размоў, і ён перажывае амаль кожнае змяненне налад, якое людзі спрабуюць перш за ўсё.
Сімптом варта чытаць уважліва, бо ён указвае на механізм, а не на наладу: пауза агульная, значыць прычына агульная, а агульны аб’ект — знешняе злучэнне. Усё астатняе ў журнале выглядае нармальна, пакуль гэта адбываецца.
Сімптом: усё замірае адначасова
Дзве ўнутраныя сувязі, што гразнуць разам, — гэта падказка. Павольная загрузка і павольная абалонка — асобныя размовы TCP з асобнымі нумарамі паслядоўнасці і асобным станам перагрузкі, таму збой у адной не павінен закранаць другую. Калі яны спыняюцца ў нагу, нешта над імі ўпарадкоўвае іх байты.
Гэта нешта — транспарт тунеля. У рэжыме TCP OpenVPN запісвае інкапсуляваныя пакеты ў адно TCP-злучэнне з партнёрам, а кантракт TCP — дастаўка ў парадку аднаго байтавага патоку. Наступныя байты не перадаюцца прыкладанню раней за страчаныя, незалежна ад таго, да якой унутранай размовы яны належаць.
Звярніце ўвагу, пра што сімптом не кажа. Ён не кажа, што шлях зламаны, што сервер перагружаны або што шыфр павольны. Гэтыя рэчы даюць іншыя формы: раўнамерна нізкую прапускную здольнасць, тайм-аўты або збоі, што закранаюць адзін кірунак. Агульная пауза, якая сканчаецца, калі страчаны сегмент перадаецца паўторна, — гэта менавіта эфект парадкавання.
Адзін знешні байтавы паток, мноства ўнутраных размоў
Уявіце, што тунель адначасова нясе загрузку і абалонку. Сегмент знешняга злучэння губляецца. Наступныя сегменты могуць дайсці да прымаючага вузла, і прымаючы стек TCP іх пацвердзіць, але ён не можа перадаць іх вышэй, пакуль прабел не будзе запоўнены. Таму OpenVPN не мае чаго чытаць для абалонкі, хоць уласныя байты абалонкі дайшлі даўно.
Гэта блакаванне на чале чаргі ўнутры аднаго злучэння, і яно не патрабуе, каб дзве праграмы дзялілі ўнутранае злучэнне. Яны дзеляць знешняе, і гэтага дастаткова.
Эфект другога парадку пагаршае сітуацыю. Унутраны адпраўнік, які не бачыць пацверджання, можа паўторна перадаць даныя, якія знешні ўзровень ужо спрабуе даставіць. Гэтая паўторная перадача становіцца дадатковым трафікам тунеля на шляху, які толькі што даказаў, што можа губляць сегменты, таму праца па аднаўленні канкуруе з тым аднаўленнем, якое мае значэнне.
Нішто з гэтага не гарантуе краху. На чыстым шляху з кароткімі кругавымі затрымкамі і шчодрымі чэргамі такая схема можа цалкам працаваць гадамі. Збой з’яўляецца, калі страты, затрымка і глыбіня чаргі супадаюць, таму паведамленні групаваюцца вакол перагружаных каналаў сувязі і мабільных каналаў, а не вакол добра забяспечаных офісаў.
Чаму даўжэйшы ўнутраны таймер не дапаможа
Павышэнне мінімальнага тайм-аўту паўторнай перадачы на маршруце з дапамогай 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 на транспартным сокеце, мае вузкую мэту: яна не дае дробным запісам чакаць больш даных перад адпраўкай. Гэта дапамагае інтэрактыўнаму трафіку пазбегнуць дадатковай затрымкі на ў іншым здаровым шляху.
Яна не робіць транспарт неўпарадкаваным і не скарачае аднаўленне пасля страчанага сегмента. Абалонка, якая спыняецца на тайм-аўт паўторнай перадачы, усё роўна спыніцца пры ўключанай опцыі, бо опцыя ніколі не кранала правіла парадкавання.
Блытаць гэтыя дзве рэчы лёгка, бо абедзве апісваюць як выпраўленне затрымкі. Адна прыбірае штучнае чаканне, унесенае буферызацыяй; другая патрабавала б змяніць тое, што гарантуе транспарт, а гэтага не робіць ні адная опцыя сокета.
Як сумленна параўноўваць транспарты
Калі аператар дазваляе і абедзве паслугі існуюць, параўнайце службу UDP і службу TCP з аднолькавай нагрузкай праз адзін і той жа шлях доступа да таго ж сервера. Змена краіны, правайдэра або пакалення сервера паміж двума тэстамі ўводзіць зменную, якая будзе дамінаваць у выніку.
Сачыце за агульнай паўзай, а не за лікам прапускной здольнасці. Некалькі ўнутраных праграм, што гразнуць разам падчас знешняй страты, — гэта назіранне, якое вызначае блакаванне на чале чаргі; адзін меншы лік тэсту хуткасці гэтага не робіць.
Дазволеныя запісы на інтэрфейсе тунеля і на фізічным інтэрфейсе чыста раздзяляюць два ўзроўні, бо ўнутраныя і знешнія паўторныя перадачы належаць розным злучэнням з рознымі прасторамі паслядоўнасцей. Бачыць унутраныя паўторныя перадачы, пакуль знешні паток паказвае прабел, — гэта прамое доказам.
Пераход на UDP прыбірае лішні надзейны паток і пакідае ўнутранаму TCP рабіць уласнае аднаўленне. Ён не абяцае нулявых страт або нізкай затрымкі, і насычаны канал сувязі, завялікія чэргі або праблема MTU ўсё яшчэ спатрэбяцца ў выпраўленні. Трафік па-за тунелем ніколі не ўтрымліваецца за прабелам паслядоўнасці тунеля, хаця ён можа пакутаваць, калі абодва шляхі дзеляць адзін перагружаны канал, і гэтае агульнае вузкае месца заслугоўвае асобнага даследавання, а не згортвання ў гэтае.