OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

OpenResty: verander NGINX in 'n volwaardige toepassingsbedienerOns publiseer die transkripsie van die verslag van die konferensie weer Hoëlaai++ 2016, wat op 7-8 November verlede jaar in Skolkovo naby Moskou gehou is. Vladimir Protasov vertel hoe om NGINX-funksionaliteit uit te brei met OpenResty en Lua.

Hallo almal, my naam is Vladimir Protasov, ek werk vir Parallels. Ek vertel jou 'n bietjie van myself. Ek spandeer driekwart van my lewe om kode te skryf. Ek het tot in die kern 'n programmeerder geword in die letterlike sin: ek sien soms kode in my drome. 'n Kwart van die lewe is industriële ontwikkeling, die skryf van kode wat reguit in produksie gaan. Kode wat sommige van julle gebruik, maar dit nie ken nie.

Om jou te laat weet hoe erg dit was. Toe ek 'n bietjie junior was, het ek ingekom en hulle het vir my hierdie twee teragreep-databasisse gegee. Dit is nou hier vir almal highload. Ek het na konferensies gegaan en gevra: “Kêrels, sê vir my, het julle groot data, is alles cool? Hoeveel basisse het jy daar? Hulle het my geantwoord: "Ons het 100 gigagrepe!" Ek het gesê: "Cool, 100 gigagrepe!" En ek het by myself gedink hoe om die poker face netjies te red. Jy dink, ja, die ouens is gaaf, en dan kom jy terug en peuter met hierdie multi-teragreep databasisse. En dit is om 'n junior te wees. Kan jy jou indink watter treffer dit is?

Ek ken meer as 20 programmeertale. Dit is wat ek in die loop van die werk moes uitvind. Hulle gee jou kode in Erlang, in C, in C++, in Lua, in Python, in Ruby, in iets anders, en jy moet dit alles sny. Oor die algemeen moes ek. Dit was nie moontlik om die presiese getal te bereken nie, maar iewers rondom 20 het die getal verlore gegaan.

Aangesien almal hier weet wat Parallels is en wat ons doen, sal ek nie praat oor hoe cool ons is en wat ons doen nie. Ek sal jou net vertel dat ons 13 kantore regoor die wêreld het, meer as 300 werknemers, ontwikkeling in Moskou, Tallinn en Malta. As jy wil, kan jy Malta toe neem en trek, as dit koud is in die winter en jy moet jou rug warm maak.

Spesifiek, ons departement skryf in Python 2. Ons is in besigheid en ons het nie tyd om modieuse tegnologie bekend te stel nie, so ons ly. Ons het Django, want dit het alles, en ons het die oormaat gevat en weggegooi. Ook MySQL, Redis en NGINX. Ons het ook baie ander oulike goed. Ons het MongoDB, ons het hase wat rondhardloop, ons het net niks nie - maar dit is nie myne nie, en ek doen dit nie.

OpenResty

Ek het van myself vertel. Kom ons kyk waaroor ek vandag gaan praat:

  • Wat is OpenResty en waarmee word dit geëet?
  • Waarom die wiel herontdek as ons Python, NodeJS, PHP, Go en ander oulike goed het waarmee almal tevrede is?
  • En 'n paar werklike voorbeelde. Ek moes die verslag baie afsny, want ek het dit vir 3,5 uur gekry, so daar sal min voorbeelde wees.

OpenResty is NGINX. Danksy hom het ons 'n volwaardige webbediener, wat goed geskryf is, dit werk vinnig. Ek dink die meeste van ons gebruik NGINX in produksie. Julle weet almal dat hy vinnig en cool is. Hulle het koel sinchrone I / O daarin gemaak, so ons hoef niks te fiets op dieselfde manier as wat geet in Python gery is nie. Gevent is gaaf, wonderlik, maar as jy C-kode skryf en iets loop verkeerd met gevent, sal jy mal word om dit te ontfout. Ek het ondervinding gehad: dit het twee hele dae geneem om uit te vind wat daar verkeerd geloop het. As iemand nie vir 'n paar weke tevore gegrawe het nie, die probleem gevind het, dit op die internet geskryf het, en Google het dit nie gekry nie, dan sou ons heeltemal mal geword het.

