Kaip „OpenAI“ dideliu mastu užtikrina balso DI veikimą su mažu vėlavimu
Autoriai: Yi Zhang ir William McDonald, techninio personalo nariai
Balso DI skamba natūraliai tik tada, kai pokalbis vyksta įprastu kalbėjimo greičiu. Kai atsiranda tinklo trukdžių, žmonės tai iškart pastebi – pasigirsta nenatūralios pauzės, staigūs nutrūkimai ar vėluojantys įsiterpimai. Tai svarbu naudojant „ChatGPT“ balso funkciją, kūrėjams, dirbantiems su „Realtime API“, agentams, veikiantiems interaktyviose darbo eigose, ir modeliams, kuriems reikia apdoroti garsą naudotojui vis dar kalbant.
„OpenAI“ veiklos mastu tai reiškia tris konkrečius reikalavimus:
- Pasaulinė aprėptis, skirta daugiau nei 900 mln. aktyvių naudotojų per savaitę
- Greitas ryšio užmezgimas, kad naudotojas galėtų pradėti kalbėti vos prasidėjus sesijai
- Trumpas ir stabilus duomenų perdavimo laikas su minimaliais delsos svyravimais ir paketų praradimais, kad apsikeitimas replikomis būtų itin sklandus
„OpenAI“ komanda, atsakinga už realaus laiko DI sąveikas, neseniai iš naujo suprojektavo mūsų „WebRTC“ technologijų dėklą. Taip buvo siekiama išspręsti tris apribojimus, kurie išryškėjo išaugus mastui: medijos srautų užbaigimas principu „vienas prievadas vienai sesijai“ netinka „OpenAI“ infrastruktūrai; būseną išlaikančioms ICE (angl. Interactive Connectivity Establishment) ir DTLS (angl. Datagram Transport Layer Security) sesijoms reikia stabilaus priskirtojo savininko; o pasaulinis maršruto parinkimas privalo išlaikyti mažą pirmojo šuolio vėlavimą. Šiame įraše aptarsime mūsų sukurtą atskirą retransliatoriaus ir siųstuvo-imtuvo architektūrą. Ji leidžia išlaikyti standartinį „WebRTC“ veikimą klientams ir kartu pakeičia paketų maršruto parinkimą „OpenAI“ infrastruktūroje.
„WebRTC“ yra atvirasis standartas, skirtas mažo vėlavimo garso, vaizdo ir duomenų perdavimui tarp naršyklių, mobiliųjų programų ir serverių. Jis dažnai siejamas su lygiaverčių mazgų (angl. peer-to-peer) skambučiais, tačiau kartu yra praktiškas pagrindas realaus laiko sistemoms, veikiančioms kliento–serverio principu. Taip yra todėl, kad jis standartizuoja sudėtingus interaktyviosios medijos aspektus: ICE ryšiui užmegzti ir NAT (angl. Network Address Translation) įveikti, DTLS ir SRTP (angl. Secure Real-time Transport Protocol) šifruotam perdavimui, kodekų derinimą garso glaudinimui bei dekodavimui, RTCP (angl. Real-time Transport Control Protocol) kokybės kontrolei ir tokias kliento funkcijas kaip aido slopinimas bei delsos svyravimų buferizavimas.
DI produktams šis standartizavimas yra labai svarbus. Be „WebRTC“ kiekvienam klientui reikėtų skirtingo sprendimo, kaip užmegzti ryšį per NAT, šifruoti mediją, suderinti kodekus (perdavimui ir išskleidimui parinktus koduotojus-dekoduotojus) bei prisitaikyti prie kintančių tinklo sąlygų. Naudodami „WebRTC“, galime remtis protokolų rinkiniu, kuris jau įdiegtas naršyklėse bei mobiliosiose platformose, ir sutelkti dėmesį į infrastruktūrą, sujungiančią realaus laiko mediją su modeliais.
Mes taip pat remiamės pačia „WebRTC“ ekosistema, įskaitant brandžius atvirojo kodo sprendimus ir standartus, užtikrinančius naršyklių, mobiliųjų programų bei serverių suderinamumą. Pamatinis Justino Uberti (vieno iš pradinių „WebRTC“ architektų) ir Seano DuBoiso („Pion“ kūrėjo ir prižiūrėtojo) darbas leido tokioms komandoms kaip mūsų kurti naudojant praktikoje išbandytą medijos infrastruktūrą, užuot iš naujo išradinėjus žemo lygmens perdavimo, šifravimo ir apkrovos valdymo mechanizmus. Džiaugiamės, kad dabar ir Justinas, ir Seanas yra mūsų kolegos „OpenAI“, padedantys atrasti geriausius būdus, kaip dar labiau suartinti „WebRTC“ ir realaus laiko DI.
DI sistemoms svarbiausia, kad garsas keliautų nepertraukiamu srautu. Balsu bendraujantis agentas gali pradėti transkribuoti, analizuoti, naudoti įrankius ar generuoti kalbą naudotojui vis dar kalbant, užuot laukęs, kol bus įkeltas visas garso įrašas. Būtent tai atskiria natūralų pokalbį nuo bendravimo, primenančio kalbėjimą per raciją (angl. push-to-talk).
Pasirinkus „WebRTC“, iškilo kitas klausimas – kur užbaigti jos sesiją (kur priimsime ir valdysime „WebRTC“ ryšį, pavyzdžiui, tinklo pakraštyje) ir kaip tas sesijas sujungti su modelio vykdymo posisteme. Sesijos užbaigimas yra svarbus, nes nuo jo priklauso, kaip valdysime realaus laiko sesijos būseną, medijos perdavimą, maršruto parinkimą, vėlavimą ir izoliavimą gedimo atveju.
SFU (angl. Selective Forwarding Unit), arba atrankinio persiuntimo mazgas, yra medijos serveris, kuris gauna po vieną „WebRTC“ srautą iš kiekvieno dalyvio ir pasirinktinai persiunčia srautus kitiems. Šiame modelyje SFU kiekvienam dalyviui sukuria atskirą „WebRTC“ ryšio užbaigimą, o DI prisijungia kaip dar vienas sesijos dalyvis. Tai gali būti geras sprendimas produktams, kuriuose vienu metu bendrauja daug šalių, pavyzdžiui, grupiniams skambučiams, virtualioms klasėms ar bendriems susitikimams. Taip garso kodekai, RTCP pranešimai, duomenų kanalai, įrašymas ir srautų taisyklės valdomi vienoje vietoje.1
Net ir kuriant kliento ir DI bendravimui skirtus produktus, SFU dažnai pasirenkamas kaip pradinis taškas. Tai leidžia komandoms pakartotinai naudoti vieną patikrintą sistemą signalizavimui, medijos nukreipimui, įrašymui, stebėjimui bei būsimiems išplėtimams, pavyzdžiui, perdavimui žmogui arba naujų dalyvių įtraukimui.
Mūsų darbo krūvio specifika yra kitokia. Dauguma sesijų vyksta principu 1:1 – vienas naudotojas kalbasi su vienu modeliu arba viena programa bendrauja su vienu realaus laiko agentu, o vėlavimas yra itin jautrus kiekviename žingsnyje. Tokiam srauto tipui pasirinkome siųstuvo-imtuvo modelį: „WebRTC“ tinklo pakraščio paslauga užbaigia kliento ryšį, o tada konvertuoja mediją bei įvykius į paprastesnius vidinius protokolus, skirtus modelio vykdymui, transkribavimui, kalbos generavimui, įrankių naudojimui ir orkestravimui.
Šioje architektūroje siųstuvas-imtuvas yra vienintelė paslauga, valdanti „WebRTC“ sesijos būseną, įskaitant ICE ryšio patikras, DTLS pasisveikinimą, SRTP šifravimo raktus ir sesijos gyvavimo ciklą. Ryšio „užbaigimas“ čia reiškia, kad siųstuvas-imtuvas yra tas prieigos taškas, kuris atlieka šiuos pasisveikinimus ir šifruoja bei iššifruoja mediją. Sutelkus šią būseną vienoje vietoje, tapo lengviau suprasti sesijų priklausomybę, o foninės paslaugos galėjo sklandžiai plėstis kaip ir įprastos paslaugos, užuot pačios veikusios kaip lygiaverčiai „WebRTC“ mazgai.
Pasirinkus siųstuvo-imtuvo modelį, mūsų pirmoji realizacija buvo viena „Go“ paslauga, sukurta naudojant „Pion“, kuri valdė ir signalizavimą, ir medijos ryšio užbaigimą. Ji užtikrina „ChatGPT“ balso funkcijos, „Realtime API“ „WebRTC“ prieigos taško ir daugelio tyrimų projektų veikimą.
Eksploataciniu požiūriu siųstuvo-imtuvo paslauga atlieka dvi užduotis:
- Signalizavimas: SDP derinimas, kodeko parinkimas, ICE kredencialai ir sesijos sąranka
- Medija: gaunamų „WebRTC“ ryšių užbaigimas ir išeinančių ryšių su foninėmis paslaugomis palaikymas, skirtas modelio vykdymui ir orkestravimui
Norėjome, kad paslauga veiktų taip pat, kaip ir likusi mūsų infrastruktūra: „Kubernetes“ aplinkoje, kur, keičiantis poreikiui, darbo krūviai gali didėti ar mažėti bei persikelti iš vieno serverio į kitą. Tačiau įprastas „vienas prievadas vienai sesijai“ „WebRTC“ modelis šiai aplinkai menkai tinka. Jis priklauso nuo didelių viešųjų UDP prievadų diapazonų, kuriuos sunku atverti, apsaugoti ir išlaikyti pridedant, pašalinant ar perplanuojant programų talpyklas.2
Pirmoji problema buvo pats „vienas prievadas vienai sesijai“ modelis. Esant dideliam vienalaikių ryšių skaičiui, tai reiškia, kad tenka atverti ir valdyti labai didelius UDP prievadų diapazonus.
- Debesijos apkrovos balansavimo įrenginiai ir „Kubernetes“ paslaugos nėra pritaikytos dešimtims tūkstančių viešųjų UDP prievadų vienai paslaugai. Kiekvienas papildomas diapazonas apsunkina apkrovos balansavimo įrenginio konfigūraciją, būklės tikrinimą, ugniasienės taisykles ir saugų naujinimų diegimą.3
- Didelius UDP prievadų diapazonus sunku apsaugoti, nes jie išplečia iš išorės pasiekiamą paviršių ir apsunkina tinklo taisyklių auditą.
- Jie taip pat prastai tinka automatiniam išteklių mastelio keitimui. „Kubernetes“ aplinkoje programų talpyklos yra nuolat pridedamos, šalinamos ir perplanuojamos. Reikalavimas, kad kiekviena talpykla rezervuotų ir skelbtų didelį stabilų prievadų diapazoną, daro šį elastingumą pažeidžiamą.4
Štai kodėl daugelis „WebRTC“ sistemų pereina prie vieno UDP prievado serveriui, naudojant programos lygmens demultipleksavimą už to prievado.5
Vieno prievado serveriui architektūra išsprendžia prievadų kiekio problemą, tačiau sukelia kitą: kaip išlaikyti kiekvienos sesijos priskirtąjį savininką visame serverių parke.
ICE ir DTLS yra būseną išlaikantys protokolai. Procesas, kuris sukūrė sesiją, privalo ir toliau gauti tos sesijos paketus, kad galėtų patvirtinti ryšio patikras, užbaigti DTLS pasisveikinimą, iššifruoti SRTP ir apdoroti vėlesnius sesijos pokyčius, pavyzdžiui, ICE paleidimus iš naujo. Jei tos pačios sesijos paketai patenka į kitą procesą, sąranka gali nepavykti arba medijos perdavimas nutrūkti.
Taigi turėjome aiškų tikslą: atverti viešajam internetui nedidelį, fiksuotą UDP paviršių, tačiau kartu nukreipti kiekvieną paketą į tą siųstuvą-imtuvą, kuriam priklauso atitinkama „WebRTC“ sesija.
Įvertinome kelis būdus tai pasiekti, įskaitant TURN (angl. Traversal Using Relays around NAT), kai tinklo pakraščio retransliatorius užbaigia kliento priskyrimus ir persiunčia srautą jo vardu.2
Metodas | Privalumai | Trūkumai |
Unikalus IP ir prievadas kiekvienai sesijai (taip pat žinomas kaip vietinis tiesioginis UDP) | Tiesioginis medijos kelias nuo kliento iki serverio Duomenų kelyje nėra persiuntimo lygmens | Reikalauja vieno viešojo UDP prievado kiekvienai sesijai Didelius prievadų diapazonus sunku atverti ir apsaugoti Prastai tinka „Kubernetes“ ir debesijos apkrovos balansavimo įrenginiams |
Unikalus IP ir prievadas kiekvienam serveriui | Žymiai mažesnis viešosios UDP erdvės pėdsakas nei atveriant pagal sesijas Vienas bendrinamas lizdas serveryje gali demultipleksuoti daug sesijų | Sklandžiai veikia viename serveryje, tačiau savaime netinka bendrinamame serverių parke, naudojančiame apkrovos balansavimą Sesijų demultipleksavimas viename serveryje padeda tik tada, kai paketas pasiekia tą serverį. Serverių parke su apkrovos balansavimu pirmasis paketas vis tiek gali patekti į netinkamą egzempliorių, todėl vis tiek reikia deterministinio būdo kiekvienai sesijai nukreipti į jai priskirtą procesą |
TURN retransliatorius (užbaigiantis protokolą) | Klientams tereikia pasiekti TURN retransliatoriaus adresą ir prievadą Leidžia centralizuoti taisykles tinklo pakraštyje | TURN priskyrimai prideda papildomų sąrankos ciklų Vis dar sudėtinga perkelti ar atkurti priskyrimus tarp TURN serverių |
Būsenos nepalaikantis persiuntėjas + būseną išlaikantis ryšio užbaigimo mazgas („OpenAI“ retransliatorius + siųstuvas-imtuvas) | Nedidelis viešasis UDP pėdsakas Siųstuvui-imtuvui vis tiek priklauso visa „WebRTC“ sesija | Pridedamas vienas persiuntimo šuolis prieš medijai pasiekiant priskirtąjį siųstuvą-imtuvą Reikalauja nestandartinio koordinavimo tarp retransliatoriaus ir siųstuvo-imtuvo |
Mūsų įdiegta architektūra atskiria paketų maršruto parinkimą nuo protokolo ryšio užbaigimo. Signalizavimas vis dar pasiekia siųstuvą-imtuvą sesijai sukurti, o medija pirmiausia pereina per retransliatorių. Retransliatorius yra lengvas UDP persiuntimo lygmuo, užimantis nedidelę viešąją erdvę, o už jo esantis siųstuvas-imtuvas yra būseną išlaikantis „WebRTC“ prieigos taškas.
Retransliatorius neiššifruoja medijos, nevykdo ICE būsenų automatų procesų ir nedalyvauja kodekų derinime. Jis nuskaito tiek paketų metaduomenų, kiek pakanka tikslui pasirinkti, o tada persiunčia paketą siųstuvui-imtuvui, kuriam priklauso sesija. Siųstuvas-imtuvas vis tiek mato įprastą „WebRTC“ srautą ir valdo visą protokolo būseną. Kliento požiūriu pačioje „WebRTC“ sesijoje niekas nepasikeičia.
Pirmojo paketo maršruto parinkimas – svarbiausias šios sąrankos žingsnis. Retransliatorius privalo nukreipti pirmąjį kliento paketą tiesioginiame paketo kelyje dar prieš sukuriant bet kokią sesiją, užuot delsęs ir kreipęsis į išorinę paieškos paslaugą.
Kiekviena „WebRTC“ sesija jau turi protokole įtaisytą maršruto parinkimo elementą: ICE naudotojo vardo fragmentą, arba ufrag. Tai trumpas identifikatorius, kuriuo apsikeičiama sesijos sąrankos metu ir kuris atkartojamas atliekant STUN ryšio patikras. Serverio pusės ufrag sugeneruojame taip, kad jame būtų lygiai tiek maršruto metaduomenų, jog retransliatorius galėtų nustatyti paskirties klasterį ir priskirtąjį siųstuvą-imtuvą.
Signalizavimo metu siųstuvas-imtuvas priskiria sesijos būseną ir SDP atsakyme grąžina bendrinamą retransliatoriaus VIP bei UDP prievadą. VIP – tai virtualusis IP adresas, esantis retransliatorių parko priešakyje. Kartu su prievadu jis suteikia klientui vieną stabilų paskirties tašką, pavyzdžiui, `203.0.113.10:3478`, nors už jo slepiasi daugybė retransliatoriaus egzempliorių. Pirmasis kliento medijos kelio paketas paprastai yra STUN (angl. Session Traversal Utilities for NAT) susiejimo užklausa, kurią ICE naudoja patikrinti, ar paketai gali pasiekti paskelbtą adresą.
Retransliatorius išnagrinėja tik tiek pirmojo STUN paketo informacijos, kad galėtų nuskaityti serverio ufrag, iškoduoti maršruto parinkimo užuominą ir persiųsti paketą priskirtajam siųstuvui-imtuvui. Kiekvienas siųstuvas-imtuvas klausosi bendrinamo UDP lizdo – tai reiškia, kad viena operacinės sistemos prieiga yra susieta su vidiniu IP ir prievadu, o ne naudoja atskirą lizdą kiekvienai sesijai. Kai retransliatorius sukuria sesiją iš kliento šaltinio IP ir prievado į paskirties siųstuvą-imtuvą, tolesni DTLS, RTP ir RTCP paketai keliauja sesijos viduje be pakartotinio ufrag dekodavimo.
Retransliatoriaus sesija sąmoningai yra minimali – ją sudaro tik atmintyje esanti sesija, skirta paketų persiuntimui nurodyti, taip pat būtini stebėsenos skaitikliai ir sesijos galiojimo pabaigos bei valymo laikmačiai. Šis architektūrinis sprendimas išlaiko paketų maršruto parinkimą tiesiogiai paties paketo kelyje. Jei retransliatorius paleidžiamas iš naujo ir praranda sesiją, kitas STUN paketas atkuria sesiją pagal ufrag maršruto užuominą. Siekiant dar didesnio patikimumo, naudojama „Redis“ podėlio atmintis. Nustačius maršrutą, ji išsaugo <kliento IP + prievado ir siųstuvo-imtuvo IP + prievado> susiejimą, todėl ryšį galima atkurti daug anksčiau – dar prieš atvykstant kitam STUN paketui.
Sumažinę viešąjį UDP paviršių iki nedidelio stabilių adresų ir prievadų skaičiaus, galėjome tą patį retransliatoriaus modelį įdiegti visame pasaulyje. Pasaulinis retransliatorius (angl. Global Relay) – tai mūsų geografiškai paskirstytų retransliatoriaus įėjimo taškų parkas. Visi šie taškai atlieka tas pačias paketų persiuntimo funkcijas.
Plati geografinė aprėptis sutrumpina pirmąjį šuolį nuo kliento iki „OpenAI“, nes paketas gali patekti į mūsų tinklą per retransliatorių, kuris yra arti naudotojo – tiek geografine, tiek tinklo topologijos prasme, užuot iš pradžių keliavęs viešuoju internetu į tolimą regioną. Praktiškai tai reiškia mažesnį vėlavimą, mažesnius delsos svyravimus ir mažiau išvengiamų paketų praradimų protrūkių dar prieš srautui pasiekiant mūsų magistralinį tinklą.6
Signalizavimui naudojame „Cloudflare“ geografinį ir artumo valdymą, todėl pirminė HTTP arba „WebSocket“ užklausa pasiekia netoliese esantį siųstuvų-imtuvų klasterį. Užklausos kontekstas nustato sesijos vietą ir tai, kuris Pasaulinio retransliatoriaus įėjimo taškas bus paskelbtas klientui. SDP atsakymas pateikia Pasaulinio retransliatoriaus adresą, o ufrag yra pakankamai informacijos, kad Pasaulinis retransliatorius galėtų nukreipti mediją į nurodytą klasterį, o vietinis retransliatorius – į paskirties siųstuvą-imtuvą.
Geografiškai valdomas signalizavimas ir Pasaulinis retransliatorius kartu užtikrina, kad sąranka bei medija keliautų per netoliese esantį įėjimo kelią, o sesija liktų susieta su vienu siųstuvu-imtuvu. Tai sutrumpina signalizavimo ir pirmosios ICE ryšio patikros perdavimo trukmę pirmyn ir atgal, o tai tiesiogiai sumažina laiką, kurio reikia laukti, kol naudotojas galės pradėti kalbėti.
Retransliatoriaus paslaugą parašėme „Go“ kalba ir jos realizaciją sąmoningai palikome siaurą. „Linux“ operacinėje sistemoje branduolio tinklo dėklas priima UDP paketus iš kompiuterio tinklo sąsajos ir pristato juos į lizdą – operacinės sistemos prieigos tašką, kurį procesas nuskaito susiejęs IP adresą ir prievadą. Retransliatorius veikia naudotojo erdvėje, todėl įprastas „Go“ procesas nuskaito paketų antraštes iš to lizdo, atnaujina nedidelę srauto būsenos dalį ir persiunčia paketus neužbaigdamas „WebRTC“ ryšio. Mums neprireikė jokios branduolio apėjimo (angl. kernel-bypass) sistemos, kuri leistų naudotojo erdvės procesui tiesiogiai apklausti tinklo eiles dėl didesnio paketų srauto, tačiau kartu padidintų eksploatacinį sudėtingumą.
Pagrindiniai architektūriniai sprendimai:
- Jokio protokolo ryšio užbaigimo: retransliatorius išnagrinėja tik STUN antraštes ir ufrag; tolesniems DTLS, RTP ir RTCP paketams jis naudoja podėlyje išsaugotą būseną, todėl paketai išlieka nepermatomi.
- Trumpalaikė būsena: jis išlaiko nedidelį, trumpai galiojantį ir atmintyje esantį kliento adreso bei paskirties siųstuvo-imtuvo susiejimą, skirtą srauto būsenai ir stebėsenai.
- Horizontalusis mastelio keitimas: už apkrovos balansavimo įrenginio lygiagrečiai veikia keli retransliatoriaus egzemplioriai. Būsena nėra griežta „WebRTC“ būsena, todėl paleidimai iš naujo sukelia tik minimalius srauto praradimus ir leidžia greitai atkurti ryšį.
Efektyvumo priemonės:
SO_REUSEPORTyra „Linux“ lizdo parinktis, leidžianti keliems retransliatoriaus darbinio proceso egzemplioriams toje pačioje mašinoje susieti tą patį UDP prievadą. Tada branduolys paskirsto gaunamus paketus šiems darbiniams procesams, o tai padeda išvengti vieno nuskaitymo ciklo kliūčių.runtime.LockOSThreadpriskiria kiekvieną UDP nuskaitančią goroutine (giją) konkrečiai operacinės sistemos gijai. Kartu suSO_REUSEPORTtai leidžia išlaikyti to paties srauto paketus (šaltinio ir paskirties IP:prievadas bei protokolas) tame pačiame procesoriaus branduolyje, taip pagerinant podėlio lokalumą ir sumažinant konteksto perjungimų skaičių.- Iš anksto priskirti buferiai ir minimalus kopijavimas išlaiko mažas nagrinėjimo bei atminties paskirstymo sąnaudas, kad „Go“ aplinkoje būtų išvengta šiukšlių rinkimo procesų sukeliamo apkrovimo.
Ši realizacija apdorojo mūsų pasaulinį realaus laiko medijos srautą naudodama palyginti nedidelį retransliatoriaus išteklių kiekį, todėl pasirinkome paprastesnį architektūros variantą ir atsisakėme branduolio apėjimo sprendimų.
Ši architektūra leidžia mums valdyti „WebRTC“ mediją „Kubernetes“ aplinkoje neatveriant tūkstančių UDP prievadų. Tai svarbu, nes mažesnį ir fiksuotą UDP paviršių lengviau apsaugoti ir subalansuoti jo apkrovą, o infrastruktūrą galima plėsti nerezervuojant didelių viešųjų prievadų diapazonų. Užtikrinant geresnį „Kubernetes“ infrastruktūros palaikymą ir didesnį saugumą dėl mažesnio paviršiaus ploto, šis architektūros modelis taip pat išlaiko standartinį „WebRTC“ veikimą klientams ir patvirtina, kad sprendimas be SFU buvo tinkamiausias priskirtasis pasirinkimas mūsų darbo krūviams. Dauguma mūsų sesijų veikia principu „nuo taško iki taško“, yra jautrios vėlavimui ir jas lengviau išplėsti, kai modelio vykdymo paslaugoms nereikia veikti kaip lygiaverčiams „WebRTC“ mazgams.
Platesnė pamoka yra ta, kad geriausia vieta pridėti sudėtingumo yra plonasis maršruto parinkimo lygmuo, o ne kiekviena foninė paslauga ar nestandartinis kliento elgesys. Maršruto parinkimo metaduomenų užkodavimas protokole įtaisytame lauke suteikė mums deterministinį pirmojo paketo maršruto parinkimą, nedidelį viešąjį UDP paviršių ir pakankamai lankstumo, kad įėjimo taškus galėtume išdėstyti arti naudotojų visame pasaulyje.
Keli sprendimai buvo ypač svarbūs:
- Protokolo semantikos išlaikymas tinklo pakraštyje. Klientai vis dar naudoja standartinę „WebRTC“, todėl naršyklių ir mobiliųjų įrenginių suderinamumas išlieka nepakitęs.
- Griežtų sesijos būsenų laikymas vienoje vietoje. Siųstuvui-imtuvui priklauso ICE, DTLS, SRTP ir sesijos gyvavimo ciklas, o retransliatorius tik persiunčia paketus.
- Maršruto parinkimas remiantis sąrankoje jau esančia informacija. ICE ufrag suteikė mums pirmojo paketo maršruto parinkimo elementą nepridedant priklausomybės nuo paieškos intensyviame kelyje (angl. hot-path).
- Įprasto atvejo optimizavimas prieš griebiantis branduolio apėjimo. Mūsų darbo krūviui visiškai pakako siauros „Go“ realizacijos su atidžiai naudojama
SO_REUSEPORTparinktimi, gijų priskyrimu ir mažai atminties reikalaujančiu nagrinėjimu.
Realaus laiko balso DI veikia tik tada, kai infrastruktūra leidžia pamiršti apie vėlavimą. Mums tai reiškė pakeisti „WebRTC“ diegimo formą, nekeičiant to, ko klientai tikisi iš pačios „WebRTC“.
Autorius
Šaltiniai
2. „GitHub“ – l7mp/stunner: „Kubernetes“ medijos šliuzas, skirtas „WebRTC“(atsidaro naujame lange)
3. Trumpai apie „WebRTC“ prievadus [pavyzdžiai] – BlogGeek.me(atsidaro naujame lange)
4. Diegimas „Kubernetes“ aplinkoje – „LiveKit“ dokumentacija(atsidaro naujame lange)
6. „Cloudflare Calls“: milijonai pakopinių medžių iki pat apačios(atsidaro naujame lange)


