OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletuPublicemu di novu a trascrizione di u rapportu di a cunferenza HighLoad ++ 2016, chì hè accadutu in Skolkovo vicinu à Mosca u Novembre 7-8 l'annu passatu. Vladimir Protasov spiega cumu allargà a funziunalità NGINX cù OpenResty è Lua.

Ciao à tutti, mi chjamu Vladimir Protasov, travagliu in Parallels. Vi dicu un pocu di mè stessu. Passu trè quarti di a mo vita à scrive u codice. Sò diventatu un programatore à u core in u sensu literale: qualchì volta vecu u codice in i mo sogni. Un quartu di a vita hè u sviluppu industriale, u codice di scrittura chì entra direttamente in a pruduzzione. Un codice chì alcuni di voi aduprate, ma ùn ne capiscenu micca.

Allora capisce quantu era male. Quandu eru un pocu ghjovanu, aghju vinutu è mi sò datu queste basa di dati di dui terabyte. Hè una carica alta per tutti quì avà. Sò andatu à cunferenze è dumandò: "Ragazzi, ditemi, avete grandi dati, hè tuttu bellu? Quante basi avete quì ? Mi anu rispostu: "Avemu 100 gigabyte!" Aghju dettu: "Cool, 100 gigabytes!" E stava à pensà à mè cumu per mantene cun cura a mo faccia di poker. Pensate, iè, i picciotti sò cool, è dopu vultate è tinker cù queste basa di dati multi-terabyte. È questu hè esse un junior. Pudete imagine chì un colpu hè questu?

Cunnoscu più di 20 lingue di prugrammazione. Questu hè qualcosa chì aghju avutu da capisce mentre travagliava. Vi danu codice in Erlang, C, C++, Lua, Python, Ruby, qualcosa altru, è avete da cutà tuttu. In generale, aghju avutu. Ùn era micca pussibule di calculà u numeru esatta, ma in un locu intornu à u 20 u numeru era persu.

Siccomu tutti i prisenti sanu ciò chì Parallels hè è ciò chì facemu, ùn parleraghju micca di quantu simu cool è ciò chì facemu. Vi dicu solu chì avemu 13 uffizii in u mondu, più di 300 impiegati, sviluppu in Mosca, Tallinn è Malta. Se vulete, pudete piglià è trasladassi à Malta s'ellu hè fretu in l'invernu è avete bisognu à calà a spalle.

Specificamenti, u nostru dipartimentu scrive in Python 2. Semu in l'affari è ùn avemu micca tempu per implementà e tecnulugia di moda, cusì soffremu. Avemu aduprà Django perchè hà tuttu, è avemu pigliatu ciò chì era innecessariu è l'aghju cacciatu. Ancu MySQL, Redis è NGINX. Avemu ancu parechje altre cose interessanti. Avemu MongoDB, avemu cunigli chì correnu, avemu tuttu - ma ùn hè micca u mo, è ùn aghju micca fà.

OpenResty

Aghju dettu di mè stessu. Scupritemu di ciò chì parlu oghje:

  • Chì ghjè OpenResty è ciò chì si manghja?
  • Perchè reinventà una altra rota quandu avemu Python, NodeJS, PHP, Go è altre cose interessanti chì tutti sò cuntenti?
  • È uni pochi di esempi da a vita. Aviu avutu à cutà u rapportu assai perchè mi pigliò 3,5 ore, cusì ci saranu pochi esempi.

OpenResty hè NGINX. Grazie à ellu, avemu un servitore web cumpletu chì hè scrittu bè è travaglia rapidamente. Pensu chì a maiò parte di noi usanu NGINX in a produzzione. Sapete tutti chì hè veloce è cool. Hanu fattu un I / O sincronu cool in questu, cusì ùn avemu micca bisognu di ciclu nunda, cum'è l'anu fattu in Python. Gevent hè bellu, fantasticu, ma se scrive u codice C è qualcosa va male, allora cù Gevent andarà pazzo per debugging. Aviu avutu l'esperienze: ci pigliò dui ghjorni sanu per capisce ciò chì era sbagliatu. Sì qualchissia ùn avia micca scavatu per parechje settimane, hà trovu u prublema, hà scrittu annantu à Internet, è Google ùn l'avia micca trovu, allora seremu completamente pazzi.

