OpenResty: paverčia NGINX visaverčiu programų serveriu

OpenResty: paverčia NGINX visaverčiu programų serveriuVėl skelbiame konferencijos pranešimo stenogramą HighLoad++ 2016 m., kuris vyko Skolkovo mieste netoli Maskvos praėjusių metų lapkričio 7-8 dienomis. Vladimiras Protasovas paaiškinama, kaip išplėsti NGINX funkcionalumą naudojant OpenResty ir Lua.

Sveiki visi, mano vardas Vladimiras Protasovas, dirbu „Parallels“. Papasakosiu šiek tiek apie save. Tris ketvirtadalius savo gyvenimo praleidžiu rašydamas kodą. Tapau programuotoju tiesiogine prasme: kartais sapnuose matau kodą. Ketvirtadalis gyvenimo yra pramonės plėtra, rašomas kodas, kuris patenka tiesiai į gamybą. Kodas, kurį kai kurie iš jūsų naudoja, bet to nesuvokia.

Taigi jūs suprantate, kaip buvo blogai. Kai buvau šiek tiek jaunesnis, atėjau ir gavau šias dviejų terabaitų duomenų bazes. Dabar čia visiems didelis krūvis. Ėjau į konferencijas ir klausiau: „Vaikinai, pasakykite man, jūs turite didelius duomenis, ar viskas šaunu? Kiek ten bazių turi? Jie man atsakė: „Turime 100 gigabaitų! Aš pasakiau: „Šaunu, 100 gigabaitų! Ir aš galvojau sau, kaip kruopščiai prižiūrėti savo pokerio veidą. Jūs manote, taip, vaikinai yra šaunūs, o tada grįšite ir ieškote šių kelių terabaitų duomenų bazių. Ir tai yra jaunesnysis. Ar įsivaizduojate, koks tai smūgis?

Žinau daugiau nei 20 programavimo kalbų. Tai turėjau išsiaiškinti, kai dirbau. Jie suteikia kodą Erlang, C, C++, Lua, Python, Ruby ir dar kažkuo, ir jūs turite viską iškirpti. Apskritai, aš turėjau. Tikslaus skaičiaus suskaičiuoti nepavyko, bet kažkur apie 20-ą skaičius buvo pamestas.

Kadangi visi susirinkusieji žino, kas yra Parallels ir ką mes darome, nekalbėsiu apie tai, kokie mes šaunūs ir ką darome. Tiesiog pasakysiu, kad turime 13 biurų visame pasaulyje, daugiau nei 300 darbuotojų, plėtojame Maskvoje, Taline ir Maltoje. Jei norite, galite pasiimti ir persikelti į Maltą, jei žiemą šalta ir reikia apšildyti nugarą.

Tiksliau, mūsų skyrius rašo Python 2. Esame versle ir neturime laiko diegti madingų technologijų, todėl kenčiame. Naudojame Django, nes jame yra viskas, o tai, kas buvo nereikalinga, paėmėme ir išmetėme. Taip pat MySQL, Redis ir NGINX. Taip pat turime daug kitų šaunių dalykų. Turime MongoDB, aplink laksto triušiai, turime viską, bet tai ne mano, ir aš to nedarau.

OpenResty

Pasakojau apie save. Išsiaiškinkime, apie ką šiandien kalbėsiu:

  • Kas yra OpenResty ir su kuo jis valgomas?
  • Kam išradinėti dar vieną ratą, kai turime Python, NodeJS, PHP, Go ir kitus šaunius dalykus, kuriais visi patenkinti?
  • Ir keli pavyzdžiai iš gyvenimo. Teko labai apkarpyti reportažą, nes užtrukau 3,5 valandos, tad pavyzdžių bus mažai.

„OpenResty“ yra NGINX. Jo dėka turime visavertį žiniatinklio serverį, kuris yra gerai parašytas ir veikia greitai. Manau, kad daugelis iš mūsų naudoja NGINX gamyboje. Visi žinote, kad jis greitas ir šaunus. Jame jie sukūrė puikų sinchroninį įvestį / išvestį, todėl mums nereikia nieko važinėti dviračiu, kaip jie padarė naudodami Python. Gevent yra šaunus, puikus, bet jei parašysite C kodą ir kažkas negerai, tada su Gevent išprotėsite jį derindami. Turėjau patirties: prireikė dviejų dienų, kol supratau, kas ten ne taip. Jei kas nors nebūtų kasinėjęs kelias savaites, suradęs problemą, parašęs internete, o Google nebūtų radęs, tai būtume išėję iš proto.

