OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi deplineRepublicăm transcrierea raportului de la conferință HighLoad ++ 2016, care a avut loc la Skolkovo, lângă Moscova, în perioada 7-8 noiembrie anul trecut. Vladimir Protasov spune cum să extindeți funcționalitatea NGINX cu OpenResty și Lua.

Salutare tuturor, numele meu este Vladimir Protasov, lucrez pentru Parallels. Îți voi spune puțin despre mine. Îmi petrec trei sferturi din viață scriind cod. Am devenit un programator de bază în sensul literal: uneori văd cod în visele mele. Un sfert din viață este dezvoltare industrială, scriind cod care intră direct în producție. Cod pe care unii dintre voi îl folosiți, dar nu îl cunoașteți.

Ca să vă spun cât de rău a fost. Când eram mic, am intrat și mi-au dat aceste două baze de date terabyte. Acum este aici pentru toată lumea. M-am dus la conferințe și am întrebat: „Băieți, spuneți-mi, aveți big data, e totul cool? Câte baze ai acolo? Mi-au răspuns: „Avem 100 de gigaocteți!” I-am spus: „Sunt, 100 de gigaocteți!” Și m-am gândit în sinea mea cum să salvez cu grijă fața de poker. Crezi că da, băieții sunt cool, iar apoi te întorci și te descurci cu aceste baze de date de mai mulți terabyte. Și asta înseamnă să fii junior. Vă puteți imagina ce hit este?

Cunosc peste 20 de limbaje de programare. Asta a trebuit să-mi dau seama în timpul muncii. Îți dau cod în Erlang, în C, în C++, în Lua, în Python, în Ruby, în altceva și trebuie să tai totul. În general, a trebuit. Nu s-a putut calcula numărul exact, dar undeva pe la 20 numărul s-a pierdut.

Din moment ce toată lumea de aici știe ce este Parallels și ce facem, nu voi vorbi despre cât de cool suntem și despre ce facem. Vă spun doar că avem 13 birouri în întreaga lume, peste 300 de angajați, dezvoltare în Moscova, Tallinn și Malta. Dacă doriți, puteți să luați și să vă mutați în Malta, dacă iarna este frig și trebuie să vă încălziți spatele.

Mai exact, departamentul nostru scrie în Python 2. Suntem în afaceri și nu avem timp să introducem tehnologii la modă, așa că suferim. Avem Django, pentru că are de toate, și am luat excesul și l-am aruncat. De asemenea, MySQL, Redis și NGINX. Avem și o mulțime de alte lucruri interesante. Avem MongoDB, avem iepuri care rulează, pur și simplu nu avem nimic - dar nu este al meu și nu o fac.

OpenResty

am spus despre mine. Să vedem despre ce voi vorbi astăzi:

  • Ce este OpenResty și cu ce se mănâncă?
  • De ce să reinventăm roata când avem Python, NodeJS, PHP, Go și alte lucruri interesante de care toată lumea este mulțumită?
  • Și câteva exemple din viața reală. A trebuit să reduc foarte mult raportul, pentru că l-am primit pentru 3,5 ore, așa că vor fi puține exemple.

OpenResty este NGINX. Datorită lui, avem un server web cu drepturi depline, care este bine scris, funcționează rapid. Cred că majoritatea dintre noi folosim NGINX în producție. Știți cu toții că este rapid și cool. Au făcut I/O sincrone grozave în el, așa că nu trebuie să ciclăm nimic în același mod în care a fost ciclat gevent în Python. Gevent este grozav, grozav, dar dacă scrieți codul C și ceva nu merge bine cu gevent, veți înnebuni depanând-o. Aveam experiență: a durat două zile întregi ca să-mi dau seama ce a mers prost acolo. Dacă cineva nu ar fi săpat cu câteva săptămâni înainte, ar fi găsit problema, ar fi scris-o pe internet și Google nu ar fi găsit-o, atunci am fi luat-o razna.

NGINX face deja stocarea în cache și conținut static. Nu trebuie să vă faceți griji despre cum să o faceți uman, pentru a nu încetini undeva, pentru a nu pierde descriptori undeva. Nginx este foarte convenabil de implementat, nu trebuie să vă gândiți ce să luați - WSGI, PHP-FPM, Gunicorn, Unicorn. Nginx a fost instalat, dat administratorilor, ei știu să lucreze cu el. Nginx gestionează cererile într-un mod structurat. Voi vorbi despre asta puțin mai târziu. Pe scurt, are o fază când tocmai a acceptat cererea, când a procesat și când a dat conținutul utilizatorului.

