Interaktivní shelka přes tunel zamrzne na několik sekund, zatímco běží kopírování souboru, a pak pokračuje, jako by se nic nestalo. Problém má jen stahování, přesto i shelka čeká, a obě se obnoví ve stejný okamžik. Tento vzorec je podpisem jednoho spolehlivého toku nesoucího mnoho konverzací a přežívá téměř každou změnu ladění, kterou lidé zkoušejí jako první.

Symptom stojí za pozorné čtení, protože ukazuje na mechanismus, ne na nastavení: pauza je sdílená, takže příčina je sdílená a sdíleným objektem je vnější spojení. Vše ostatní v logu vypadá během toho normálně.

Symptom: všechno se zastaví najednou

Dvě vnitřní spojení, která ztuhnou společně, jsou stopou. Pomalé stahování a pomalá shelka jsou oddělené TCP konverzace s oddělenými sekvenčními čísly a odděleným stavem zahlcení, takže porucha v jednom by se neměla dotknout druhého. Když se zastaví ve stejném rytmu, něco nad nimi řadí jejich bajty.

Tím něčím je transport tunelu. V režimu TCP OpenVPN zapisuje zapouzdřené pakety do jednoho TCP spojení k protějšku a smlouva TCP je doručování jednoho bajtového toku v pořadí. Pozdější bajty se aplikaci nepředají dřív než chybějící, bez ohledu na to, ke které vnitřní konverzaci patří.

Všimněte si, co symptom neříká. Neříká, že je cesta rozbitá, že je server přetížený nebo že je šifra pomalá. Ty dávají jiné tvary: rovnoměrně nízkou propustnost, časové limity nebo poruchy postihující jeden směr. Sdílená pauza, která skončí, když se jeden ztracený segment přenese znovu, je konkrétně efekt řazení.

Jeden vnější bajtový tok, mnoho vnitřních konverzací

Představte si tunel, který zároveň nese stahování a shelku. Segment vnějšího spojení se ztratí. Následující segmenty mohou dorazit na přijímající hostitel a přijímající TCP stack je potvrdí, ale nemůže je předat nahoru, dokud se mezera nevyplní. OpenVPN proto nemá pro shelku co číst, i když její vlastní bajty dorazily dávno.

To je blokování na čele fronty uvnitř jednoho spojení a nevyžaduje, aby dvě aplikace sdílely vnitřní spojení. Sdílejí to vnější, což stačí.

Efekt druhého řádu to zhoršuje. Vnitřní odesílatel, který nevidí potvrzení, může znovu odeslat data, která se vnější vrstva už snaží doručit. Toto opakované odeslání se stává dalším provozem tunelu na cestě, která právě dokázala, že může ztrácet segmenty, takže práce na obnově soutěží s obnovou, na které záleží.

Nic z toho nezaručuje zhroucení. Na čisté cestě s krátkými odezvami a štědrými frontami může být uspořádání roky zcela použitelné. Porucha se objeví, když se ztráta, zpoždění a hloubka fronty sejdou, a proto se zprávy shromažďují kolem přetížených vzestupných linek a mobilních spojení, ne kolem dobře vybavených kanceláří.

Proč delší vnitřní časovač nepomůže

Zvýšení minimálního časového limitu pro opakované odesílání na trase pomocí rto_min odkládá opakované odesílání podle časovače pro místně generovaný TCP provoz, který tuto trasu používá. Je to skutečný regulační prvek se skutečným účinkem a řeší problém druhého řádu, ne prvního.

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

Co nedokáže, je uvolnit vnější bajty mimo pořadí, obnovit chybějící segment rychleji nebo přimět vzdálený server aplikace převzít stejný časovač. Přijímající stack stále doručuje v pořadí a odesílatel na druhém konci stále používá svá vlastní měření zpětné doby.

Také nevypíná všechny ostatní mechanismy obnovy po ztrátě. Tam, kde skutečná ztráta vyžaduje obnovu podle časovače, nutí větší minimum aplikaci čekat déle, než začne jednat, což je opak toho, co potřebuje relace citlivá na latenci.

Pevná podlaha dvanácti sekund se v radách k tomuto tématu objevuje, jako by ji existence TCP tunelu předpokládala. Časovač opakovaného odesílání popsaný v RFC 6298 vychází z měřené doby odezvy s exponenciálním odstupem, takže konstantní podlaha je volba politiky pro konkrétní trasu, ne požadavek protokolu. Široce uplatněná skrývá symptom, zatímco mění obnovu pro každý tok, který trasa pokrývá.

Co tcp-nodelay dělá a co ne

Volba tunelu, která vypíná bufferování ve stylu Nagle na transportním socketu, má úzký účel: brání malým zápisům čekat na další data před odesláním. To pomáhá interaktivnímu provozu vyhnout se zbytečnému zpoždění na jinak zdravé cestě.

Nepřevádí transport na neuspořádaný a nezkracuje obnovu po ztraceném segmentu. Shelka, která se zastaví kvůli časovému limitu opakovaného odesílání, se zastaví i s touto volbou zapnutou, protože volba se nikdy nedotkla pravidla řazení.

Zaměnit obojí je snadné, protože obojí se popisuje jako oprava latence. Jedno odstraňuje umělé čekání zavedené bufferováním; druhé by vyžadovalo změnit to, co transport garantuje, což žádná volba socketu nedělá.

Jak spravedlivě porovnávat transporty

Pokud to operátor dovolí a obě služby existují, porovnejte službu UDP a službu TCP se stejnou zátěží přes stejnou přístupovou cestu ke stejnému serveru. Změna země, poskytovatele nebo generace serveru mezi oběma testy zavádí proměnnou, která bude výsledku dominovat.

Sledujte sdílenou pauzu, ne číslo propustnosti. Několik vnitřních aplikací, které ztuhnou společně během vnější ztráty, je pozorování, které identifikuje blokování na čele fronty; jedno nižší číslo rychlostního testu to nedělá.

Autorizované odchyty na rozhraní tunelu a na fyzickém rozhraní čistě oddělují obě vrstvy, protože vnitřní a vnější opakovaná odesílání patří k různým spojením s různými sekvenčními prostory. Vidět vnitřní opakovaná odesílání, zatímco vnější tok ukazuje mezeru, je přímý důkaz.

Přechod na UDP odstraňuje nadbytečný spolehlivý tok a nechává vnitřní TCP, aby si dělalo vlastní obnovu. Neslibuje nulové ztráty ani nízkou latenci a nasycená vzestupná linka, přehnaně velké fronty nebo problém s MTU budou stále potřebovat opravu. Provoz mimo tunel není nikdy držen za sekvenční mezerou tunelu, i když může trpět, když obě cesty sdílejí jedno přetížené spojení, a toto sdílené hrdlo si zaslouží vlastní vyšetřování, místo aby se vtlačilo do tohoto.

Související články