NGINX jau turi talpyklą ir statinį turinį. Jums nereikia rūpintis, kaip tai padaryti žmogiškai, kad kažkur nesulėtėtumėte greičio, kad kur nors neprarastumėte aprašų. „Nginx“ yra labai patogu įdiegti, jums nereikia galvoti, ką pasiimti - WSGI, PHP-FPM, Gunicorn, Unicorn. Nginx buvo įdiegtas, duotas administratoriams, jie žino, kaip su juo dirbti. „Nginx“ apdoroja užklausas struktūriškai. Apie tai pakalbėsiu šiek tiek vėliau. Trumpai tariant, jis turi etapą, kai jis ką tik priėmė užklausą, kai ją apdorojo ir kai pateikė turinį vartotojui.

„Nginx“ yra šaunus, tačiau yra viena problema: jis nėra pakankamai lankstus, net ir su visomis puikiomis funkcijomis, kurias vaikinai įdėjo į konfigūraciją, nepaisant to, ką galima sukonfigūruoti. Šios galios nepakanka. Štai kodėl vaikinai iš Taobao, seniai, atrodo, prieš aštuonerius metus, pastatė Lua. Ką tai duoda?

  • Dydis. Jis yra mažas. „LuaJIT“ suteikia apie 100–200 kilobaitų atminties ir minimalų našumą.
  • Pagreitinti. LuaJIT interpretatorius daugelyje situacijų yra artimas C, kai kuriose situacijose pralaimi Java, kitose pranoksta. Kurį laiką jis buvo laikomas moderniausiu, šauniausiu JIT kompiliatoriumi. Dabar yra ir vėsesnių, bet jie labai sunkūs, pavyzdžiui, tas pats V8. Kai kurie JS interpretatoriai ir „Java HotSpot“ kai kuriose vietose yra greitesni, tačiau kai kuriose vietose vis tiek pralaimi.
  • Lengva išmokti. Jei turite, tarkime, Perl kodo bazę ir nesate Booking, Perl programuotojų nerasite. Kadangi jų nėra, jie visi buvo atimti, o jų mokymas yra ilgas ir sunkus. Jei norite programuotojų kažkam kitam, taip pat gali tekti juos perkvalifikuoti arba susirasti. Lua atveju viskas paprasta. Bet kuris jaunesnysis gali išmokti Lua per tris dienas. Man prireikė maždaug dviejų valandų, kol tai supratau. Po dviejų valandų jau rašiau kodą gamyboje. Maždaug po savaitės jis nuėjo tiesiai į gamybą ir išėjo.

Dėl to jis atrodo taip:

OpenResty: paverčia NGINX visaverčiu programų serveriu

Čia yra daug. „OpenResty“ surinko daugybę modulių, tiek „luash“, tiek su variklio. Ir jūs turite viską paruošę – išsidėstę ir veikiate.

pavyzdžiai

Užteks dainų žodžių, pereikime prie kodo. Štai mažas Hello World:

OpenResty: paverčia NGINX visaverčiu programų serveriu

Kas ten? Tai yra Enginso vieta. Nesijaudiname, patys nerašome maršruto, nesiimame paruošto – jau turime jį NGINX, gyvename gerai ir tingiai.

content_by_lua_block yra blokas, kuriame sakoma, kad teikiame turinį naudodami Lua scenarijų. Mes paimame kintamąjį „Engins“. remote_addr ir įdėkite string.format. Tai tas pats kaip sprintf, tik Lua, tik teisinga. Ir atiduodame klientui.

Dėl to jis atrodys taip:

OpenResty: paverčia NGINX visaverčiu programų serveriu

Bet grįžkime į realų pasaulį. Niekas nediegia „Hello World“ gamyboje. Mūsų programa dažniausiai patenka į duomenų bazę arba kur nors kitur ir dažniausiai laukia atsakymo.

OpenResty: paverčia NGINX visaverčiu programų serveriu