NGINX hà digià fattu caching è cuntenutu staticu. Ùn avete bisognu di preoccupassi di cumu fà questu umanamente, per ùn rallentà in qualchì locu, per ùn perde micca descriptori in qualchì locu. Nginx hè assai còmuda di implementà, ùn avete micca bisognu di pensà à ciò chì piglià - WSGI, PHP-FPM, Gunicorn, Unicorn. Nginx hè statu stallatu, datu à l'amministratori, sanu cumu travaglià cun ellu. Nginx processa e dumande in una manera strutturata. Parlaraghju di questu un pocu dopu. In corta, hà una fase quandu hà accettatu a dumanda, quandu l'hà processatu, è quandu hà servitu u cuntenutu à l'utilizatore.

Nginx hè cool, ma ci hè un prublema: ùn hè micca abbastanza flexible, ancu cù tutte e funzioni cool chì i picciotti anu crammed in a cunfigurazione, malgradu u fattu chì pò esse cunfiguratu. Stu putere ùn hè micca abbastanza. Hè per quessa chì i ragazzi di Taobao, assai tempu fà, pare chì ottu anni fà, hà custruitu Lua in questu. Chì dà ?

  • grannizza. Hè chjucu. LuaJIT dà circa 100-200 kilobytes di overhead di memoria è un minimu di rendimentu overhead.
  • Speed. L'interprete LuaJIT hè vicinu à C in parechje situazioni, in certi situazioni perde à Java, in altri supera. Per qualchì tempu era cunsideratu u statu di l'arti, u compilatore JIT più cool. Avà ci sò più fresche, ma sò assai pisanti, per esempiu, u stessu V8. Certi interpreti JS è Java HotSpot sò più veloci in certi punti, ma in certi lochi anu sempre perde.
  • Facile à amparà. Sè vo avete, dì, una basa di codice Perl, è ùn site Booking, ùn truverete programatori Perl. Perchè ùn esistenu micca, sò stati tutti pigliati, è l'insignamentu hè longu è difficiule. Se vulete i programatori per qualcosa d'altru, pudete ancu avè da ricuperà o truvà. In u casu di Lua, tuttu hè simplice. Ogni junior pò amparà Lua in trè ghjorni. Mi pigliò circa duie ore per capisce. Dui ore dopu aghju digià scrittu codice in produzzione. Circa una settimana dopu si n'andò direttamente à a pruduzzione è si n'andò.

In u risultatu, pare cusì:

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Ci hè assai quì. OpenResty hà cullatu una mansa di moduli, sia luash sia motori. È avete tuttu prontu - implementatu è travagliatu.

esempi

Basta di i testi, andemu à u codice. Eccu un pocu Hello World:

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Chì ci hè ? Questu hè un locu Engins. Ùn ci preoccupa micca, ùn scrivemu micca u nostru propiu routing, ùn pigliamu micca un pocu prontu - l'avemu digià in NGINX, vivemu una vita bona è pigra.

content_by_lua_block hè un bloccu chì dice chì serve u cuntenutu cù un script Lua. Pigliemu a variabile Engins remote_addr è mette in string.format. Hè u listessu cum'è sprintf, solu in Lua, solu currettu. È damu à u cliente.

