Kaip mes įveikėme Didžiąją Kinijos ugniasienę (2 dalis)

Sveiki!

Nikita vėl su jumis, sistemos inžinierius iš įmonės SEMrush. Ir šiuo straipsniu tęsiu istoriją apie tai, kaip mes sugalvojome sprendimą Kinijos ugniasienė mūsų paslaugai semrush.com.

В ankstesnė dalis Aš pasakiau:

  • kokios problemos iškyla priėmus sprendimą „Turime, kad mūsų paslauga veiktų Kinijoje“
  • Kokių problemų turi Kinijos internetas?
  • kodėl jums reikia ICP licencijos?
  • kaip ir kodėl nusprendėme išbandyti savo bandymų vietas su Catchpoint
  • koks buvo mūsų pirmojo sprendimo, pagrįsto „Cloudflare China Network“, rezultatas
  • Kaip radome „Cloudflare“ DNS klaidą

Ši dalis, mano nuomone, pati įdomiausia, nes joje daugiausia dėmesio skiriama specifiniams techniniams pastatymo įgyvendinimams. Ir mes pradėsime, tiksliau, tęsime nuo Alibaba debesis.

Alibaba debesis

Alibaba debesis yra gana didelis debesų tiekėjas, turintis visas paslaugas, leidžiančias nuoširdžiai vadintis debesų paslaugų teikėju. Gerai, kad jie turi galimybę užsiregistruoti užsienio vartotojams ir kad didžioji dalis svetainės yra išversta į anglų kalbą (Kinijai tai yra prabanga). Šiame debesyje galite dirbti su daugeliu pasaulio regionų, žemynine Kinija, taip pat su Okeanine Azija (Honkongas, Taivanas ir kt.).

IPSEC

Pradėjome nuo geografijos. Kadangi mūsų bandomoji svetainė buvo „Google Cloud“, mums reikėjo „susieti“ „Alibaba Cloud“ su GCP, todėl atidarėme vietų, kuriose veikia „Google“, sąrašą. Tuo metu jie dar neturėjo savo duomenų centro Honkonge.
Paaiškėjo, kad artimiausias regionas azija-rytai1 (Taivanas). Ali pasirodė esantis arčiausiai Taivano esantis žemyninės Kinijos regionas cn-shenzhen (Šendženas).

naudojant terraformas aprašė ir iškėlė visą infrastruktūrą GCP ir Ali. 100 Mbit/s tunelis tarp debesų pakilo beveik akimirksniu. Šendženo ir Taivano pusėje buvo iškeltos tarpinio serverio virtualios mašinos. Šendžene vartotojų srautas nutraukiamas, tarpinis serveris per tunelį nukreipiamas į Taivaną, o iš ten nukreipiamas tiesiai į išorinį mūsų paslaugos IP adresą. mus-rytai (JAV rytinė pakrantė). Ping tarp virtualių mašinų per tunelį 24ms, kas nėra taip blogai.

Tuo pačiu metu įrengėme bandomąją zoną Alibaba Cloud DNS. Perdavus zoną NS Ali, skyros laikas sumažėjo nuo 470 ms iki 50 ms. Prieš tai zona taip pat buvo „Cloudlfare“.

Lygiagrečiai tuneliui į azija-rytai1 iškėlė kitą tunelį iš Šendženo tiesiai į mus-rytai4. Ten jie sukūrė daugiau tarpinių virtualių mašinų ir pradėjo testuoti abu sprendimus, nukreipdami bandomąjį srautą naudodami slapukus arba DNS. Bandymo stendas schematiškai aprašytas toliau pateiktame paveikslėlyje:

Tunelių delsa pasirodė tokia:
Ali cn-Shenzhen <—> GCP asia-east1 – 24 ms
Ali cn-shenzhen <—> GCP us-east4 – 200 ms

Catchpoint naršyklės bandymai parodė puikų pagerėjimą.

Palyginkite dviejų sprendimų bandymų rezultatus:

sprendimas
Pasiekiamumas
Mediana
75 procentilis
95 procentilis

Cloudflare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

Tai duomenys iš sprendimo, kuris naudoja IPSEC tunelį per azija-rytai1. Per mus-east4 rezultatai buvo prastesni, o klaidų buvo daugiau, todėl rezultatų nepateiksiu.