Jis tik sėdi ir laukia. Tai nėra labai gerai. Kai ateina 100.000 XNUMX vartotojų, mums labai sunku. Taigi kaip pavyzdį naudokime paprastą programą. Ieškosime nuotraukų, pavyzdžiui, kačių. Tačiau mes ne tik ieškosime, bet ir išplėsime raktinius žodžius ir, jei vartotojas ieškojo „kačiukai“, rasime kačių, pūkuotų kačių ir pan. Pirmiausia turime gauti užklausos duomenis vidinėje sistemoje. Tai atrodo taip:

OpenResty: paverčia NGINX visaverčiu programų serveriu

Dvi eilutės leidžia pasiimti GET parametrus, jokių komplikacijų. Tada, tarkime, iš duomenų bazės su raktinio žodžio ir plėtinio ženklu gauname šią informaciją naudodami įprastą SQL užklausą. Tai paprasta. Tai atrodo taip:

OpenResty: paverčia NGINX visaverčiu programų serveriu

Bibliotekos prijungimas resty.mysql, kurį jau turime rinkinyje. Mums nieko nereikia montuoti, viskas paruošta. Mes nurodome, kaip prisijungti ir atlikti SQL užklausą:

OpenResty: paverčia NGINX visaverčiu programų serveriu

Čia šiek tiek baisu, bet viskas veikia. Čia 10 yra riba. Ištraukiame 10 įrašų, tingime, nenorime daugiau rodyti. Pamiršau apie SQL limitą.

Toliau rasime nuotraukas visoms užklausoms. Surenkame krūvą užklausų ir užpildome Lua lentelę, vadinamą reqs, ir mes darome ngx.location.capture_multi.

OpenResty: paverčia NGINX visaverčiu programų serveriu

Visos šios užklausos siunčiamos lygiagrečiai, o atsakymai grąžinami mums. Veikimo laikas yra lygus lėčiausio atsako laikui. Jei visi nufilmuosime per 50 milisekundžių, o išsiuntėme šimtą užklausų, tai atsakymą gausime per 50 milisekundžių.

Kadangi esame tingūs ir nenorime rašyti HTTP ir talpyklos tvarkymo, priversime NGINX viską padaryti už mus. Kaip matėte, buvo prašymas url/fetch, štai jis:

OpenResty: paverčia NGINX visaverčiu programų serveriu

Padarome tai paprasta proxy_pass, mes nurodome, kur talpinti, kaip tai padaryti, ir viskas mums tinka.

Bet to nepakanka, vis tiek turime pateikti duomenis vartotojui. Paprasčiausia idėja yra suskirstyti viską JSON, lengvai, dviem eilutėmis. Mes suteikiame turinio tipą, suteikiame JSON.

Tačiau yra vienas sunkumas: vartotojas nenori skaityti JSON. Turime pritraukti front-end kūrėjus. Kartais iš pradžių nenorime to daryti. O SEO specialistai pasakys, kad jeigu mes ieškome nuotraukų, tai jiems tai nesvarbu. Ir jei suteiksime jiems turinio, jie sakys, kad mūsų paieškos sistemos nieko neindeksuoja.

Ką su tuo daryti? Žinoma, mes suteiksime vartotojui HTML. Generuoti rankiniu būdu nėra komme il faut, todėl norime naudoti šablonus. Tam yra biblioteka lua-resty-template.

OpenResty: paverčia NGINX visaverčiu programų serveriu

Tikriausiai matėte tris baisias raides OPM. „OpenResty“ yra su savo paketų tvarkykle, per kurią galite įdiegti daugybę skirtingų modulių, visų pirma, lua-resty-template. Tai paprastas šablonų variklis, panašus į Django šablonus. Ten galite rašyti kodą ir atlikti kintamųjų pakeitimą.

Dėl to viskas atrodys maždaug taip:

OpenResty: paverčia NGINX visaverčiu programų serveriu

Paėmėme duomenis ir pateikėme šabloną, vėlgi dviem eilutėmis. Vartotojas patenkintas, gavo kačių. Kadangi praplėtėme užklausą, jis gavo ir kačiukų kailinį ruonį. Niekada negali žinoti, galbūt jis ieškojo būtent to, bet negalėjo teisingai suformuluoti savo prašymo.