NGINX doen reeds kas en statiese inhoud. Jy hoef nie bekommerd te wees oor hoe om dit menslik te doen nie, sodat jy nie iewers stadiger ry nie, sodat jy nie iewers beskrywers verloor nie. Nginx is baie gerieflik om te ontplooi, jy hoef nie te dink oor wat om te neem nie - WSGI, PHP-FPM, Gunicorn, Unicorn. Nginx is geïnstalleer, gegee aan die admins, hulle weet hoe om daarmee te werk. Nginx hanteer versoeke op 'n gestruktureerde manier. Ek sal 'n bietjie later hieroor praat. Kortom, hy het 'n fase wanneer hy pas die versoek aanvaar het, wanneer hy verwerk het en wanneer hy die inhoud aan die gebruiker gegee het.

Nginx is cool, maar daar is een probleem: dit is nie buigsaam genoeg nie, selfs met al daardie cool kenmerke wat die ouens in die konfigurasie gedruk het, ten spyte van die feit dat dit aangepas kan word. Hierdie krag is nie genoeg nie. Daarom het die ouens van Taobao eens, ek dink so agt jaar gelede, Lua daarin ingebou. Wat gee hy?

  • Grootte. Dit is klein. LuaJIT gee iewers ongeveer 100-200 kilogrepe geheue bokoste en minimale werkverrigting bokoste.
  • Spoed. Die LuaJIT-tolk is naby aan C in baie situasies, in sommige situasies verloor dit aan Java, in sommige haal dit dit verby. Vir 'n rukkie is dit as moderne, die coolste JIT-samesteller beskou. Nou is daar koeler, maar hulle is baie swaar, byvoorbeeld dieselfde V8. Sommige JS-tolke en Java HotSpot is op sommige punte vinniger, maar verloor steeds op sommige punte.
  • Maklik om te leer. As jy byvoorbeeld 'n Perl-kodebasis het en jy bespreek nie, sal jy nie Perl-programmeerders vind nie. Omdat hulle nie daar is nie, is hulle almal weggeneem, en dit is lank en moeilik om hulle te leer. As jy programmeerders vir iets anders wil hê, moet hulle dalk ook heropgelei of gevind word. In die geval van Lua is alles eenvoudig. Lua kan binne drie dae deur enige junior aangeleer word. Dit het my ongeveer twee uur geneem om dit uit te vind. Twee uur later was ek reeds besig om kode in produksie te skryf. Sowat 'n week later is hy reguit produksie toe en vertrek.

Gevolglik lyk dit so:

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Hier is baie. OpenResty het 'n klomp modules saamgestel, beide luash en enjins. En jy het alles gereed - ontplooi en werk.

voorbeelde

Genoeg van die lirieke, kom ons gaan aan na die kode. Hier is 'n bietjie Hello World:

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Wat is daar? dit is die enjin se ligging. Ons is nie bekommerd nie, ons skryf nie ons eie roetes nie, ons neem nie een of ander klaargemaakte een nie - ons het dit reeds in NGINX, ons leef goed en lui.

content_by_lua_block is 'n blok wat sê dat ons inhoud bedien deur 'n Lua-skrif te gebruik. Ons neem 'n enjins veranderlike remote_addr en glip dit in string.format. Dit is dieselfde as sprintf, net in Lua, net korrek. En ons gee dit aan die kliënt.

