OpenVPN TCP-n: az rto_min nem oldja meg a sor eleji blokkolást
A külső bájtfolyam sorrendben szállít, ezért egyetlen hiányzó szegmens is megállíthat minden belső folyamot. A hosszabb belső időzítő az órát változtatja, nem ezt a korlátot.
A tunnelen át futó interaktív shell több másodpercre lefagy, miközben fájlmásolás fut, majd úgy folytatódik, mintha mi sem történt volna. Csak a letöltésnek van problémája, mégis a shell is vár, és mindkettő ugyanabban a pillanatban áll helyre. Ez a minta egyetlen megbízható folyam jellemzője, amely sok beszélgetést szállít, és túléli szinte minden hangolási változtatást, amit az emberek először kipróbálnak.
Érdemes figyelmesen olvasni a tünetet, mert mechanizmusra mutat, nem beállításra: a szünet közös, tehát az ok közös, és a közös objektum a külső kapcsolat. Minde közben a napló többi része normálisnak látszik.
A tünet: minden egyszerre áll meg
Két belső kapcsolat, amely együtt akad el, a nyom. A lassú letöltés és a lassú shell külön TCP-beszélgetés külön sorszámokkal és külön torlódási állapottal, ezért az egyik hibája nem érintheti a másikat. Amikor egyszerre tartanak szünetet, valami felettük rendezi a bájtjaikat.
Az a valami a tunel átvitele. TCP módban az OpenVPN a beágyazott csomagokat egyetlen TCP-kapcsolatba írja a peer felé, a TCP szerződése pedig egyetlen bájtfolyam sorrendben történő kézbesítése. A későbbi bájtokat nem adják át az alkalmazásnak a hiányzók előtt, akármelyik belső beszélgetéshez tartoznak.
Figyeljük meg, mit nem mond a tünet. Nem mondja, hogy az útvonal törött, hogy a szerver túlterhelt, vagy hogy a titkosítás lassú. Ezek más formákat adnak: egyenletesen alacsony átbocsátást, időtúllépéseket vagy egy irányt érintő hibákat. Az a közös szünet, amely egy elveszett szegmens újraküldésével ér véget, kifejezetten sorrendezési hatás.
Egy külső bájtfolyam, sok belső beszélgetés
Képzeljük el, hogy a tunel egyszerre visz egy letöltést és egy shellt. A külső kapcsolat egyik szegmense elveszik. A következő szegmensek megérkezhetnek a fogadó hoszthoz, és a fogadó TCP-verem nyugtázza őket, de addig nem tudja feljebb adni, amíg a rés be nem töltődik. Ezért az OpenVPN-nek nincs mit olvasnia a shellhez, pedig a shell saját bájtjai régen megérkeztek.
Ez a kapcsolaton belüli sor eleji blokkolás, és nem igényli, hogy a két alkalmazás belső kapcsolatot osszon meg. A külsőt osztják meg, és ez elég.
A másodrendű hatás rontja a helyzetet. Egy belső küldő, amely nem lát nyugtát, újraküldhet olyan adatot, amelyet a külső réteg már próbál kézbesíteni. Ez az újraküldés további tunelforgalommá válik egy olyan útvonalon, amely épp most bizonyította, hogy veszíthet szegmenseket, így a helyreállítási munka versenyez a fontos helyreállítással.
Mindebből semmi nem garantál összeomlást. Tiszta útvonalon, rövid oda-vissza időkkel és bő sorokkal a felállás évekig teljesen használható lehet. A hiba akkor jelenik meg, amikor a veszteség, a késleltetés és a sor mélysége együtt áll fenn, ezért a jelentések a torlódott feltöltő linkek és mobil kapcsolatok köré csoportosulnak, nem a jól ellátott irodák köré.
Miért nem segíthet a hosszabb belső időzítő
Egy útvonalon az rto_min használatával a legkisebb újraküldési időtúllépés növelése elhalasztja az időzítőalapú újraküldést a helyben termelt, azt az útvonalat használó TCP-forgalom számára. Ez valódi csavar valódi hatással, és a másodrendű problémát kezeli az első helyett.
ip route show
ip route show cache 2>/dev/null | head
ss -tin dst 10.70.0.1
Amit nem tud: renden kívül engedni a külső bájtokat, gyorsabban helyreállítani a hiányzó szegmenst, vagy rábírni a távoli alkalmazásszervert ugyanarra az időzítőre. A fogadó verem továbbra is sorrendben kézbesít, és a túlsó végi küldő továbbra is a saját oda-vissza méréseit használja.
Nem kapcsol ki minden más veszteség-helyreállítási mechanizmust sem. Ahol a valódi veszteség időzítőalapú helyreállítást igényel, a nagyobb minimum hosszabb várakozásra készteti az alkalmazást, ami az ellentéte annak, amire egy késleltetésre érzékeny munkamenetnek szüksége van.
Egy fix tizenkét másodperces alsó korlát úgy jelenik meg a témáról szóló tanácsokban, mintha egy TCP-tunel létezése ezt implikálná. Az RFC 6298-ban leírt újraküldési időzítő a mért oda-vissza időből származik exponenciális visszalépéssel, ezért az állandó alsó korlát egy adott útvonalra vonatkozó szakpolitikai döntés, nem protokollkövetelmény. Széles körben alkalmazva elrejti a tünetet, miközben megváltoztatja a helyreállítást minden folyamnál, amelyet az útvonal lefed.
Mit tesz és mit nem tesz a tcp-nodelay
A tunelopció, amely kikapcsolja a Nagle-stílusú pufferelést az átviteli socketen, szűk célt szolgál: megakadályozza, hogy a kis írások további adatra várjanak küldés előtt. Ez segít az interaktív forgalomnak elkerülni egy plusz késleltetést egy egyébként egészséges útvonalon.
Nem teszi rendezetlenné az átvitelt, és nem rövidíti le a helyreállítást egy elveszett szegmens után. Az a shell, amely újraküldési időtúllépés miatt szünetel, bekapcsolt opcióval is szünetelni fog, mert az opció soha nem érintette a sorrendezési szabályt.
Könnyű összetéveszteni a kettőt, mert mindkettőt késleltetésjavítóként írják le. Az egyik eltávolítja a pufferelés okozta mesterséges várakozást, a másik megváltoztatná, amit az átvitel garantál, és ezt egyetlen socket-opció sem teszi.
Hogyan hasonlítsuk össze tisztességesen az átviteleket
Ha az üzemeltető engedi, és mindkét szolgáltatás létezik, hasonlítson össze egy UDP- és egy TCP-szolgáltatást ugyanazzal a terheléssel ugyanazon hozzáférési útvonalon, ugyanahhoz a szerverhez. Ha a két teszt között országot, szolgáltatót vagy szervergenerációt váltunk, olyan változót viszünk be, amely uralni fogja az eredményt.
A közös szünetre figyeljünk, ne egy átbocsátási számra. Több belső alkalmazás együttes elakadása külső veszteség alatt az a megfigyelés, amely azonosítja a sor eleji blokkolást; egyetlen alacsonyabb sebességteszt-szám nem.
Az engedélyezett rögzítések a tunel interfészén és a fizikai interfészen tisztán elválasztják a két réteget, mert a belső és külső újraküldések különböző kapcsolatokhoz, különböző sorszámterekhez tartoznak. Az a tény, hogy belső újraküldéseket látunk, miközben a külső folyam rést mutat, a közvetlen bizonyíték.
Az UDP-re váltás eltávolítja a plusz megbízható folyamot, és a belső TCP-re hagyja a saját helyreállítását. Nem ígér nulla veszteséget vagy alacsony késleltetést, és a telített feltöltő link, a túlméretezett sorok vagy az MTU-probléma továbbra is javítást igényel. A tunelen kívüli forgalmat soha nem tartja vissza a tunel sorszámrése, bár még mindig szenvedhet, ha mindkét útvonal egyetlen torlódott linket oszt meg, és ez a közös szűk keresztmetszet saját vizsgálatot érdemel, ahelyett hogy ebbe hajtogatnánk.