Viskas puiku, bet mes kuriami ir kol kas nenorime to rodyti vartotojams. Padarykime įgaliojimą. Norėdami tai padaryti, pažiūrėkime, kaip NGINX apdoroja užklausą OpenResty sąlygomis:

  • Pirmas etapas - naudotis, kai vartotojas ką tik atvyko, ir žiūrėjome į jį pagal antraštes, pagal IP adresą ir kitus duomenis. Galime iš karto jį nutraukti, jei mums tai nepatinka. Tai gali būti naudojama autorizuojant arba, jei gauname daug užklausų, šiame etape galime lengvai jas nutraukti.
  • perrašyti. Perrašome kai kuriuos užklausos duomenis.
  • turinys. Pateikiame turinį vartotojui.
  • antraštės filtras. Pakeičiame atsakymų antraštes. Jei naudojome proxy_pass, kai kurias antraštes galime perrašyti prieš pateikdami jas vartotojui.
  • kūno filtras. Mes galime pakeisti kūną.
  • prisijungti - medienos ruoša. Galite rašyti žurnalus elasticsearch be papildomo sluoksnio.

Mūsų įgaliojimas atrodys maždaug taip:

OpenResty: paverčia NGINX visaverčiu programų serveriu

Prie to pridėsime tai location, kurį aprašėme anksčiau, ir įdėkite ten šį kodą:

OpenResty: paverčia NGINX visaverčiu programų serveriu

Pažiūrime, ar turime slapuko žetoną. Jei ne, prašome leidimo. Vartotojai yra gudrūs ir gali atspėti, kad jiems reikia nustatyti slapuko žetoną. Todėl mes taip pat įdėsime jį į Redis:

OpenResty: paverčia NGINX visaverčiu programų serveriu

Kodas dirbti su Redis yra labai paprastas ir niekuo nesiskiria nuo kitų kalbų. Tuo pačiu metu visa įvestis / išvestis čia ir ten nėra blokuojama. Jei rašote sinchroninį kodą, jis veikia asinchroniškai. Beveik kaip Geventas, bet atliktas gerai.

OpenResty: paverčia NGINX visaverčiu programų serveriu

Atlikime patį autorizavimą:

OpenResty: paverčia NGINX visaverčiu programų serveriu

Sakome, kad turime perskaityti užklausos turinį. Gauname POST argumentus ir patikriname, ar teisingi prisijungimo duomenys ir slaptažodis. Jei jie neteisingi, mes kreipiamės į jus dėl leidimo. Ir jei teisingai, parašykite žetoną Redis:

OpenResty: paverčia NGINX visaverčiu programų serveriu

Nepamirškite nustatyti slapuko, tai taip pat daroma dviem eilutėmis:

OpenResty: paverčia NGINX visaverčiu programų serveriu