As gevolg hiervan sal dit so lyk:

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Maar terug na die regte wêreld. In produksie ontplooi niemand Hello World nie. Ons toepassing gaan gewoonlik na die databasis of iewers anders en die meeste van die tyd wag dit vir 'n antwoord.

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Sit net en wag. Dit is nie baie goed nie. Wanneer 100.000 XNUMX gebruikers kom, is dit vir ons baie moeilik. Daarom, kom ons gebruik 'n eenvoudige toepassing as 'n voorbeeld. Ons sal prente soek, byvoorbeeld katte. Net ons sal nie net soek nie, ons sal die sleutelwoorde uitbrei en, as die gebruiker na "katjies" gesoek het, sal ons katte, fluffies, ensovoorts vind. Eerstens moet ons die versoekdata op die agterkant kry. Dit lyk so:

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Twee reëls laat jou toe om GET-parameters op te tel, geen komplikasies nie. Dan kry ons byvoorbeeld hierdie inligting vanaf 'n databasis met 'n tabel per sleutelwoord en uitbreiding deur 'n gewone SQL-navraag te gebruik. Alles is eenvoudig. Dit lyk so:

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Ons verbind die biblioteek resty.mysql, wat ons reeds in die kit het. Ons hoef niks te installeer nie, alles is gereed. Spesifiseer hoe om te koppel en 'n SQL-navraag te maak:

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Dit is 'n bietjie skrikwekkend, maar dit werk. Hier is 10 die limiet. Ons trek 10 plate uit, ons is lui, ons wil nie meer wys nie. In SQL het ek vergeet van die limiet.

Dan vind ons beelde vir alle navrae. Ons versamel 'n klomp versoeke en vul 'n Lua-tabel in wat genoem word reqs, en doen ngx.location.capture_multi.

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Al hierdie versoeke gaan parallel, en die antwoorde word aan ons terugbesorg. Die looptyd is gelyk aan die reaksietyd van die stadigste een. As ons almal binne 50 millisekondes terugskiet, en ons het honderd versoeke gestuur, dan sal ons binne 50 millisekondes 'n antwoord ontvang.

Aangesien ons lui is en nie HTTP-hantering en kas wil skryf nie, sal ons NGINX alles vir ons laat doen. Soos jy gesien het, was daar 'n versoek vir url/fetch, hier is hy:

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Ons maak eenvoudig proxy_pass, spesifiseer waar om te kas, hoe om dit te doen, en alles werk vir ons.

Maar dit is nie genoeg nie, ons moet steeds die data aan die gebruiker gee. Die eenvoudigste idee is om alles maklik in twee reëls na JSON te serialiseer. Ons gee Content-Type, ons gee JSON.

Maar daar is een probleem: die gebruiker wil nie JSON lees nie. Ons moet front-end ontwikkelaars lok. Soms is ons aanvanklik nie lus om dit te doen nie. Ja, en SEO-spesialiste sal sê dat as ons prente soek, dan gee hulle nie om nie. En as ons vir hulle 'n bietjie inhoud gee, sal hulle sê dat ons soekenjins niks indekseer nie.

Wat om daarmee te doen? Natuurlik sal ons die gebruiker HTML gee. Genereer met handvatsels is nie comme il faut nie, so ons wil sjablone gebruik. Daar is 'n biblioteek hiervoor lua-resty-template.

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Jy het seker die drie gevreesde letters OPM gesien. OpenResty kom met sy eie pakketbestuurder, waardeur u 'n klomp verskillende modules kan installeer, veral, lua-resty-template. Dit is 'n eenvoudige sjabloonenjin soortgelyk aan Django-sjablone. Daar kan jy kode skryf en veranderlike vervanging doen.

As gevolg hiervan sal alles soos volg lyk:

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Ons het die data geneem en die sjabloon weer in twee reëls weergegee. Die gebruiker is gelukkig, het katte. Aangesien ons die versoek uitgebrei het, het hy ook 'n pelsrob vir katjies ontvang. Jy weet nooit, dalk het hy daarna gesoek, maar hy kon nie sy versoek reg formuleer nie.