In u risultatu, serebbe cusì:

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Ma vultemu à u mondu reale. Nimu ùn implementa Hello World à a produzzione. A nostra applicazione di solitu va à a basa di dati o in un altru locu è a maiò parte di u tempu aspetta una risposta.

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Ellu si mette solu è aspetta. Ùn hè micca assai bonu. Quandu 100.000 XNUMX utilizatori venenu, hè assai difficiule per noi. Allora usemu una applicazione simplice cum'è un esempiu. Avemu da circà ritratti, per esempiu, di misgi. Ma ùn avemu micca solu circà, avemu espansione e parolle chjave è, se l'utilizatore hà cercatu "gattini", truvamu misgi, gatti furry, etc. Prima, avemu bisognu di ottene i dati di dumanda nantu à u backend. Sembra cusì:

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Dui linii permettenu di coglie i paràmetri GET, senza cumplicazioni. In seguitu, dicemu, da una basa di dati cù un signu per una keyword è estensione, ottenemu sta informazione utilizendu una dumanda SQL regulare. Hè simplice. Sembra cusì:

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Cunnettendu a biblioteca resty.mysql, chì avemu digià in u kit. Ùn avemu bisognu di stallà nunda, tuttu hè prontu. Indichemu cumu cunnette è fà una dumanda SQL:

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Hè un pocu paura quì, ma tuttu funziona. Quì 10 hè u limitu. Tiremu fora 10 entrate, simu pigri, ùn vulemu micca vede più. Aghju scurdatu di u limitu in SQL.

In seguitu truvemu ritratti per tutte e dumande. Raccogliemu una mansa di dumande è compie una tavola Lua chjamata reqs, è facemu ngx.location.capture_multi.

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Tutte queste dumande sò mandate in parallelu, è e risposte sò tornate à noi. U tempu di operazione hè uguali à u tempu di risposta di u più lento. Se tutti sparemu in 50 millisecondi, è avemu mandatu un centu di dumande, allora riceveremu una risposta in 50 milliseconds.

Siccomu simu pigri è ùn vulemu micca scrive HTTP è caching handling, faremu NGINX fà tuttu per noi. Comu avete vistu, ci era una dumanda url/fetch, eccu ellu:

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Facemu simplice proxy_pass, indichemu induve cache, cumu fà, è tuttu travaglia per noi.

Ma questu ùn hè micca abbastanza, avemu sempre bisognu di dà i dati à l'utilizatori. L'idea più simplice hè di serializza tuttu in JSON, facilmente, in duie linee. Demu Content-Type, demu JSON.

Ma ci hè una difficultà: l'utilizatore ùn vole micca leghje JSON. Avemu bisognu di attruvarà sviluppatori front-end. Calchì volta ùn vulemu micca fà questu prima. È i specialisti di SEO diceranu chì, s'ellu circhemu ritratti, ùn importa micca per elli. È se li demu qualchì cuntenutu, diceranu chì i nostri mutori di ricerca ùn indizianu nunda.

Cosa da fà? Di sicuru, daremu à l'utilizatori HTML. Generazione a manu ùn hè micca comme il faut, cusì vulemu aduprà mudelli. Ci hè una biblioteca per questu lua-resty-template.

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Probabilmente avete vistu e trè lettere spaventose OPM. OpenResty vene cun u so propiu gestore di pacchetti, per mezu di quale pudete installà una mansa di diversi moduli, in particulare, lua-resty-template. Questu hè un mutore di mudellu simplice, simile à i mudelli Django. Quì pudete scrive codice è eseguisce a sustituzione variabile.

Cum'è un risultatu, tuttu sarà simile à questu:

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Avemu pigliatu i dati è rende u mudellu, novu in duie linee. L'utilizatore hè felice, hà ricevutu i misgi. Siccomu avemu allargatu a dumanda, hà ancu ricevutu un sigellu di fur per i gattini. Ùn sapete mai, forse ellu cercava esattamente questu, ma ùn pudia micca formulà a so dumanda currettamente.