Remiantis šio dviejų tunelių, kurių vienas baigiasi arčiausiai Kinijos regione, o kitas – galutiniame taške, bandymo rezultatais tapo aišku, kad svarbu kuo greičiau „išlipti“ iš po Kinijos užkardos. įmanoma, o tada naudokite sparčiuosius tinklus (CDN teikėjai , debesijos paslaugų teikėjai ir kt.). Nereikia bandyti peržengti ugniasienės ir vienu ypu pasiekti savo tikslą. Tai nėra greičiausias būdas.

Apskritai rezultatai nėra blogi, tačiau semrush.com mediana yra 8.8 s ir 75 procentai 9.4 s (to paties testo metu).
O prieš eidamas toliau, norėčiau padaryti trumpą lyrinį nukrypimą.

Lyrinis nukrypimas

Vartotojui įėjus į svetainę www.semrushchina.cn, kuris išsprendžiamas naudojant „greitus“ Kinijos DNS serverius, HTTP užklausa perduodama per mūsų greitą sprendimą. Atsakymas grąžinamas tuo pačiu keliu, tačiau domenas nurodytas visuose JS scenarijuose, HTML puslapiuose ir kituose tinklalapio elementuose semrush.com papildomiems ištekliams, kurie turi būti įkeliami pateikiant puslapį. Tai yra, klientas išsprendžia „pagrindinį“ A įrašą www.semrushchina.cn ir patenka į greitąjį tunelį, greitai gauna atsakymą – HTML puslapį, kuriame rašoma:

  • atsisiųskite tokius ir tokius js iš sso.semrush.com,
  • Gaukite CSS failus iš cdn.semrush.com,
  • taip pat paimkite keletą nuotraukų iš dab.semrush.com
  • ir taip toliau.

Naršyklė pradeda eiti į „išorinį“ internetą, kad gautų šiuos išteklius, kiekvieną kartą pereidama per ugniasienę, kuri sunaudoja atsako laiką.

Tačiau ankstesnis testas rodo rezultatus, kai puslapyje nėra išteklių semrush.com, tik semrushchina.cn, ir *.semrushchina.cn nustato virtualiosios mašinos adresą Šendžene, kad patektų į tunelį.

Tik tokiu būdu, maksimaliai išstumdami visą įmanomą srautą per savo sprendimą, skirtą greitai pereiti prie Kinijos ugniasienės, galite gauti priimtiną greitį ir svetainės prieinamumo rodiklius bei sąžiningus sprendimo testų rezultatus.
Tai padarėme be jokio kodo redagavimo komandos produkto pusėje.

Subfiltras

Sprendimas gimė beveik iš karto po šios problemos atsiradimo. Mums reikėjo PoC (Proof of Concept), kad mūsų ugniasienės įsiskverbimo sprendimai tikrai veikia gerai. Norėdami tai padaryti, į šį sprendimą turite kiek įmanoma labiau įtraukti visą svetainės srautą. Ir kreipėmės subfiltras nginx.

Subfiltras yra gana paprastas nginx modulis, leidžiantis pakeisti vieną atsakymo eilutę į kitą eilutę. Taigi mes pakeitėme visus įvykius semrush.com apie semrushchina.cn visuose atsakymuose.

Ir... tai neveikė, nes gavome suspaustą turinį iš backendų, todėl subfiltras nerado reikiamos eilutės. Turėjau pridėti kitą vietinį serverį prie nginx, kuris išglaudindavo atsakymą ir perdavė jį kitam vietiniam serveriui, kuris jau buvo užsiėmęs eilutės pakeitimu, suspaudimu ir siuntimu į kitą tarpinį serverį grandinėje.

Dėl to kur klientas gautų .semrush.com, jis gavo .semrushchina.cn ir klusniai žengė per mūsų sprendimą.

Tačiau neužtenka vien pakeisti domeną vienu būdu, nes backends vis tiek tikisi semrush.com vėlesnėse kliento užklausose. Atitinkamai, tame pačiame serveryje, kuriame atliekamas vienpusis pakeitimas, naudojant paprastą reguliarųjį posakį gauname užklausos padomenį, o tada atliekame proxy_pass su kintamuoju $ šeimininkas, eksponuojamas m $subdomain.semrush.com. Tai gali atrodyti painu, bet tai veikia. Ir tai gerai veikia. Atskiriems domenams, kuriems reikalinga kitokia logika, tiesiog sukurkite savo serverio blokus ir atlikite atskirą konfigūraciją. Žemiau pateikiamos sutrumpintos nginx konfigūracijos, kad būtų aiškiau ir parodyta ši schema.

