A konferenciáról készült beszámoló átiratát újra közzétesszük 2016, amelyet a Moszkva melletti Szkolkovóban rendeztek meg tavaly november 7-8. elmagyarázza, hogyan lehet kiterjeszteni az NGINX funkcióit az OpenResty és a Lua segítségével.
Üdvözlök mindenkit, a nevem Vladimir Protasov, a Parallels-nek dolgozom. Mesélek egy kicsit magamról. Életem háromnegyedét kódírással töltöm. Végig programozó lettem a szó szoros értelmében: néha látom a kódot álmaimban. Az élet egynegyede ipari fejlesztés, kód írása, amely egyenesen a termelésbe kerül. Kód, amelyet néhányan használnak, de nem ismerik.
Hogy tudd, milyen rossz volt. Kicsit fiatalabb koromban bejöttem, és odaadták ezt a két terabájtos adatbázist. Most itt van mindenki számára highload. Konferenciákra mentem, és megkérdeztem: „Srácok, mondjátok meg, van nagy adatotok, minden menő? Hány bázisod van ott? Azt válaszolták: „100 gigabájtunk van!” Azt mondtam: "Csodálatos, 100 gigabájt!" És azon gondolkodtam, hogyan menthetném meg szépen a pókerarcot. Azt gondolod, igen, a srácok menők, aztán visszajössz, és bütykölöd ezeket a több terabájtos adatbázisokat. És ez juniornak lenni. El tudod képzelni, milyen sláger ez?
Több mint 20 programozási nyelvet ismerek. Erre kellett rájönnöm a munka során. Erlang-ban, C-ben, C++-ban, Lua-ban, Python-ban, Ruby-ban, valami másban kódot adnak, és az egészet le kell vágni. Általában muszáj volt. Pontos számot nem lehetett kiszámolni, de valahol 20 körül elveszett a szám.
Mivel itt mindenki tudja, mi az a Parallels, és mit csinálunk, nem fogok beszélni arról, hogy milyen menők vagyunk és mit csinálunk. Csak annyit mondok el, hogy 13 irodánk van szerte a világon, több mint 300 alkalmazottunk van, fejlesztés Moszkvában, Tallinnban és Máltán. Ha kívánja, elviheti és költözhet Máltára, ha télen hideg van, és fel kell melegítenie a hátát.
Konkrétan a részlegünk Python 2-ben ír. Üzleti tevékenységet folytatunk, és nincs időnk divatos technológiákat bevezetni, ezért szenvedünk. Nekünk van Django, mert minden megvan, a felesleget pedig elvittük és kidobtuk. MySQL, Redis és NGINX is. Sok más klassz cuccunk is van. Van MongoDB-nk, nyulak rohangálnak, csak nincs semmink – de nem az enyém, és nem is csinálom.
OpenResty
meséltem magamról. Lássuk, miről fogok ma beszélni:
- Mi az az OpenResty és mivel eszik?
- Miért kell feltalálni a kereket, ha Python, NodeJS, PHP, Go és egyéb klassz dolgok vannak, amelyekkel mindenki elégedett?
- És néhány példa az életből. Nagyon le kellett vágnom a beszámolót, mert 3,5 órára kaptam, szóval kevés lesz a példa.
Az OpenResty az NGINX. Neki köszönhetően van egy teljes értékű webszerverünk, ami jól meg van írva, gyorsan működik. Azt hiszem, a legtöbben NGINX-et használunk a termelésben. Mindenki tudja, hogy gyors és menő. Menő szinkron I/O-t készítettek benne, így nem kell semmit sem úgy ciklusolnunk, mint ahogy a geventet Pythonban ciklusozták. A Gevent klassz, nagyszerű, de ha C-kódot írsz, és valami elromlik a geventtel, akkor megőrülsz a hibakeresésben. Volt tapasztalatom: két teljes napba telt, mire rájöttem, mi a baj. Ha valaki azelőtt néhány hétig nem ásott volna, megtalálta a problémát, felírta volna az internetre, és a Google nem találta volna, akkor teljesen megőrültünk volna.
Az NGINX már csinál gyorsítótárat és statikus tartalmat. Nem kell azon aggódnod, hogyan kell ezt emberileg csinálni, hogy ne lassíts le valahol, hogy ne veszíts el valahol a leírókat. Az Nginx telepítése nagyon kényelmes, nem kell azon gondolkodni, hogy mit vegyen – WSGI, PHP-FPM, Gunicorn, Unicorn. Az Nginx telepítve volt, odaadták az adminoknak, tudják, hogyan kell vele dolgozni. Az Nginx strukturált módon kezeli a kéréseket. Erről egy kicsit később beszélek. Röviden: van egy fázisa, amikor éppen elfogadta a kérést, mikor feldolgozta és mikor adta át a tartalmat a felhasználónak.
Az Nginx menő, de van egy probléma: még azokkal a jó tulajdonságokkal sem elég rugalmas, amiket a srácok betoltak a konfigba, annak ellenére, hogy testreszabható. Ez az erő nem elég. Ezért a taobaói srácok valamikor, úgy gondolom, nyolc éve, beleépítették Luát. Mit ad?
- méret. Ez kicsi. A LuaJIT körülbelül 100-200 kilobájt memóriát és minimális teljesítményt biztosít.
- Sebesség. A LuaJIT interpreter sok helyzetben közel áll a C-hez, bizonyos helyzetekben elveszíti a Java-t, néhány esetben megelőzi. Egy ideig a legkorszerűbbnek számított, a legmenőbb JIT fordító. Most már vannak hűvösebbek, de azok nagyon nehezek, pl ugyanaz a V8-as. Egyes JS-tolmácsok és a Java HotSpot bizonyos pontokon gyorsabbak, de bizonyos pontokon még mindig veszítenek.
- Könnyű megtanulni. Ha mondjuk van egy Perl kódbázisod, és nem Booking vagy, akkor nem találsz Perl programozókat. Mivel nincsenek ott, mindet elvitték, és hosszú és nehéz megtanítani őket. Ha valami máshoz szeretne programozókat, akkor lehet, hogy át kell őket képezni vagy meg kell találni. Lua esetében minden egyszerű. A Lua-t bármelyik junior megtanulhatja három nap alatt. Körülbelül két órámba telt mire rájöttem. Két órával később már élesben írtam a kódot. Körülbelül egy héttel később egyenesen a gyártásba ment, és távozott.
Ennek eredményeként ez így néz ki:

Nagyon sok van itt. Az OpenResty egy csomó modult állított össze, luash-t és motorokat egyaránt. És minden készen áll – telepítve és működőképes.
Примеры
Elég a dalszövegből, térjünk át a kódra. Íme egy kis Hello World:

Mi van ott? ez a motorok helye. Nem aggódunk, nem írunk saját útválasztást, nem veszünk valami készet - már az NGINX-ben van, jól és lustán élünk.
content_by_lua_block egy blokk, amely azt mondja, hogy Lua-szkriptet használunk a tartalmak kiszolgálására. Vegyünk egy motor változót remote_addr és csúsztasd bele string.format. Ez ugyanaz, mint sprintf, csak Lua-ban, csak helyes. És adjuk az ügyfélnek.
Ennek eredményeként ez így fog kinézni:

De vissza a való világhoz. A gyártás során senki sem telepíti a Hello World-et. Alkalmazásunk általában az adatbázisba vagy máshova megy, és legtöbbször válaszra vár.

Csak ül és vár. Nem túl jó. Amikor 100.000 XNUMX felhasználó érkezik, nagyon nehéz számunkra. Ezért használjunk egy egyszerű alkalmazást példaként. Képeket fogunk keresni, például macskákról. Csak mi nem csak keresni fogunk, kibővítjük a kulcsszavakat, és ha a felhasználó a "cicák" kifejezésre keresett, akkor macskákat, bolyhokat stb. Először meg kell szereznünk a kérési adatokat a háttérben. Ez így néz ki:

Két sor lehetővé teszi a GET paraméterek felvételét, komplikációk nélkül. Ezután például egy táblázatot tartalmazó adatbázisból nyerjük ki ezeket az információkat kulcsszónként és kiterjesztésenként egy normál SQL lekérdezéssel. Minden egyszerű. Ez így néz ki:

Összekapcsoljuk a könyvtárat resty.mysql, ami már a készletben van. Nem kell semmit telepítenünk, minden készen áll. Adja meg a csatlakozás módját és az SQL-lekérdezést:

Kicsit ijesztő, de működik. Itt 10 a határ. Kihúzunk 10 lemezt, lusták vagyunk, nem akarunk többet mutatni. Az SQL-ben megfeledkeztem a korlátról.
Ezután minden lekérdezéshez találunk képeket. Összegyűjtünk egy csomó kérést, és kitöltünk egy Lua táblázatot reqs, és csináld ngx.location.capture_multi.

Mindezek a kérések párhuzamosan érkeznek, és a válaszokat visszaküldik nekünk. A futási idő megegyezik a leglassabb válaszidejével. Ha mindannyian 50 ezredmásodperc alatt lőünk vissza, és száz kérést küldünk, akkor 50 ezredmásodperc alatt kapunk választ.
Mivel lusták vagyunk, és nem akarunk HTTP-kezelést és gyorsítótárat írni, az NGINX-et megtesszük helyettünk. Amint láttad, volt egy kérés url/fetch, itt van:

Egyszerűsítjük proxy_pass, adja meg, hol kell gyorsítótárat tárolni, hogyan kell csinálni, és minden működik nekünk.
De ez nem elég, az adatokat továbbra is át kell adnunk a felhasználónak. A legegyszerűbb ötlet az, hogy mindent JSON-ba sorosítunk, egyszerűen, két sorban. Tartalomtípust adunk, JSON-t adunk.
De van egy nehézség: a felhasználó nem akarja olvasni a JSON-t. Csábítanunk kell a front-end fejlesztőket. Néha először nincs kedvünk hozzá. Igen, és a SEO szakemberek azt mondják majd, hogy ha képeket keresünk, akkor nem érdekli őket. És ha adunk nekik némi tartalmat, azt fogják mondani, hogy a keresőmotorjaink nem indexelnek semmit.
Mit kell vele csinálni? Természetesen megadjuk a felhasználónak a HTML-t. A fogantyúkkal történő generálás nem comme il faut, ezért szeretnénk sablonokat használni. Erre van könyvtár lua-resty-template.

Biztosan láttad a három rettegett OPM betűt. Az OpenResty saját csomagkezelővel rendelkezik, amelyen keresztül számos különböző modult telepíthet, különösen, lua-resty-template. Ez egy egyszerű sablonmotor, amely hasonló a Django sablonokhoz. Itt kódot írhat és változó helyettesítést végezhet.
Ennek eredményeként minden így fog kinézni:

Felvettük az adatokat, és két sorban újra rendereltük a sablont. A felhasználó boldog, macskák vannak. Mivel kibővítettük a kérést, cicáknak szánt szőrfókát is kapott. Soha nem lehet tudni, lehet, hogy kereste, de nem tudta helyesen megfogalmazni a kérését.
Minden rendben van, de fejlesztés alatt állunk, és még nem akarjuk megmutatni a felhasználóknak. Csináljunk felhatalmazást. Ehhez nézzük meg, hogyan kezeli az NGINX a kérést az OpenResty szempontjából:
- Első fázis - hozzáférés, amikor éppen jött a felhasználó, és megnéztük őt fejlécek, IP-címek, egyéb adatok alapján. Azonnal levághatjuk, ha nem szeretjük. Ezt fel lehet használni az engedélyezésre, vagy ha sok kérés érkezik hozzánk, akkor ebben a fázisban könnyen feldarabolhatjuk azokat.
- rewrite. Néhány kérési adat átírása.
- tartalom. Tartalmat adunk a felhasználónak.
- fejléc szűrő. Módosítsa a válaszfejléceket. Ha használnánk
proxy_pass, átírhatunk néhány fejlécet, mielőtt megadnánk a felhasználónak. - testszűrő. Megváltoztathatjuk a testünket.
- log - fakitermelés. Az elaszticsearch-ben további réteg nélkül is lehet naplókat írni.
Engedélyezésünk valahogy így fog kinézni:

Hozzáadjuk location, amelyet korábban leírtunk, és helyezze oda a következő kódot:

Megnézzük, hogy van-e sütijelzőnk. Ha nem, akkor felhatalmazást adunk. A felhasználók furfangosak, és azt sejthetik, hogy cookie-tokkent kell beállítani. Ezért a Redisbe is betesszük:

A Redis-szel való munkavégzés kódja nagyon egyszerű, és nem különbözik más nyelvektől. Ugyanakkor minden bemenet / kimenet, ami van, ami itt van, nem blokkol. Ha szinkron kódot ír, akkor aszinkron módon működik. Mint a geventnél, csak jól sikerült.

Végezzük el magát az engedélyezést:

Azt mondjuk, hogy el kell olvasnunk a kérés törzsét. POST argumentumokat kapunk, ellenőrizze, hogy a bejelentkezési név és a jelszó helyes-e. Ha hibás, akkor felhatalmazást adunk. És ha helyesek, akkor írjuk a tokent Redisnek:

Ne felejtse el beállítani a sütit, ez is két sorban történik:

A példa egyszerű, spekulatív. Természetesen nem készítünk olyan szolgáltatást, amely macskákat mutat meg az embereknek. De ki ismer minket. Tehát nézzük meg, mit lehet tenni a termelésben.
- Minimalista háttér. Néha elég sok adatot kell kiadnunk a háttérrendszernek: hol a dátumot kell helyettesíteni, hol valami listát kell megjeleníteni, mondjuk hány felhasználó van most az oldalon, csavarni kell egy számlálót vagy statisztikákat. Valami olyan kicsi. Néhány minimális darab nagyon könnyen elkészíthető. Ez gyors, egyszerű és nagyszerű lesz.
- Adatok előfeldolgozása. Néha hirdetéseket szeretnénk beágyazni oldalunkba, és ezeket API-kérésekkel fogadjuk. Ezt itt nagyon könnyű megtenni. Nem töltjük be a háttérrendszerünket, amely már keményen dolgozik. Itt tudod átvenni és átvenni. Néhány JS-t formázhatunk, vagy éppen ellenkezőleg, leválaszthatunk, elődolgozhatunk valamit, mielőtt a felhasználónak adnánk.
- Homlokzat mikroszervizhez. Ez is nagyon jó eset, meg is valósítottam. Ezt megelőzően a Tenzornál dolgoztam, egy elektronikus jelentéstevő cégnél, amely az ország jogi személyeinek mintegy fele számára biztosít jelentést. Létrehoztunk egy szolgáltatást, sok mindent ugyanazzal a mechanizmussal végeznek: útválasztás, engedélyezés stb.
Az OpenResty a mikroszolgáltatások ragasztójaként használható, hogy egyetlen hozzáférést biztosítson mindenhez és egyetlen felületet. Mivel a mikroszolgáltatásokat úgy is meg lehet írni, hogy itt van a Node.js, itt van PHP, itt van Python, itt van valami Erlang dolog, megértjük, hogy nem akarjuk mindenhol ugyanazt a kódot átírni. Ezért az OpenResty csatlakoztatható az előlaphoz. - Statisztika és elemzés. Általában az NGINX a bejáratnál van, és minden kérés ezen keresztül megy át. Ezen a helyen nagyon kényelmes a gyűjtés. Azonnal kiszámolhat valamit és eldobhatja valahova, például ugyanazt az Elasticsearch-ot, Logstash-t, vagy csak beírhatja a naplóba, és elküldheti valahova.
- Többfelhasználós rendszerek. Például az online játékok is nagyon jók. Ma Fokvárosban Alexander Gladysh elmeséli, hogyan lehet gyorsan prototípust készíteni egy többszemélyes játékot az OpenResty segítségével.
- Szűrés kérése (WAF). Manapság divat mindenféle webalkalmazás-tűzfalat készíteni, sok szolgáltatás nyújt ilyet. Az OpenResty segítségével webalkalmazás-tűzfalat készíthet magának, amely egyszerűen és egyszerűen szűri a kéréseket az Ön igényei szerint. Ha van Python-ja, akkor megérti, hogy a PHP-t biztosan nem fogják beinjektálni, kivéve, ha természetesen a konzolról bárhol előállítja. Tudod, hogy MySQL-el és Python-nal rendelkezel. Valószínűleg itt megpróbálhatnak valamiféle címtárbejárást végezni és beszúrni valamit az adatbázisba. Ezért a hülye kéréseket gyorsan és olcsón kiszűrheti közvetlenül az elején.
- Közösség. Mivel az OpenResty NGINX-en alapul, van egy bónusza – ez az NGINX közösség. Nagyon nagy, és az NGINX közössége már megválaszolta az első kérdéseket.
Lua fejlesztők. Tegnap beszélgettem azokkal a srácokkal, akik eljöttek a HighLoad ++ edzésnapra és hallottam, hogy csak a Tarantool van Lua nyelven írva. Ez nem így van, sok minden le van írva Lua nyelven. Példák: OpenResty, Prosody XMPP szerver, Love2D játékmotor, a Lua forgatókönyve Warcraftban és máshol van. Nagyon sok Lua fejlesztő van, nagy és érzékeny közösségük van. Minden Luával kapcsolatos kérdésemre néhány órán belül választ kaptam. Amikor írsz a levelezőlistára, szó szerint pár perc múlva már egy rakás válasz van, leírják, hogy mit és hogyan, mi az, ami. Ez nagyszerű. Ilyen kedves őszinte közösség sajnos nem mindenhol van.
Az OpenResty-nek van GitHubja, ahol meg lehet nyitni a problémát, ha valami elromlik. A Google Csoportokban van egy levelezőlista, ahol általános kérdéseket vitathat meg, van egy kínai nyelvű levelezőlista – sosem tudhatja, lehet, hogy nem beszél angolul, de van kínai nyelvtudása.
Eredményei
- Remélem, sikerült érzékeltetnem, hogy az OpenResty egy nagyon kényelmes, webre szabott keretrendszer.
- Alacsony a belépési küszöb, mivel a kód hasonló ahhoz, amit írunk, a nyelvezet meglehetősen egyszerű és minimalista.
- Aszinkron I/O-t biztosít visszahívások nélkül, nem lesz tészta, ahogy néha NodeJS-ben írhatjuk.
- Könnyen telepíthető, mert csak NGINX kell a megfelelő modullal és a kódunkkal, és minden azonnal működik.
- Nagy és érzékeny közösség.
Nem árultam el részletesen, hogyan történik az útválasztás, nagyon hosszú történetnek bizonyult.
Спасибо за внимание!

Forrás: will.com