Nginx este cool, dar există o problemă: nu este suficient de flexibil chiar și cu toate acele caracteristici interesante pe care băieții le-au împins în configurație, în ciuda faptului că poate fi personalizat. Această putere nu este suficientă. Prin urmare, băieții de la Taobao, cred că acum vreo opt ani, au construit Lua în ea. Ce dă el?

  • Dimensiune. Este mic. LuaJIT oferă undeva în jur de 100-200 de kiloocteți de supraîncărcare de memorie și supraîncărcare minimă de performanță.
  • Viteză. Interpretul LuaJIT este aproape de C în multe situații, în unele situații pierde în fața Java, în unele îl depășește. Pentru o vreme, a fost considerat de ultimă generație, cel mai tare compilator JIT. Acum sunt unele mai cool, dar sunt foarte grele, de exemplu, același V8. Unele interpreți JS și Java HotSpot sunt mai rapide în unele momente, dar pierd în unele momente.
  • Usor de invatat. Dacă aveți, să zicem, o bază de cod Perl și nu sunteți Booking, nu veți găsi programatori Perl. Pentru că nu sunt acolo, toți au fost duși și este lung și greu să-i înveți. Dacă doriți programatori pentru altceva, este posibil ca aceștia să fie, de asemenea, pregătiți sau găsiți. În cazul lui Lua, totul este simplu. Lua poate fi învățată de orice junior în trei zile. Mi-a luat vreo două ore să-mi dau seama. Două ore mai târziu, scriam deja cod în producție. Aproximativ o săptămână mai târziu, a trecut direct la producție și a plecat.

Ca urmare, arată astfel:

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Sunt multe aici. OpenResty a asamblat o grămadă de module, atât luash, cât și motoare. Și aveți totul gata - implementat și funcțional.

exemple

Destul de versuri, să trecem la cod. Iată un mic Hello World:

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Ce este acolo? aceasta este locatia motorului. Nu ne facem griji, nu ne scriem propria rută, nu luăm una gata făcută - o avem deja în NGINX, trăim bine și leneș.

content_by_lua_block este un bloc care spune că difuzăm conținut folosind un script Lua. Luăm o variabilă engins remote_addr și strecură-l în string.format. Aceasta este la fel ca sprintf, numai în Lua, numai corect. Și o dăm clientului.

Ca rezultat, va arăta astfel:

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Dar înapoi la lumea reală. În producție, nimeni nu implementează Hello World. Aplicația noastră merge de obicei la baza de date sau în altă parte și de cele mai multe ori așteaptă un răspuns.

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Doar sta și așteaptă. Nu e foarte bine. Când vin 100.000 de utilizatori, ne este foarte greu. Prin urmare, să folosim o aplicație simplă ca exemplu. Vom căuta imagini, de exemplu, pisici. Numai că nu vom căuta doar, vom extinde cuvintele cheie și, dacă utilizatorul a căutat „pisici”, vom găsi pisici, pufoase și așa mai departe. Mai întâi trebuie să obținem datele solicitării pe backend. Arata cam asa:

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Două linii vă permit să preluați parametrii GET, fără complicații. Apoi, de exemplu, obținem aceste informații dintr-o bază de date cu un tabel după cuvânt cheie și extensie folosind o interogare SQL obișnuită. Totul este simplu. Arata cam asa:

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Conectăm biblioteca resty.mysql, pe care o avem deja în kit. Nu trebuie să instalăm nimic, totul este gata. Specificați cum să vă conectați și să faceți o interogare SQL:

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Este puțin înfricoșător, dar funcționează. Aici 10 este limita. Scoatem 10 discuri, suntem leneși, nu vrem să arătăm mai mult. În SQL, am uitat de limită.

Apoi găsim imagini pentru toate interogările. Colectăm o grămadă de solicitări și completăm un tabel Lua numit reqs, si fa ngx.location.capture_multi.

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Toate aceste solicitări merg în paralel, iar răspunsurile ne sunt returnate. Timpul de rulare este egal cu timpul de răspuns al celui mai lent. Dacă toți tragem înapoi în 50 de milisecunde și am trimis o sută de solicitări, atunci vom primi un răspuns în 50 de milisecunde.

Deoarece suntem leneși și nu vrem să scriem manipularea HTTP și stocarea în cache, vom face ca NGINX să facă totul pentru noi. După cum ați văzut, a fost o cerere pentru url/fetch, aici era:

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Facem simplu proxy_pass, specificați unde să stocați în cache, cum să o faceți și totul funcționează pentru noi.