Ši konfigūracija apdoroja visas užklausas iš Kinijos į .semrushchina.cn:

    listen 80;

    server_name ~^(?<subdomain>[w-]+).semrushchina.cn$;

    sub_filter '.semrush.com' '.semrushchina.cn';
    sub_filter_last_modified on;
    sub_filter_once off;
    sub_filter_types *;

    gzip on;
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript;

    location / {
        proxy_pass http://127.0.0.1:8083;
        proxy_set_header Accept-Encoding "";
        proxy_set_header Host $subdomain.semrush.com;
        proxy_set_header X-Accept-Encoding $http_accept_encoding;
    }
}

Ši konfigūracija yra tarpinis serveris localhost į 83 prievadą ir ten laukia ši konfigūracija:

    listen 127.0.0.1:8083;

    server_name *.semrush.com;

    location / {
        resolver 8.8.8.8 ipv6=off;
        gunzip on;
        proxy_pass https://$host;
        proxy_set_header Accept-Encoding gzip;
    }
}

Kartoju, tai yra apkarpytos konfigūracijos.

Šitaip. Tai gali atrodyti sudėtinga, bet tai yra žodžiais. Tiesą sakant, viskas paprasčiau nei garuose virtos ropės :)

Nukrypimo pabaiga

Kurį laiką džiaugėmės, nes mitas apie krentančius IPSEC tunelius nepasitvirtino. Bet tada tuneliai pradėjo griūti. Kelis kartus per dieną po kelias minutes. Šiek tiek, bet mums tai netiko. Kadangi abu tuneliai buvo baigti Ali pusėje tame pačiame maršrutizatoriuje, nusprendėme, kad galbūt tai regioninė problema, todėl reikia padidinti atsarginį regioną.

Jie jį pakėlė. Tuneliai pradėjo sugesti skirtingu metu, bet nginx aukštesnio lygio gedimas mums puikiai veikė. Bet tada tuneliai pradėjo kristi maždaug tuo pačiu metu 🙂 Ir vėl prasidėjo 502 ir 504. Veikimo laikas pradėjo prastėti, todėl pradėjome dirbti su pasirinkimu Alibaba CEN („Cloud Enterprise Network“).

CEN

CEN - tai dviejų VPC iš skirtingų „Alibaba Cloud“ regionų sujungimas, tai yra, galite sujungti bet kurių debesies regionų privačius tinklus. Ir svarbiausia: šis kanalas turi gana griežtą SLA. Jis yra labai stabilus tiek greičio, tiek veikimo metu. Bet tai niekada nebūna taip paprasta:

  • LABAI sunku gauti, jei nesate Kinijos pilietis ar juridinis asmuo,
  • Turite mokėti už kiekvieną kanalo pralaidumo megabitą.

Turint galimybę prisijungti žemyninės Kinijos и užsienyje, sukūrėme CEN tarp dviejų Ali regionų: cn-shenzhen и mus-rytai-1 (arčiausiai mūsų esantis taškas-rytai4). Ali mus-rytai-1 iškėlė dar vieną virtualią mašiną, kad būtų dar viena hop'as.

Tai pasirodė taip:

Naršyklės bandymo rezultatai pateikiami žemiau:

sprendimas
Pasiekiamumas
Mediana
75 procentilis
95 procentilis

Cloudflare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

CEN
99.75
16s
21s
27s

Našumas yra šiek tiek geresnis nei IPSEC. Bet per IPSEC galima parsisiųsti 100 Mbit/s greičiu, o per CEN – tik 5 Mbit/s ir daugiau.

Skamba kaip hibridas, tiesa? Sujunkite IPSEC greitį ir CEN stabilumą.

Tai mes padarėme, leisdami eismą per IPSEC ir CEN, jei sugestų IPSEC tunelis. Veikimo laikas tapo daug ilgesnis, tačiau svetainės įkėlimo greitis vis dar palieka daug norimų rezultatų. Tada nubraižiau visas grandines, kurias jau naudojome ir išbandėme, ir nusprendžiau pabandyti į šią grandinę pridėti šiek tiek daugiau GCP, būtent dangtelį.

dangtelį

dangtelį - yra Global Load Balancer (arba „Google Cloud Load Balancer“). Jis turi mums svarbų pranašumą: CDN kontekste jis turi Anycast IP, kuri leidžia nukreipti srautą į arčiausiai kliento esantį duomenų centrą, kad srautas greitai patektų į greitąjį Google tinklą ir mažiau eitų per „įprastą“ internetą.

Du kartus negalvodami pakėlėme HTTP/HTTPS LB Įdiegėme savo virtualias mašinas su subfiltru GCP ir kaip užpakalinę programą.

