{"id":71378,"date":"2020-02-25T20:45:02","date_gmt":"2020-02-25T17:45:02","guid":{"rendered":"https:\/\/prohoster.info\/blog\/openresty-prevrashhaem-nginx-v-polnoczennyj-server-prilozhenij"},"modified":"2020-03-03T16:14:21","modified_gmt":"2020-03-03T13:14:21","slug":"openresty-prevrashhaem-nginx-v-polnoczennyj-server-prilozhenij","status":"publish","type":"post","link":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/openresty-prevrashhaem-nginx-v-polnoczennyj-server-prilozhenij","title":{"rendered":"OpenResty: turning NGINX into a full-fledged application server","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/62eb484051c7963c96842393884ddd98.jpg\" style=\"display:block;margin: 0 auto;\" \/><em>Public\u0103m din nou transcrierea prezent\u0103rii de la conferin\u021ba <noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/\">HighLoad++<\/a><\/noindex> din 2016, care a avut loc \u00een Skolkovo, suburba Moscovei, \u00eentre 7 \u0219i 8 noiembrie anul trecut. <noindex><a rel=\"nofollow\" href=\"https:\/\/habrahabr.ru\/post\/315726\/\">Vladimir Protasov<\/a><\/noindex> vorbe\u0219te despre cum s\u0103 extinzi func\u021bionalit\u0103\u021bile NGINX cu OpenResty \u0219i Lua.<\/em><\/p>\n<p>Bun\u0103 ziua, m\u0103 numesc Vladimir Protasov, lucrez la Parallels. O s\u0103 v\u0103 povestesc pu\u021bin despre mine. Trei sferturi din via\u021ba mea am scris cod. Am devenit programator p\u00e2n\u0103 \u00een m\u0103duv\u0103, adic\u0103 uneori visez codul. Un sfert din via\u021b\u0103 este dedicat dezvolt\u0103rii industriale, scrierii codului care ajunge direct \u00een produc\u021bie. Codul pe care unii dintre voi \u00eel folosi\u021bi, dar nu v\u0103 da\u021bi seama.<\/p>\n<p>Ca s\u0103 \u00een\u021belege\u021bi c\u00e2t de r\u0103u era totul. C\u00e2nd eram un junior mic, am venit \u0219i mi-au dat astfel de baze de date de dou\u0103 terabai\u021bi. Acum toat\u0103 lumea are highload. M\u0103 duceam la conferin\u021be, \u00eentrebam: \u201eB\u0103ie\u021bi, spune\u021bi-mi, ave\u021bi big data, e tare? C\u00e2te date ave\u021bi?\u201d R\u0103spundeau: \u201eAvem 100 de giga!\u201d Eu spuneam: \u201eMinunat, 100 de giga!\u201d Dar \u00een g\u00e2nd m\u0103 g\u00e2ndeam, cum s\u0103-mi p\u0103strez fa\u021ba impasibil\u0103. Credeai c\u0103 sunt tare, iar apoi te \u00eentorci \u0219i \u00ee\u021bi dai seama c\u0103 trebuie s\u0103 te descurci cu acele baze de date de c\u00e2teva terabai\u021bi. \u0218i asta, fiind junior. V\u0103 imagina\u021bi ce lovitur\u0103 a fost?<\/p>\n<p>\u0218tiu peste 20 de limbaje de programare. Asta e ceea ce a trebuit s\u0103 \u00eenv\u0103\u021b \u00een timpul muncii. \u00ce\u021bi dau cod pe Erlang, C, C++, Lua, Python, Ruby, pe alte limbaje, \u0219i trebuie s\u0103 le folose\u0219ti pe toate. \u00cen general, a\u0219a a fost. Nici m\u0103car nu am reu\u0219it s\u0103 num\u0103r exact, dar pe undeva am pierdut num\u0103rul pe la 20.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nDeoarece to\u021bi prezen\u021bii \u0219tiu ce este Parallels \u0219i cu ce ne ocup\u0103m, nu o s\u0103 vorbesc despre c\u00e2t de grozavi suntem \u0219i ce facem. Voi spune doar c\u0103 avem 13 birouri \u00een lume, peste 300 de angaja\u021bi, dezvoltare la Moscova, Tallinn \u0219i Malta. Dac\u0103 dori\u021bi, pute\u021bi s\u0103 v\u0103 muta\u021bi pe Malta, dac\u0103 iarna e frig \u0219i trebuie s\u0103 v\u0103 \u00eenc\u0103lzi\u021bi.<\/p>\n<p>Departamentul nostru scrie \u00een Python 2. Ne ocup\u0103m de afaceri \u0219i nu avem timp s\u0103 implement\u0103m tehnologii moderne, a\u0219a c\u0103 suferim. Folosim Django, pentru c\u0103 are tot ce ne trebuie, iar ce e \u00een plus am aruncat. De asemenea, MySQL, Redis \u0219i NGINX. Avem multe alte lucruri grozave. Avem MongoDB, avem iepuri care alearg\u0103, avem de toate \u2013 dar nu este domeniul meu, \u0219i nu m\u0103 ocup de asta.<\/p>\n<h1>OpenResty<\/h1>\n<p>\nAsta a fost despre mine. Hai s\u0103 vedem despre ce voi vorbi ast\u0103zi:<\/p>\n<ul>\n<li>Ce este OpenResty \u0219i cu ce se m\u0103n\u00e2nc\u0103?<\/li>\n<li>De ce s\u0103 invent\u0103m o alt\u0103 biciclet\u0103, c\u00e2nd avem Python, NodeJS, PHP, Go \u0219i alte lucruri grozave de care toat\u0103 lumea este mul\u021bumit\u0103?<\/li>\n<li>\u0218i c\u00e2teva exemple din via\u021ba real\u0103. A trebuit s\u0103 reduc considerabil prezentarea, deoarece mi-a ie\u0219it de 3,5 ore, a\u0219a c\u0103 vor fi pu\u021bine exemple.<\/li>\n<\/ul>\n<p>\nOpenResty este NGINX. Datorit\u0103 lui, avem un server web complet func\u021bional, care este bine scris \u0219i func\u021bioneaz\u0103 rapid. Cred c\u0103 majoritatea dintre noi folosim NGINX \u00een produc\u021bie. To\u021bi \u0219ti\u021bi c\u0103 este rapid \u0219i grozav. A fost realizat\u0103 o intrare\/ie\u0219ire sincron\u0103 fantastic\u0103, a\u0219a c\u0103 nu trebuie s\u0103 ne facem griji s\u0103 reinvent\u0103m roata, a\u0219a cum s-a \u00eent\u00e2mplat cu gevent \u00een Python. Gevent este grozav, dar dac\u0103 scrii cod \u00een C \u0219i ceva nu merge bine, devine al naibii de greu s\u0103 deboghezi cu gevent. Am avut experien\u021ba asta: a fost nevoie de dou\u0103 zile \u00eentregi s\u0103 \u00een\u021beleg ce s-a \u00eent\u00e2mplat gre\u0219it. Dac\u0103 cineva nu s-ar fi b\u0103gat c\u00e2teva s\u0103pt\u0103m\u00e2ni s\u0103 descopere problema, s\u0103 o scrie pe internet, iar Google nu ar fi g\u0103sit-o, am fi \u00eennebunit complet.<\/p>\n<p>\u00cen NGINX deja exist\u0103 caching \u0219i con\u021binut static. Nu trebuie s\u0103 \u00ee\u021bi faci griji cum s\u0103 faci asta ca lumea, pentru a nu r\u0103m\u00e2ne blocat undeva, s\u0103 nu pierzi descriptorii undeva. NGINX se deplaseaz\u0103 foarte u\u0219or, nu trebuie s\u0103 te g\u00e2nde\u0219ti ce s\u0103 alegi - WSGI, PHP-FPM, Gunicorn, Unicorn. NGINX a fost instalat, l-am dat administratorilor \u0219i ei \u0219tiu cum s\u0103 lucreze cu el. NGINX proceseaz\u0103 cererile \u00eentr-un mod structurat. Voi vorbi mai multe despre asta mai t\u00e2rziu. Pe scurt, are o faz\u0103 \u00een care a primit cererea, \u00een care a procesat-o \u0219i \u00een care a livrat con\u021binutul utilizatorului.<\/p>\n<p>NGINX este grozav, dar exist\u0103 o problem\u0103: nu este suficient de flexibil chiar \u0219i cu toate acele caracteristici grozave pe care le-au inclus \u00een configura\u021bie, av\u00e2nd \u00een vedere c\u00e2t de multe pot fi ajustate. Aceast\u0103 putere nu este suficient\u0103. De aceea, b\u0103ie\u021bii de la Taobao, acum c\u00e2\u021biva ani, parc\u0103 acum opt ani, au \u00eencorporat Lua. Ce ofer\u0103 acesta?<\/p>\n<ul>\n<li><strong>Dimensiune<\/strong>. Este mic. LuaJIT ofer\u0103 undeva \u00eentre 100-200 de kilobyte overhead \u00een memorie \u0219i un overhead minim \u00een performan\u021b\u0103.<\/li>\n<li><strong>Vitez\u0103<\/strong>. Interpretatorul LuaJIT este aproape la fel de rapid ca C \u00een multe situa\u021bii, \u00een unele situa\u021bii pierde \u00een fa\u021ba Java, iar \u00een altele o dep\u0103\u0219e\u0219te. O perioad\u0103 a fost considerat cel mai bun, un JIT compilator fantastic. Acum sunt variante mai grozave, dar sunt foarte grele, de exemplu, V8. Unele interpretatoare JS \u0219i HotSpot-ul Java sunt mai rapide \u00een anumite puncte, dar \u00een alte situa\u021bii tot mai pierd.<\/li>\n<li><strong>U\u0219urin\u021ba de \u00eenv\u0103\u021bare<\/strong>. Dac\u0103 ave\u021bi, de exemplu, o baz\u0103 de cod \u00een Perl \u0219i nu sunte\u021bi Booking, nu ve\u021bi g\u0103si programatori Perl. Pentru c\u0103 nu exist\u0103, i-au luat pe to\u021bi, iar a-i \u00eenv\u0103\u021ba dureaz\u0103 mult \u0219i e complicat. Dac\u0103 dori\u021bi programatori pe altceva, s-ar putea s\u0103 trebuiasc\u0103 s\u0103-i recalifica\u021bi sau s\u0103-i g\u0103si\u021bi. \u00cen cazul Lua, totul e simplu. Lua poate fi \u00eenv\u0103\u021bat de orice junior \u00een trei zile. Mi-a trebuit cam dou\u0103 ore s\u0103 m\u0103 familiarizez. Dup\u0103 dou\u0103 ore, scriam deja cod \u00een produc\u021bie. Cam dup\u0103 o s\u0103pt\u0103m\u00e2n\u0103, codul meu a fost deja livrat \u00een produc\u021bie.<\/li>\n<\/ul>\n<p>\n\u00cen rezultat, arat\u0103 a\u0219a:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/1e6c253c5436fdc894f8be7999799cb0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAici este mult. \u00cen OpenResty, au adunat o gr\u0103mad\u0103 de module, at\u00e2t lua c\u00e2t \u0219i engine. \u0218i ave\u021bi totul gata - l-a\u021bi implementat \u0219i func\u021bioneaz\u0103.<\/p>\n<h1>Exemple<\/h1>\n<p>\nAjunge cu lirica, s\u0103 trecem la cod. Iat\u0103 un mic Hello World:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/bbd056b72c71b193b0f06dd3248f5381.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCe avem aici? Este o loca\u021bie de engine. Nu ne complic\u0103m, nu scriem rutarea noastr\u0103, nu lu\u0103m ceva gata - avem deja \u00een NGINX, tr\u0103im bine \u0219i lene\u0219.<\/p>\n<p><code>content_by_lua_block<\/code> \u2013 acesta este un bloc care indic\u0103 faptul c\u0103 livr\u0103m con\u021binut printr-un script Lua. Lu\u0103m variabila de engine <code>remote_addr<\/code> \u0219i o introducem \u00een <code>string.format<\/code>. Este la fel ca \u0219i <code>sprintf<\/code>, doar c\u0103 \u00een Lua, doar c\u0103 corect. \u0218i livr\u0103m clientului.<\/p>\n<p>\u00cen rezultat, va ar\u0103ta a\u0219a:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/9f1aaf6625f1fe5904b1e8a568fac76d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nDar s\u0103 ne \u00eentoarcem \u00een lumea real\u0103. \u00cen produc\u021bie, nimeni nu implementeaz\u0103 Hello World. Aplica\u021bia noastr\u0103 merge de obicei \u00een baza de date sau \u00een alt\u0103 parte \u0219i cea mai mare parte a timpului a\u0219teapt\u0103 un r\u0103spuns.<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/485f713c0284e16b0817500c8606c104.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPur \u0219i simplu a\u0219teapt\u0103. Aceasta nu este foarte bine. C\u00e2nd vin 100.000 de utilizatori, ne este foarte greu. De aceea, s\u0103 lu\u0103m ca exemplu o aplica\u021bie simpl\u0103. Vom c\u0103uta imagini, de exemplu, cu pisici. Doar c\u0103 nu vom c\u0103uta pur \u0219i simplu, vom extinde cuvintele cheie \u0219i, dac\u0103 utilizatorul caut\u0103 \u201episicu\u021be\u201d, \u00eei vom g\u0103si pisici, pufo\u0219i \u0219i altele. Pentru \u00eenceput, trebuie s\u0103 ob\u021binem datele cererii pe backend. Arat\u0103 astfel:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/a2134f86f15764745ae8330f63185367.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nDou\u0103 linii v\u0103 permit s\u0103 ob\u021bine\u021bi parametrii GET, nimic complicat. Apoi, presupunem c\u0103 din baza de date cu o tabel\u0103 pe cuv\u00e2ntul cheie \u0219i extensie ob\u021binem aceast\u0103 informa\u021bie printr-o interogare SQL obi\u0219nuit\u0103. Totul e simplu. Arat\u0103 astfel:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/4543685dc907f30bba2a079a0fadad2c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nConect\u0103m biblioteca <code>resty.mysql<\/code>, care este deja inclus\u0103. Nu trebuie s\u0103 instal\u0103m nimic, totul este preg\u0103tit. Specific\u0103m cum s\u0103 ne conect\u0103m \u0219i facem interogarea SQL:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/2234b3a5b2e1d8efafec00a49f1a13b0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAici este pu\u021bin \u00eenfrico\u0219\u0103tor, dar totul func\u021bioneaz\u0103. Aici, 10 este limita. Extragem 10 \u00eenregistr\u0103ri, suntem leno\u0219i, nu vrem s\u0103 ar\u0103t\u0103m mai mult. Am uitat de limit\u0103 \u00een SQL.<\/p>\n<p>Apoi g\u0103sim imagini pentru toate cererile. Adun\u0103m un pachet de cereri \u0219i complet\u0103m o tabel\u0103 Lua, care se nume\u0219te <code>reqs<\/code>, \u0219i facem <code>ngx.location.capture_multi<\/code>.<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/c18171845b3bd3872c4a7a7feae0d4bc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nToate aceste cereri pleac\u0103 \u00een paralel \u0219i primim r\u0103spunsuri. Timpul de execu\u021bie este egal cu timpul r\u0103spunsului celui mai lent. Dac\u0103 toate r\u0103spund \u00een 50 de milisecunde \u0219i am trimis o sut\u0103 de cereri, atunci r\u0103spunsul va veni \u00een 50 de milisecunde.<\/p>\n<p>Deoarece suntem lene\u0219i \u0219i nu vrem s\u0103 scriem procesare HTTP \u0219i caching, vom obliga NGINX s\u0103 fac\u0103 totul pentru noi. A\u0219a cum a\u021bi v\u0103zut, a fost o cerere la <code>url\/fetch<\/code>, iat\u0103-l:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/ef8fcc6905b2860a7f214c41251582a1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nFacem o simpl\u0103 <code>proxy_pass<\/code>, specific\u0103m unde s\u0103 cache-uim, cum s\u0103 o facem, \u0219i totul func\u021bioneaz\u0103.<\/p>\n<p>Dar asta nu este suficient, trebuie s\u0103 livr\u0103m datele utilizatorului. Cea mai simpl\u0103 idee este s\u0103 le serializ\u0103m \u00een JSON, simplu, \u00een dou\u0103 r\u00e2nduri. Livr\u0103m Content-Type, livr\u0103m JSON.<\/p>\n<p>Dar exist\u0103 o dificultate: utilizatorul nu vrea s\u0103 citeasc\u0103 JSON. Trebuie s\u0103 atragem frontend-erii. Uneori, nu ne dorim s\u0103 facem asta de la bun \u00eenceput. \u0218i SEO-i\u0219tii vor spune c\u0103, dac\u0103 c\u0103ut\u0103m imagini, nu le pas\u0103. Iar dac\u0103 le livr\u0103m un fel de con\u021binut, vor spune c\u0103 motoarele noastre de c\u0103utare nu indexeaz\u0103 nimic.<\/p>\n<p>Ce putem face cu asta? Evident, vom livra utilizatorului HTML. A genera manual nu este o op\u021biune, a\u0219a c\u0103 vrem s\u0103 folosim \u0219abloane. Pentru aceasta exist\u0103 o bibliotec\u0103 <code>lua-resty-template<\/code>.<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/66a6cffc402575d286cb00d138dc201a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nProbabil a\u021bi v\u0103zut cele trei litere terifiante OPM. OpenResty vine cu propriul manager de pachete, prin care pot fi instalate \u0219i multe module diferite, \u00een special, <code>lua-resty-template<\/code>. Este un motor simplu de \u0219abloane, similar cu Django templates. Acolo se pot scrie coduri \u0219i face \u00eenlocuiri de variabile.<\/p>\n<p>Ca rezultat, totul va ar\u0103ta aproximativ astfel:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/b54497e4f1ab5a80183dc49c172a7f15.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAm preluat datele \u0219i am redat \u0219ablonul din nou \u00een dou\u0103 r\u00e2nduri. Utilizatorul este fericit, a primit pisici. Deoarece am extins cererea, el a primit \u0219i o rob\u0103 marin\u0103, cine \u0219tie, poate c\u0103utase tocmai acel lucru, dar nu a putut formula corect cererea.<\/p>\n<p>Totul este grozav, dar suntem \u00een dezvoltare \u0219i nu vrem s\u0103 le ar\u0103t\u0103m utilizatorilor deocamdat\u0103. Hai s\u0103 facem autorizare. Pentru a face asta, hai s\u0103 vedem cum NGINX proceseaz\u0103 cererea \u00een termeni de OpenResty:<\/p>\n<ul>\n<li>Prima faz\u0103 - <strong>-token \u0219i<\/strong>, c\u00e2nd utilizatorul a venit doar, iar noi l-am analizat dup\u0103 titluri, dup\u0103 adresa IP, dup\u0103 alte date. \u00cel putem elimina imediat dac\u0103 nu ne place. Aceasta poate fi utilizat\u0103 pentru autorizare, sau, dac\u0103 primim foarte multe cereri, le putem bloca u\u0219or \u00een aceast\u0103 faz\u0103.<\/li>\n<li><strong>rewrite<\/strong>. Rescriem unele date ale cererii.<\/li>\n<li><strong>con\u021binut<\/strong>. Furniz\u0103m con\u021binutul utilizatorului.<\/li>\n<li><strong>filtru de antete<\/strong>. \u00cenlocuim antetele r\u0103spunsului. Dac\u0103 am folosit <code>proxy_pass<\/code>, putem rescrie unele antete \u00eenainte de a le da utilizatorului.<\/li>\n<li><strong>filtru de corp<\/strong>. Putem \u00eenlocui corpul.<\/li>\n<li><strong>log<\/strong>\u00a0\u2014 logare. Se pot scrie loguri \u00een elasticsearch f\u0103r\u0103 un strat suplimentar.<\/li>\n<\/ul>\n<p>\nAutorizarea noastr\u0103 va ar\u0103ta cam a\u0219a:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/f6c16665b75ce0fa0ee69e07ab6a4a61.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nVom ad\u0103uga asta \u00een cel <code>location<\/code>, pe care l-am descris anterior, \u0219i vom introduce acolo un astfel de cod:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/126d8411c92afa92f3c4f5b9791b3e9c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nVerific\u0103m dac\u0103 avem token cookie. Dac\u0103 nu, ne \u00eendrept\u0103m c\u0103tre autorizare. Utilizatorii sunt iste\u021bi \u0219i pot ghici c\u0103 trebuie s\u0103 pun\u0103 token cookie. Prin urmare, o vom stoca \u0219i \u00een Redis:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/b876372412d648885c2f7d53e712a85b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nCodul de lucru cu Redis este foarte simplu \u0219i nu se deosebe\u0219te de celelalte limbaje. \u00cen acela\u0219i timp, toat\u0103 intrarea\/ie\u0219irea, at\u00e2t acolo c\u00e2t \u0219i aici, este non-blocant\u0103. Dac\u0103 scrie\u021bi cod sincron, acesta func\u021bioneaz\u0103 asincron. Aproape ca \u0219i cu gevent, doar c\u0103 este realizat bine.<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/74066c9c750c718f368617faacbe0acc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nS\u0103 facem autoriza\u021bia \u00een sine:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/0b3b486ca3c417716ebdaac189bfdcbf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nSpunem c\u0103 trebuie s\u0103 citim corpul cererii. Ob\u021binem argumentele POST, verific\u0103m c\u0103 numele de utilizator \u0219i parola sunt corecte. Dac\u0103 sunt gre\u0219ite, ne \u00eendrept\u0103m c\u0103tre autorizare. Iar dac\u0103 sunt corecte, stoc\u0103m token \u00een Redis:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/bcf470d84791b6d1d01152d5ad511dbd.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nNu uit\u0103m s\u0103 set\u0103m cookie, acest lucru se face \u0219i \u00een dou\u0103 linii:<\/p>\n<p><img decoding=\"async\" alt=\"OpenResty: turning NGINX into a full-fledged application server\" src=\"\/wp-content\/uploads\/2020\/02\/efe06a113de28bacd14b26d6bb62a037.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUn exemplu simplu, ipotetic. Cu siguran\u021b\u0103 nu vom face un serviciu care s\u0103 arate oamenilor pisici. De\u0219i cine \u0219tie. A\u0219adar, s\u0103 vedem ce putem face \u00een produc\u021bie.<\/p>\n<ul>\n<li><strong>Backend minimalist<\/strong>. Uneori avem nevoie s\u0103 oferim backend-ului doar c\u00e2teva date: uneori trebuie s\u0103 introducem o dat\u0103, uneori s\u0103 prezent\u0103m o list\u0103, s\u0103 spunem c\u00e2\u021bi utilizatori sunt pe site, s\u0103 ata\u0219\u0103m un contor sau statistica. Ceva mic. Piesele minime pot fi realizate foarte u\u0219or. Asta va ie\u0219i rapid, u\u0219or \u0219i grozav.\n<\/li>\n<li><strong>Preprocesarea datelor<\/strong>. Uneori, vrem s\u0103 integr\u0103m reclame \u00een pagina noastr\u0103, iar aceste reclame le lu\u0103m prin interog\u0103ri API. Este foarte u\u0219or s\u0103 facem asta aici. Nu ne \u00eenc\u0103rc\u0103m backend-ul, care oricum lucreaz\u0103 din greu. Putem s\u0103 lu\u0103m \u0219i s\u0103 construim aici. Putem s\u0103 \u00eembin\u0103m unele JS sau, dimpotriv\u0103, s\u0103 desp\u0103r\u021bim, s\u0103 preprocess\u0103m ceva \u00eenainte de a-l livra utilizatorului.\n<\/li>\n<li><strong>Fa\u021bada pentru microserviciu<\/strong>. Acesta este, de asemenea, un caz foarte bun, pe care l-am implementat. \u00cen trecut, am lucrat la compania Tenzor, care se ocup\u0103 cu raportarea electronic\u0103, asigur\u00e2nd raportarea pentru aproximativ jum\u0103tate din persoanele juridice din \u021bar\u0103. Am creat un serviciu, iar multe lucruri au fost realizate cu ajutorul acelea\u0219i mecanisme: rutare, autorizare \u0219i altele.<br \/>\nOpenResty poate fi folosit ca un lipici pentru microserviciile voastre, care va oferi un acces unificat la tot \u0219i o interfa\u021b\u0103 unic\u0103. Deoarece microserviciile pot fi scrise astfel \u00eenc\u00e2t aici s\u0103 ave\u021bi Node.js, aici PHP, aici Python, aici o solu\u021bie pe Erlang, \u00een\u021belegem c\u0103 nu dorim s\u0103 rescriem acela\u0219i cod peste tot. De aceea, OpenResty poate fi integrat \u00een front-end.<\/p>\n<\/li>\n<li><strong>Statistic\u0103 \u0219i analiz\u0103<\/strong>. De obicei, NGINX se afl\u0103 la intrare \u0219i toate cererile trec prin el. Este tocmai locul unde este foarte convenabil s\u0103 adun\u0103m date. Putem calcula ceva imediat \u0219i s\u0103 le trimitem undeva, de exemplu, la Elasticsearch, Logstash sau pur \u0219i simplu s\u0103 le \u00eenregistr\u0103m \u00een log \u0219i apoi s\u0103 le trimitem mai departe.\n<\/li>\n<li><strong>Sisteme multi-utilizator<\/strong>. De exemplu, este foarte bine s\u0103 faci jocuri online. Ast\u0103zi, \u00een Cape Town, Alexandre Glady\u0219 va vorbi despre cum s\u0103 prototipizezi rapid un joc multi-utilizator cu ajutorul OpenResty.\n<\/li>\n<li><strong>Filtrarea cererilor (WAF)<\/strong>. \u00cen prezent, este la mod\u0103 s\u0103 creezi diverse firewalls pentru aplica\u021bii web, sunt multe servicii care le ofer\u0103. Cu ajutorul OpenResty po\u021bi crea un firewall pentru aplica\u021bii web care va filtra cererile conform cerin\u021belor tale, rapid \u0219i u\u0219or. Dac\u0103 ai Python, \u00een\u021belegi c\u0103 PHP nu va fi injectat cu siguran\u021b\u0103, cu condi\u021bia s\u0103 nu-l lansezi din consol\u0103 \u00een alt\u0103 parte. \u0218tii c\u0103 ai MySQL \u0219i Python. Probabil c\u0103 aici se pot face \u00eencerc\u0103ri de directory traversal \u0219i alte inject\u0103ri \u00een baz\u0103. De aceea, po\u021bi filtra rapid \u0219i ieftin cererile suspecte direct \u00een front-end.\n<\/li>\n<li><strong>Comunitate.<\/strong> Deoarece OpenResty este construit pe baza NGINX, are un bonus \u2013 aceasta este <strong>comunitatea NGINX<\/strong>. Este foarte vast, iar o parte considerabil\u0103 din \u00eentreb\u0103rile pe care le ve\u021bi avea la \u00eenceput au fost deja solu\u021bionate de comunitatea NGINX.\n<p><strong>Dezvoltatori Lua<\/strong>. Ieri, am discutat cu ni\u0219te colegi care au venit la ziua de training HighLoad++ \u0219i am aflat c\u0103 Tarantool este singurul scris \u00een Lua. Nu este adev\u0103rat, \u00een Lua sunt scrise multe lucruri. Exemple: OpenResty, serverul XMPP Prosody, motorul de joc Love2D, Lua este utilizat \u00een Warcraft \u0219i \u00een alte locuri. Exist\u0103 mul\u021bi dezvoltatori Lua, iar comunitatea lor este mare \u0219i receptiv\u0103. Toate \u00eentreb\u0103rile mele legate de Lua au fost rezolvate \u00een c\u00e2teva ore. Atunci c\u00e2nd scrii pe lista de discu\u021bii, practic \u00een c\u00e2teva minute deja prime\u0219ti o mul\u021bime de r\u0103spunsuri, explic\u00e2nd ce \u0219i cum, ce se \u00eent\u00e2mpl\u0103. Este minunat. Din p\u0103cate, nu peste tot exist\u0103 o comunitate a\u0219a de binevoitoare.<br \/>\nDespre OpenResty exist\u0103 GitHub, unde po\u021bi deschide un issue dac\u0103 ceva nu func\u021bioneaz\u0103. Exist\u0103 o list\u0103 de discu\u021bii pe Google Groups, unde po\u021bi discuta \u00eentreb\u0103ri generale, \u0219i exist\u0103 o discu\u021bie \u00een chinez\u0103 - la urma urmei, poate nu st\u0103p\u00e2ne\u0219ti engleza, \u00eens\u0103 ai cuno\u0219tin\u021be de chinez\u0103.<\/li>\n<\/ul>\n<p><\/p>\n<h1>Concluzii<\/h1>\n<p><\/p>\n<ul>\n<li>Sper c\u0103 am reu\u0219it s\u0103 transmit faptul c\u0103 OpenResty este un framework foarte confortabil, special conceput pentru web.<\/li>\n<li>Are o barier\u0103 de intrare sc\u0103zut\u0103, deoarece codul este similar cu ceea ce scriem, iar limbajul este destul de simplu \u0219i minimalist.<\/li>\n<li>Ofer\u0103 I\/O asincron f\u0103r\u0103 callbacks, nu vom avea complexitatea pe care uneori o scriem \u00een NodeJS.<\/li>\n<li>Are un deployment u\u0219or, deoarece avem nevoie doar de NGINX cu modulul necesar \u0219i codul nostru, \u0219i totul func\u021bioneaz\u0103 imediat.<\/li>\n<li>O comunitate mare \u0219i receptiv\u0103.<\/li>\n<\/ul>\n<p>\nNu am explicat \u00een detaliu cum se face rutarea, ar fi ie\u0219it un discurs foarte lung.<\/p>\n<p>V\u0103 mul\u021bumesc pentru aten\u021bie!<\/p>\n<p><center><div class=\"youtube-placeholder\" data-id=\"silrEB0Brvo\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/silrEB0Brvo\/hqdefault.jpg\" alt=\"Reda\u021bi video\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\n<em><noindex><a rel=\"nofollow\" href=\"http:\/\/www.highload.ru\/2016\/abstracts\/2432.html\">Vladimir Protasov - OpenResty: transform\u0103m NGINX \u00eentr-un server de aplica\u021bii complet<\/a><\/noindex><\/em><br \/>\n<br \/>Sursa: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/321864\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041c\u044b \u0432\u043d\u043e\u0432\u044c \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0443 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u0441 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0438 HighLoad++ 2016, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043b\u0430 \u0432 \u043f\u043e\u0434\u043c\u043e\u0441\u043a\u043e\u0432\u043d\u043e\u043c \u0421\u043a\u043e\u043b\u043a\u043e\u0432\u043e 7\u20148 \u043d\u043e\u044f\u0431\u0440\u044f \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u0433\u043e\u0434\u0430. \u0412\u043b\u0430\u0434\u0438\u043c\u0438\u0440 \u041f\u0440\u043e\u0442\u0430\u0441\u043e\u0432 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u0430\u043a \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c NGINX \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e OpenResty \u0438 Lua. \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u043c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0412\u043b\u0430\u0434\u0438\u043c\u0438\u0440 \u041f\u0440\u043e\u0442\u0430\u0441\u043e\u0432, \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0432 Parallels. \u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0447\u0443\u0442\u044c-\u0447\u0443\u0442\u044c \u043e \u0441\u0435\u0431\u0435. \u0422\u0440\u0438 \u0447\u0435\u0442\u0432\u0435\u0440\u0442\u0438 \u0441\u0432\u043e\u0435\u0439 \u0436\u0438\u0437\u043d\u0438 \u044f \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0441\u044c \u0442\u0435\u043c, \u0447\u0442\u043e \u043f\u0438\u0448\u0443 \u043a\u043e\u0434. \u0421\u0442\u0430\u043b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":71379,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-71378","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041c\u044b \u0432\u043d\u043e\u0432\u044c \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0443.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/openresty-prevrashhaem-nginx-v-polnoczennyj-server-prilozhenij\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47OpenResty: \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u043c NGINX \u0432 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041c\u044b \u0432\u043d\u043e\u0432\u044c \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0443.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/openresty-prevrashhaem-nginx-v-polnoczennyj-server-prilozhenij\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-02-25T17:45:02+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-03T13:14:21+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47OpenResty: transform\u0103m NGINX \u00eentr-un server de aplica\u021bii complet | ProHoster","description":"Public\u0103m din nou transcrierea.","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/openresty-prevrashhaem-nginx-v-polnoczennyj-server-prilozhenij","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47OpenResty: \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u043c NGINX \u0432 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 | ProHoster","og:description":"\u041c\u044b \u0432\u043d\u043e\u0432\u044c \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0443.","og:url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/openresty-prevrashhaem-nginx-v-polnoczennyj-server-prilozhenij","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-02-25T17:45:02+00:00","article:modified_time":"2020-03-03T13:14:21+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"71378","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:03:22","updated":"2022-09-30 08:39:30","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/71378","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=71378"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/71378\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media\/71379"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=71378"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=71378"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=71378"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}