Pavyzdys paprastas ir spekuliatyvus. Žinoma, mes nedarysime paslaugos, rodančios žmonėms kates. Bet kas mus žino. Taigi pažiūrėkime, ką galima padaryti gamyboje.

  • Minimalistinis backend. Kartais mums reikia išvesti tik šiek tiek duomenų į užpakalinę programą: kažkur reikia įterpti datą, kažkur parodyti sąrašą, pasakyti, kiek vartotojų šiuo metu yra svetainėje, pridėti skaitiklį arba statistiką. Kažkas tokio mažo. Kai kuriuos minimalius gabalus galima padaryti labai lengvai. Tai padarys tai greita, paprasta ir puiku.
  • Išankstinis duomenų apdorojimas. Kartais mes norime įterpti reklamą į savo puslapį ir gauname šią reklamą naudodami API užklausas. Čia tai padaryti labai paprasta. Neapkrauname savo backend, kuris jau sėdi ir sunkiai dirba. Čia galite pasiimti ir atsiimti. Galime sujungti kai kuriuos JS arba, priešingai, atjungti ir ką nors iš anksto apdoroti prieš pateikdami jį vartotojui.
  • Fasadas mikroservisui. Tai irgi labai geras atvejis, aš jį įgyvendinau. Prieš tai dirbau įmonėje „Tenzor“, kuri užsiima elektroninių ataskaitų teikimu ir teikia ataskaitas maždaug pusei šalies juridinių asmenų. Sukūrėme paslaugą, daug dalykų ten buvo daroma naudojant tą patį mechanizmą: maršruto parinkimas, autorizavimas ir kt.
    „OpenResty“ gali būti naudojamas kaip jūsų mikropaslaugų klijai, suteikiantys vieną prieigą prie visko ir vieną sąsają. Kadangi mikroservisus galima parašyti taip, kad čia turi Node.js, čia PHP, čia Python, čia kažkoks Erlang reikalas, suprantame, kad nenorime visur perrašyti to paties kodo. Todėl „OpenResty“ galima prijungti prie priekio.

  • Statistika ir analitika. Paprastai NGINX yra prie įėjimo, o visos užklausos vyksta per jį. Būtent šioje vietoje labai patogu rinkti. Galite iš karto ką nors apskaičiuoti ir kur nors įkelti, pavyzdžiui, Elasticsearch, Logstash, arba tiesiog įrašyti į žurnalą ir tada kur nors išsiųsti.
  • Kelių vartotojų sistemos. Pavyzdžiui, internetinius žaidimus taip pat labai gera kurti. Šiandien Keiptaune Aleksandras Gladyshas kalbės apie tai, kaip greitai sukurti kelių žaidėjų žaidimo prototipą naudojant „OpenResty“.
  • Užklausų filtravimas (WAF). Šiais laikais madinga kurti visokias žiniatinklio programų užkardas, jas teikia daugybė paslaugų. Naudodami OpenResty galite sukurti žiniatinklio programos užkardą, kuri paprastai ir lengvai filtruos užklausas pagal jūsų poreikius. Jei turite Python, tuomet jūs suprantate, kad PHP jums tikrai nebus įdėta, nebent, žinoma, jį sukursite kur nors iš konsolės. Jūs žinote, kad turite MySQL ir Python. Tikriausiai jie gali bandyti atlikti kokį nors katalogo perėjimą ir ką nors įvesti į duomenų bazę. Todėl galite greitai ir pigiai išfiltruoti keistas užklausas tiesiai priekyje.
  • Bendruomenė. Kadangi „OpenResty“ sukurtas ant NGINX, jis turi papildomą – tai NGINX bendruomenė. Jis yra labai didelis, o nemaža dalis klausimų, kuriuos turėsite iš pradžių, jau išsprendė NGINX bendruomenė.

    Lua kūrėjai. Vakar kalbėjausi su vaikinais, kurie atėjo į HighLoad++ treniruočių dieną ir išgirdau, kad Lua parašyta tik Tarantool. Tai netiesa, daug kas parašyta Lua kalba. Pavyzdžiai: „OpenResty“, „Prosody XMPP“ serveris, „Love2D“ žaidimų variklis, „Lua“ scenarijus sukurtas „Warcraft“ ir kitur. Yra daug Lua kūrėjų, jie turi didelę ir reaguojančią bendruomenę. Visi mano Lua klausimai buvo išspręsti per kelias valandas. Kai rašai į adresų sąrašą, tiesiog per kelias minutes jau yra krūva atsakymų, aprašančių kas ir kaip, kas yra kas. Tai gerai. Deja, tokios malonios, dvasingos bendruomenės yra ne visur.
    Yra „OpenResty“ skirtas „GitHub“, kuriame galite išspręsti problemą, jei kas nors sugenda. „Google Groups“ yra adresatų sąrašas, kuriame galite aptarti bendras problemas, yra adresų sąrašas kinų kalba – niekada negali žinoti, galbūt nekalbi angliškai, bet žinai kinų kalbą.

rezultatai

  • Tikiuosi, kad man pavyko pasakyti, kad OpenResty yra labai patogi sistema, pritaikyta žiniatinkliui.
  • Ji turi mažą įėjimo barjerą, nes kodas panašus į tai, ką rašome, kalba gana paprasta ir minimalistinė.
  • Tai suteikia asinchroninį įvestį / išvestį be atgalinių skambučių, neturėsime jokių makaronų, kaip kartais galime rašyti NodeJS.
  • Jį lengva įdiegti, nes mums reikia tik NGINX su reikiamu moduliu ir mūsų kodu, ir viskas veikia iš karto.
  • Didelė ir jautri bendruomenė.

Detaliai nepasakojau, kaip atliekamas maršrutas, tai pasirodė labai ilga istorija.

Dėkojame už dėmesį!


Vladimiras Protasovas - „OpenResty“: paverčia NGINX visaverčiu programų serveriu

Šaltinis: www.habr.com

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