Buvo kelios schemos:

  • Naudokite „Cloudflare“ Kinijos tinklas, tačiau šį kartą „Origin“ turėtų nurodyti globalų IP GLB.
  • Nutraukti klientus adresu cn-shenzhen, o iš ten nukreipkite srautą tiesiai į dangtelį.
  • Važiuokite tiesiai iš Kinijos į dangtelį.
  • Nutraukti klientus adresu cn-shenzhen, iš ten proxy į azija-rytai1 per IPSEC (į mus-rytai4 per CEN), iš ten eikite į GLB (ramiai, žemiau bus nuotrauka ir paaiškinimas)

Išbandėme visas šias parinktis ir dar keletą hibridinių:

  • Cloudflare + GLB

Ši schema mums netiko dėl veikimo laiko ir DNS klaidų. Bet testas buvo atliktas prieš ištaisant klaidą CF pusėje, galbūt dabar geriau (tačiau tai neatmeta HTTP skirtojo laiko).

  • Ali + GLB

Ši schema mums taip pat netiko veikimo laiko atžvilgiu, nes GLB dažnai iškrito iš priešsrovės dėl to, kad nepavyko prisijungti per priimtiną laiką arba dėl laiko pabaigos, nes serveriui Kinijoje GLB adresas lieka išorėje, taigi ir už Kinijos ugniasienė. Magija neįvyko.

  • Tik GLB

Variantas panašus į ankstesnį, tik nenaudojo serverių pačioje Kinijoje: srautas ėjo tiesiai į GLB (pakeisti DNS įrašai). Atitinkamai, rezultatai nebuvo patenkinami, nes paprasti Kinijos klientai, besinaudojantys įprastų interneto tiekėjų paslaugomis, turi daug prastesnę užkardos perėjimo situaciją nei „Ali Cloud“.

  • Šendženas -> (CEN / IPSEC) -> Tarpinis serveris -> GLB

Čia nusprendėme naudoti geriausią iš visų sprendimų:

  • stabilumas ir garantuotas SLA iš CEN
  • didelis greitis iš IPSEC
  • „Google“ „greitasis“ tinklas ir jo transliacija.

Schema atrodo maždaug taip: vartotojo srautas nutraukiamas virtualioje mašinoje ch-Shenzhen. Ten sukonfigūruoti „Nginx“ srautai, kai kurie iš jų nurodo privačius IP serverius, esančius kitame IPSEC tunelio gale, o kai kurie aukštyn nukreipti serveriai nukreipia į privačius serverių adresus kitoje CEN pusėje. IPSEC sukonfigūruotas pagal regioną azija-rytai1 GSP (sprendimo kūrimo metu buvo arčiausiai Kinijos esantis regionas. GCP dabar taip pat veikia Honkonge). CEN – į regioną mus-rytai1 Ali debesyje.

Tada eismas iš abiejų galų buvo nukreiptas į Anycast IP GLB, ty iki artimiausio „Google“ buvimo vietos, ir per jos tinklus nuėjo į regioną mus-rytai4 GCP, kurioje buvo pakaitinių virtualių mašinų (su subfiltru nginx).

Šis hibridinis sprendimas, kaip ir tikėjomės, išnaudojo kiekvienos technologijos privalumus. Paprastai srautas vyksta per greitą IPSEC, bet jei prasideda problemos, mes greitai ir kelioms minutėms pašaliname šiuos serverius iš aukštyn ir srautą siunčiame tik per CEN, kol tunelis stabilizuosis.

Įdiegę 4-ąjį sprendimą iš aukščiau pateikto sąrašo pasiekėme tai, ko norėjome ir ko tuo metu iš mūsų reikalavo verslas.

Naujojo sprendimo naršyklės bandymo rezultatai, palyginti su ankstesniais:

sprendimas
Pasiekiamumas
Mediana
75 procentilis
95 procentilis

Cloudflare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

CEN
99.75
16s
21s
27s

CEN/IPsec + GLB
99.79
13s
16s
25s

CDN

Mūsų įdiegtame sprendime viskas gerai, tačiau nėra CDN, kuris galėtų pagreitinti eismą regioniniu ir net miesto lygiu. Teoriškai tai turėtų pagreitinti svetainę galutiniams vartotojams naudojant greitus CDN teikėjo ryšio kanalus. Ir mes visą laiką apie tai galvojome. Ir dabar atėjo laikas kitai projekto iteracijai: CDN tiekėjų paieškai ir testavimui Kinijoje.

Ir apie tai papasakosiu kitoje, paskutinėje dalyje :)

Šaltinis: www.habr.com

Добавить комментарий