Tuttu hè bellu, ma simu in u sviluppu è ùn vulemu micca vede à l'utilizatori ancu. Facemu l'autorizazione. Per fà questu, fighjemu cumu NGINX gestisce a dumanda in termini OpenResty:

  • prima fase - accessu à, quandu l'utilizatore hè ghjustu ghjuntu, è l'avemu guardatu per intestazioni, per indirizzu IP è per altri dati. Pudemu immediatamente taglià si ùn ci piace micca. Questu pò esse usatu per l'autorizazione, o se ricevemu assai richieste, pudemu facilmente tagliate in questa fase.
  • riscriva. Riscrivemu alcuni dati di dumanda.
  • cuntenutu. Trasmettimu u cuntenutu à l'utilizatore.
  • filtru di headers. Sustituemu l'intestazione di risposta. Se avemu usatu proxy_pass, pudemu riscrive qualchi intestazioni prima di dà à l'utilizatori.
  • filtru di u corpu. Pudemu cambià u corpu.
  • Scie à - logging. Pudete scrive logs in elasticsearch senza una capa addiziale.

A nostra autorizazione serà simile à questu:

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Avemu da aghjunghje questu à quellu location, chì avemu descrittu prima, è mette u codice seguente quì:

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Fighjemu per vede s'ellu avemu un cookie token. Se no, allora dumandemu l'autorizazione. L'utilizatori sò astuti è ponu indovinà chì anu bisognu di stabilisce un token di cookie. Dunque, ci metteremu ancu in Redis:

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

U codice per travaglià cù Redis hè assai simplice è ùn hè micca sfarente di altre lingue. À u listessu tempu, tutte l'input / output, quì è quì, ùn hè micca bluccatu. Se scrive u codice sincronu, funziona in modu asincronu. Quasi cum'è gevent, ma fattu bè.

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Facemu l'autorizazione stessu:

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Dicemu chì avemu bisognu di leghje u corpu di a dumanda. Ricevemu argumenti POST è verificate chì u login è a password sò curretti. Se sò sbagliati, allora ti sfidemu per l'autorizazione. È se currettu, allora scrivite u token in Redis:

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Ùn vi scurdate di mette a cookie, questu hè ancu fattu in duie linee:

OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