Alles is cool, maar ons is in ontwikkeling, en ons wil nog nie gebruikers wys nie. Kom ons doen 'n magtiging. Om dit te doen, kom ons kyk hoe NGINX die versoek hanteer in terme van OpenResty:

  • Eerste fase - toegang, toe die gebruiker net gekom het, en ons het na hom gekyk deur opskrifte, volgens IP-adres, deur ander data. Jy kan dit dadelik afkap as ons nie daarvan hou nie. Dit kan vir magtiging gebruik word, of as ons baie versoeke ontvang, kan ons dit maklik in hierdie fase kap.
  • herskryf. Herskryf sommige versoekdata.
  • inhoud. Ons gee inhoud aan die gebruiker.
  • kop filter. Verander die antwoordopskrifte. As ons gebruik het proxy_pass, kan ons 'n paar kopskrifte herskryf voordat dit aan die gebruiker gegee word.
  • liggaam filter. Ons kan die liggaam verander.
  • teken - aanteken. Dit is moontlik om logs in elasticsearch te skryf sonder 'n bykomende laag.

Ons magtiging sal iets soos volg lyk:

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Ons sal dit daarby voeg location, wat ons voorheen beskryf het, en plaas die volgende kode daar:

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Ons kyk of ons 'n koekietoken het. Indien nie, dan gooi ons magtiging op. Gebruikers is slinks en kan raai dat 'n koekietoken gestel moet word. Daarom sal ons dit ook in Redis plaas:

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Die kode om met Redis te werk is baie eenvoudig en verskil nie van ander tale nie. Terselfdertyd, alle invoer / uitset, wat daar is, wat hier is, dit blokkeer nie. As jy sinchroniese kode skryf, werk dit asinchronies. Soos met gevent, net goed gedoen.

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Kom ons doen die magtiging self:

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Ons sê dat ons die versoekliggaam moet lees. Ons ontvang POST-argumente, maak seker dat die login en wagwoord korrek is. As dit verkeerd is, gooi ons magtiging op. En as hulle korrek is, dan skryf ons die teken aan Redis:

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Moenie vergeet om die koekie te stel nie, dit word ook in twee reëls gedoen:

OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Die voorbeeld is eenvoudig, spekulatief. Ons sal natuurlik nie ’n diens maak wat katte vir mense wys nie. Maar wie ken ons. So kom ons gaan oor wat in produksie gedoen kan word.

  • Minimalistiese agterkant. Soms moet ons heelwat data aan die agterkant gee: iewers moet ons die datum vervang, iewers moet ons 'n soort lys vertoon, sê hoeveel gebruikers nou op die webwerf is, 'n teller of statistieke aandraai. Iets so klein. Sommige minimale stukke kan baie maklik gemaak word. Dit sal vinnig, maklik en wonderlik wees.
  • Datavoorverwerking. Soms wil ons advertensies in ons bladsy insluit, en ons neem hierdie advertensies saam met API-versoeke. Dit is baie maklik om hier te doen. Ons laai nie ons agterkant nie, wat reeds hard werk. Jy kan hier optel en afhaal. Ons kan 'n JS vorm of, inteendeel, iets losmaak, iets vooraf verwerk voordat ons dit aan die gebruiker gee.
  • Fasade vir mikrodiens. Dit is ook 'n baie goeie geval, ek het dit geïmplementeer. Voor dit het ek vir Tenzor gewerk, ’n elektroniese verslagdoeningsmaatskappy wat aan sowat die helfte van die regsentiteite in die land verslagdoening verskaf. Ons het 'n diens gemaak, baie dinge word daar gedoen met dieselfde meganisme: roetering, magtiging en meer.
    OpenResty kan gebruik word as die gom vir jou mikrodienste om 'n enkele toegang tot alles en 'n enkele koppelvlak te bied. Aangesien mikrodienste so geskryf kan word dat jy Node.js hier het, jy het PHP hier, jy het Python hier, daar is een of ander Erlang ding hier, ons verstaan ​​dat ons nie oral dieselfde kode wil oorskryf nie. Daarom kan OpenResty aan die voorkant ingeprop word.

  • Statistiek en analise. Gewoonlik is NGINX by die ingang, en alle versoeke gaan daardeur. Dit is op hierdie plek dat dit baie gerieflik is om te versamel. Jy kan dadelik iets bereken en dit iewers gooi, byvoorbeeld dieselfde Elasticsearch, Logstash, of dit net na die log skryf en dit dan iewers heen stuur.
  • Multi-gebruiker stelsels. Byvoorbeeld, aanlyn speletjies is ook baie goed om te doen. Vandag in Kaapstad sal Alexander Gladysh jou vertel hoe om vinnig 'n multispeler-speletjie met OpenResty te prototipeer.
  • Versoekfiltrering (WAF). Nou is dit modieus om allerhande webtoepassings-firewalls te maak, daar is baie dienste wat dit verskaf. Met die hulp van OpenResty kan jy vir jou 'n webtoepassing-firewall maak, wat versoeke eenvoudig en maklik volgens jou vereistes sal filter. As jy Python het, dan verstaan ​​jy dat PHP beslis nie by jou ingespuit sal word nie, tensy jy dit natuurlik enige plek vanaf die konsole kweek. Jy weet jy het MySQL en Python. Waarskynlik, hier kan hulle probeer om 'n soort gidsoorgang te doen en iets in die databasis in te spuit. Daarom kan jy dom versoeke vinnig en goedkoop reg aan die voorkant uitfiltreer.
  • Gemeenskap. Aangesien OpenResty op NGINX gebaseer is, het dit 'n bonus - dit is NGINX gemeenskap. Dit is baie groot, en baie van die vrae wat jy eers sal hê, is reeds deur die NGINX-gemeenskap beantwoord.

    Lua ontwikkelaars. Gister het ek met die ouens gepraat wat na die HighLoad ++ opleidingsdag gekom het en gehoor dat net Tarantool in Lua geskryf is. Dit is nie so nie, baie dinge is in Lua geskryf. Voorbeelde: OpenResty, Prosody XMPP-bediener, Love2D-speletjie-enjin, Lua is in Warcraft en elders geskryf. Daar is baie Lua-ontwikkelaars, hulle het 'n groot en responsiewe gemeenskap. Al my Lua-vrae is binne 'n paar uur beantwoord. Wanneer jy na die poslys skryf, is daar letterlik binne 'n paar minute reeds 'n klomp antwoorde, hulle beskryf wat en hoe, wat is wat. Dis wonderlik. Ongelukkig is so 'n vriendelike opregte gemeenskap nie oral nie.
    OpenResty het GitHub, waar jy 'n probleem kan oopmaak as iets breek. Daar is 'n poslys op Google Groups waar jy algemene kwessies kan bespreek, daar is 'n poslys in Chinees - jy weet nooit, miskien praat jy nie Engels nie, maar jy het kennis van Chinees.

Resultate van

  • Ek hoop ek kon oordra dat OpenResty 'n baie gerieflike raamwerk is wat vir die web aangepas is.
  • Dit het 'n lae toegangsdrempel, aangesien die kode soortgelyk is aan wat ons skryf, is die taal redelik eenvoudig en minimalisties.
  • Dit bied asynchrone I/O sonder terugbel, ons sal nie noedels hê nie, aangesien ons soms in NodeJS kan skryf.
  • Dit het 'n maklike ontplooiing, want ons benodig net NGINX met die regte module en ons kode, en alles werk dadelik.
  • Groot en responsiewe gemeenskap.

Ek het nie in detail vertel hoe roetering gedoen word nie, dit het geblyk 'n baie lang storie te wees.

Skep 'n nuwe weergawe!


Vladimir Protasov - OpenResty: verander NGINX in 'n volwaardige toepassingsbediener

Bron: will.com

Voeg 'n opmerking