Dar acest lucru nu este suficient, mai trebuie să dăm datele utilizatorului. Cea mai simplă idee este să serializați totul în JSON, ușor, în două rânduri. Dăm Content-Type, dăm JSON.

Dar există o dificultate: utilizatorul nu dorește să citească JSON. Trebuie să atragem dezvoltatori front-end. Uneori nu avem chef să o facem la început. Da, iar specialiștii SEO vor spune că dacă căutăm poze, atunci nu le pasă. Și dacă le dăm ceva conținut, vor spune că motoarele noastre de căutare nu indexează nimic.

Ce să faci cu el? Desigur, vom oferi utilizatorului HTML. Generarea cu mânere nu este comme il faut, așa că dorim să folosim șabloane. Există o bibliotecă pentru asta lua-resty-template.

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Trebuie să fi văzut cele trei litere de temut OPM. OpenResty vine cu propriul manager de pachete, prin care puteți instala o mulțime de module diferite, în special, lua-resty-template. Este un motor de șabloane simplu similar șabloanelor Django. Acolo puteți scrie cod și face înlocuirea variabilelor.

Ca rezultat, totul va arăta cam așa:

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Am luat datele și am redat șablonul din nou în două rânduri. Utilizatorul este fericit, are pisici. Deoarece am extins cererea, a primit și o sigiliu de blană pentru pisoi. Nu se știe niciodată, poate că o căuta, dar nu și-a putut formula corect cererea.

Totul este cool, dar suntem în dezvoltare și nu vrem să le arătăm încă utilizatorilor. Hai sa facem o autorizatie. Pentru a face acest lucru, să vedem cum NGINX gestionează cererea în ceea ce privește OpenResty:

  • Primă fază - acces, când tocmai a venit utilizatorul și ne-am uitat la el după anteturi, după adresa IP, după alte date. Puteți să-l tăiați imediat dacă nu ne place. Acesta poate fi folosit pentru autorizare, sau dacă primim o mulțime de solicitări, le putem tăia cu ușurință în această fază.
  • rescrie. Rescrierea unor date de solicitare.
  • conţinut. Oferim conținut utilizatorului.
  • filtru de antet. Schimbați anteturile răspunsului. Dacă am folosit proxy_pass, putem rescrie câteva anteturi înainte de a le oferi utilizatorului.
  • filtru de corp. Putem schimba corpul.
  • log - Logare. Este posibil să scrieți jurnalele în elasticsearch fără un strat suplimentar.

Autorizarea noastră va arăta cam așa:

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

O vom adăuga la asta location, pe care am descris-o mai înainte și am pus următorul cod acolo:

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Ne uităm să vedem dacă avem un simbol cookie. Dacă nu, atunci aruncăm pe autorizare. Utilizatorii sunt vicleni și pot ghici că trebuie setat un simbol cookie. Prin urmare, îl vom pune și în Redis:

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Codul pentru lucrul cu Redis este foarte simplu și nu este diferit de alte limbi. În același timp, toate intrările / ieșirile, ce este acolo, ce este aici, nu se blochează. Dacă scrieți cod sincron, atunci acesta funcționează asincron. Ca și cu gevent, doar făcut bine.

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Să facem autorizarea în sine:

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Spunem că trebuie să citim corpul cererii. Primim argumente POST, verificați dacă login-ul și parola sunt corecte. Dacă este incorectă, atunci aruncăm autorizația. Și dacă sunt corecte, atunci îi scriem jetonul lui Redis:

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Nu uitați să setați cookie-ul, acest lucru se face și în două rânduri:

OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Exemplul este simplu, speculativ. Desigur, nu vom face un serviciu care să arate pisicile oamenilor. Dar cine ne cunoaște. Deci, să trecem peste ce se poate face în producție.

  • Backend minimalist. Uneori trebuie să furnizăm destul de multe date către backend: undeva trebuie să înlocuim data, undeva trebuie să afișăm un fel de listă, să spunem câți utilizatori sunt acum pe site, să înșurubăm un contor sau statistici. Ceva atât de mic. Unele piese minimale pot fi realizate foarte ușor. Acest lucru va fi rapid, ușor și grozav.
  • Preprocesarea datelor. Uneori dorim să încorporam anunțuri în pagina noastră și luăm aceste anunțuri cu solicitări API. Acest lucru este foarte ușor de făcut aici. Nu ne încărcăm backend-ul, care lucrează deja din greu. Puteți ridica și ridica aici. Putem modela niște JS sau, dimpotrivă, dezlipim, preprocesăm ceva înainte de a-l oferi utilizatorului.
  • Fațadă pentru microserviciu. Acesta este și un caz foarte bun, l-am implementat. Înainte de asta, am lucrat pentru Tenzor, o companie de raportare electronică care oferă raportare pentru aproximativ jumătate dintre entitățile juridice din țară. Am realizat un service, multe lucruri se fac acolo folosind același mecanism: rutare, autorizare și multe altele.
    OpenResty poate fi folosit ca lipici pentru microservicii tale pentru a oferi un singur acces la tot și o singură interfață. Deoarece microservicii pot fi scrise în așa fel încât să aveți Node.js aici, aveți PHP aici, aveți Python aici, există ceva Erlang aici, înțelegem că nu vrem să rescriem același cod peste tot. Prin urmare, OpenResty poate fi conectat în față.

  • Statistică și analiză. De obicei, NGINX este la intrare și toate cererile trec prin ea. În acest loc este foarte convenabil să colectezi. Puteți să calculați imediat ceva și să îl aruncați undeva, de exemplu, același Elasticsearch, Logstash, sau pur și simplu să îl scrieți în jurnal și apoi să îl trimiteți undeva.
  • Sisteme multi-utilizator. De exemplu, jocurile online sunt, de asemenea, foarte bune de făcut. Astăzi, în Cape Town, Alexander Gladysh vă va spune cum să prototipați rapid un joc multiplayer folosind OpenResty.
  • Filtrarea cererilor (WAF). Acum este la modă să faci tot felul de firewall-uri pentru aplicații web, sunt multe servicii care le oferă. Cu ajutorul OpenResty, vă puteți face un firewall de aplicație web, care va filtra simplu și ușor cererile în funcție de cerințele dumneavoastră. Dacă aveți Python, atunci înțelegeți că PHP cu siguranță nu vă va fi injectat, decât dacă, desigur, îl generați oriunde din consolă. Știți că aveți MySQL și Python. Probabil, aici ei pot încerca să facă un fel de parcurgere a directorului și să injecteze ceva în baza de date. Prin urmare, puteți filtra cererile stupide rapid și ieftin chiar din față.
  • Comunitate. Deoarece OpenResty se bazează pe NGINX, are un bonus - acesta este Comunitatea NGINX. Este foarte mare și multe dintre întrebările pe care le veți avea la început au primit deja răspunsuri de către comunitatea NGINX.

    Dezvoltatorii Lua. Ieri am vorbit cu băieții care au venit la ziua de antrenament HighLoad ++ și am auzit că doar Tarantool este scris în Lua. Nu este așa, multe lucruri sunt scrise în Lua. Exemple: OpenResty, server Prosody XMPP, motor de joc Love2D, Lua este scriptat în Warcraft și în alte părți. Există o mulțime de dezvoltatori Lua, au o comunitate mare și receptivă. Toate întrebările mele Lua au primit răspuns în câteva ore. Când scrii pe lista de corespondență, literalmente în câteva minute există deja o grămadă de răspunsuri, ele descriu ce și cum, ce este ce. E minunat. Din păcate, o comunitate atât de amabilă și sinceră nu este peste tot.
    OpenResty are GitHub, unde puteți deschide o problemă dacă se strica ceva. Există o listă de corespondență pe Grupuri Google unde puteți discuta probleme generale, există o listă de corespondență în chineză - nu se știe niciodată, poate că nu vorbiți engleza, dar aveți cunoștințe de chineză.

Rezultatele

  • Sper că am putut să transmit că OpenResty este un cadru web foarte convenabil.
  • Are un prag de intrare scăzut, deoarece codul este similar cu ceea ce scriem noi, limbajul este destul de simplu și minimalist.
  • Oferă I/O asincron fără apeluri inverse, nu vom avea tăiței, deoarece uneori putem scrie în NodeJS.
  • Are o implementare ușoară, pentru că avem nevoie doar de NGINX cu modulul potrivit și codul nostru și totul funcționează imediat.
  • Comunitate mare și receptivă.

Nu am spus în detaliu cum se face rutarea, s-a dovedit a fi o poveste foarte lungă.

Vă mulțumim pentru atenție!


Vladimir Protasov - OpenResty: transformarea NGINX într-un server de aplicații cu drepturi depline

Sursa: www.habr.com

Adauga un comentariu