L'esempiu hè simplice è speculativu. Di sicuru, ùn faremu micca un serviziu chì mostra a ghjente i misgi. Ma chi ci cunnosci. Allora andemu nantu à ciò chì pò esse fattu in a produzzione.

  • Backend minimalista. Calchì volta avemu bisognu di fà un pocu di dati à u backend: in un locu avemu bisognu di inserisce una data, in un locu avemu bisognu di vede una lista, dì quanti utilizatori sò in u situ avà, aghjunghje un contatore o statistiche. Qualcosa cusì chjucu. Certi pezzi minimi ponu esse fatti assai facilmente. Questu hà da fà prestu, faciule è grande.
  • Preprocessing di dati. A volte vulemu incrustà publicità in a nostra pagina, è ricevemu sta publicità utilizendu richieste API. Questu hè assai faciule da fà quì. Ùn caricamu micca u nostru backend, chì hè digià pusatu è travagliendu duramente. Pudete piglià è cullà quì. Pudemu cobble together some JS o, à u cuntrariu, uncouple it and preprocess something before give it to the user.
  • Facciata per u microserviziu. Questu hè ancu un casu assai bonu, l'aghju implementatu. Prima di quessa, aghju travagliatu in Tenzor, una sucietà chì si tratta di rapportu elettronicu è furnisce rapportu à circa a mità di e entità giuridiche in u paese. Avemu criatu un serviziu, assai cose sò state fatte quì cù u stessu mecanismu: routing, auturizazione è più.
    OpenResty pò esse usatu cum'è cola per i vostri microservizi, furnisce un accessu unicu à tuttu è una sola interfaccia. Siccomu i microservizi ponu esse scrittu in tale manera chì avete Node.js quì, PHP quì, Python quì, qualcosa Erlang quì, avemu capitu chì ùn vulemu riscrive u listessu codice in ogni locu. Dunque, OpenResty pò esse inseritu in u fronte.

  • Statistiche è analitiche. Di solitu NGINX hè à l'entrata, è tutte e dumande passanu per ellu. Hè in questu locu chì hè assai cunvenutu per cullà. Pudete immediatamente calculà qualcosa è cullà in un locu, per esempiu, Elasticsearch, Logstash, o simpricimenti scrivite à u logu è poi mandatu in un locu.
  • Sistemi multi-utilizatori. Per esempiu, i ghjochi in linea sò ancu assai boni per fà. Oghje in Cape Town, Alexander Gladysh parlerà di cume prototipà rapidamente un ghjocu multiplayer cù OpenResty.
  • Filtru di dumanda (WAF). Oghje hè di moda di fà ogni tipu di firewall di l'applicazioni web; ci sò parechji servizii chì li furnisce. Utilizendu OpenResty, pudete fà sè stessu un firewall di l'applicazione web chì filtrarà facilmente e richieste in cunfurmità cù i vostri bisogni. Sè vo avete Python, allora capite chì PHP ùn serà micca definitu injected in voi, salvu chì, sicuru, ùn u spawn in ogni locu da a cunsola. Sapete chì avete MySQL è Python. Probabilmente, puderanu pruvà à fà qualchì tipu di traversu di u repertoriu è injectà qualcosa in a basa di dati. Dunque, pudete filtrà e dumande strane rapidamente è à pocu prezzu ghjustu in fronte.
  • Cumunità. Siccomu OpenResty hè custruitu nantu à NGINX, hà un bonus - questu A cumunità NGINX. Hè assai grande, è una parte decente di e dumande chì avete da prima sò digià risolte da a cumunità NGINX.

    Lua sviluppatori. Aieri aghju parlatu cù i picciotti chì sò ghjunti à u ghjornu di furmazione HighLoad++ è intesu chì solu Tarantool hè statu scrittu in Lua. Questu ùn hè micca veru, assai cose sò scritte in Lua. Esempii: OpenResty, Prosody XMPP server, Love2D game engine, Lua scripted in Warcraft è in altrò. Ci sò assai sviluppatori Lua, anu una cumunità grande è responsiva. Tutte e mo dumande Lua sò state risolte in pocu ore. Quandu scrivite à a lista di mailing, littiralmenti in pochi minuti, ci sò digià una mansa di risposti, chì descrive ciò chì è cumu, chì hè ciò chì. Hè grande. Sfurtunatamente, un tali tipu, cumunità spirituale ùn hè micca in ogni locu.
    Ci hè GitHub per OpenResty, induve pudete apre un prublema se qualcosa hè rottu. Ci hè una lista di mailing in Google Groups, induve pudete discutiri questioni generali, ci hè una mailing list in Chinese - ùn sapete mai, forse ùn parlate micca inglese, ma sapete cinese.

Risultati

  • Spergu chì aghju sappiutu trasmette chì OpenResty hè un framework assai cunvene adattatu per u web.
  • Havi una bassa barriera à l'ingressu, postu chì u codice hè simile à ciò chì scrivimu, a lingua hè abbastanza simplice è minimalista.
  • Fornisce I / O asincronu senza callbacks, ùn averemu micca tagliatelle cum'è pudemu qualchì volta scrive in NodeJS.
  • Hà una implementazione faciule, postu chì avemu solu bisognu di NGINX cù u modulu necessariu è u nostru codice, è tuttu funziona subitu.
  • Comunità grande è responsiva.

Ùn aghju micca dettu in dettagliu cumu u routing hè fattu, hè diventatu una storia assai longa.

Ti ringraziu per a vostra attenzione!


Vladimir Protasov - OpenResty: trasfurmendu NGINX in un servitore d'applicazioni cumpletu

Source: www.habr.com

Add a comment