Avaldame uuesti konverentsi ettekande stenogrammi 2016, mis peeti Moskva lÀhedal Skolkovos mullu 7.-8.novembril. rÀÀgib, kuidas laiendada NGINX-i funktsioone OpenResty ja Lua abil.
Tere kÔigile, minu nimi on Vladimir Protasov, töötan ettevÔttes Parallels. Ma rÀÀgin teile natuke endast. Kolmveerand oma elust kulutan koodi kirjutamisele. Minust sai hingepÔhjani programmeerija selle otseses mÔttes: nÀen mÔnikord unenÀgudes koodi. Veerand elust on tööstusareng, kirjutades koodi, mis lÀheb otse tootmisse. Kood, mida mÔned teist kasutavad, kuid ei tea seda.
Et teaksite, kui halb see oli. Kui olin vĂ€ike noorem, tulin sisse ja nad andsid mulle need kaks terabaidist andmebaasi. See on nĂŒĂŒd siin kĂ”igile highload. KĂ€isin konverentsidel ja kĂŒsisin: "Poisid, öelge mulle, kas teil on suuri andmeid, kas kĂ”ik on lahe? Mitu alust sul seal on? Nad vastasid mulle: "Meil on 100 gigabaiti!" Ma ĂŒtlesin: "Lahe, 100 gigabaiti!" Ja mĂ”tlesin endamisi, kuidas pokkerinagu kenasti pÀÀsta. Arvate, jah, poisid on lahedad, ja siis tulete tagasi ja nokitsete nende mitme terabaidise andmebaaside kallal. Ja see on juunior olemine. Kas kujutate ette, milline hitt see on?
Ma tean rohkem kui 20 programmeerimiskeelt. Selle pidin ma töö kĂ€igus vĂ€lja mĂ”tlema. Nad annavad teile koodi Erlangis, C-s, C++-s, Lua-s, Pythonis, Ruby-s, milleski muus ja sa pead selle kĂ”ik Ă€ra lĂ”ikama. Ăldiselt pidin. TĂ€pset arvu polnud vĂ”imalik vĂ€lja arvutada, aga kuskil 20 kandis lĂ€ks number kaduma.
Kuna kĂ”ik siin teavad, mis on Parallels ja mida me teeme, siis ma ei hakka rÀÀkima, kui lahedad me oleme ja mida me teeme. Ătlen vaid, et meil on 13 esindust ĂŒle maailma, ĂŒle 300 töötaja, arendus Moskvas, Tallinnas ja Maltal. Soovi korral vĂ”ite vĂ”tta ja kolida Maltale, kui talvel on kĂŒlm ja on vaja selga soojendada.
TĂ€psemalt, meie osakond kirjutab Python 2-s. Oleme Ă€ris ja meil pole aega moekaid tehnoloogiaid tutvustada, seega kannatame. Meil on Django, sest sellel on kĂ”ik olemas, vĂ”tsime ĂŒleliigse ja viskasime minema. Samuti MySQL, Redis ja NGINX. Meil on ka palju muud Ă€gedat. Meil on MongoDB, meil jooksevad jĂ€nesed ringi, meil pole lihtsalt midagi â aga see pole minu oma ja ma ei tee seda.
OpenResty
RÀÀkisin endast. Vaatame, millest ma tÀna rÀÀgin:
- Mis on OpenResty ja millega seda sĂŒĂŒakse?
- Miks leiutada ratast, kui meil on Python, NodeJS, PHP, Go ja muud lahedad asjad, millega kÔik rahul on?
- Ja paar nÀidet elust. Pidin aruannet kÔvasti kÀrpima, sest sain 3,5 tunniks, nii et nÀiteid tuleb vÀheks.
OpenResty on NGINX. TĂ€nu temale on meil tĂ€isvÀÀrtuslik veebiserver, mis on hĂ€sti kirjutatud, töötab kiiresti. Arvan, et enamik meist kasutab tootmises NGINX-i. Te kĂ”ik teate, et ta on kiire ja lahe. Nad tegid selles lahedad sĂŒnkroonsed I/O-d, nii et meil pole vaja midagi tsĂŒklistada samal viisil, nagu geventi Pythonis tsĂŒklistati. Gevent on lahe, lahe, aga kui kirjutad C-koodi ja geventiga lĂ€heb midagi valesti, lĂ€hed silumisega hulluks. Mul oli kogemus: kulus tervelt kaks pĂ€eva, et aru saada, mis seal valesti lĂ€ks. Kui keegi poleks varem paar nĂ€dalat kaevanud, ei leidnud probleemi ĂŒles, poleks internetti kirjutanud ja Google poleks leidnud, siis oleksime tĂ€itsa hulluks lĂ€inud.
NGINX juba teeb vahemĂ€llu salvestamist ja staatilist sisu. Te ei pea muretsema selle pĂ€rast, kuidas seda inimlikult teha, et te ei vĂ”taks kiirust kuskil maha, et te ei kaotaks kirjeldusi kuhugi. Nginxi on vĂ€ga mugav juurutada, ei pea mĂ”tlema, mida vĂ”tta â WSGI, PHP-FPM, Gunicorn, Unicorn. Nginx installiti, anti administraatoritele, nad teavad, kuidas sellega töötada. Nginx töötleb taotlusi struktureeritud viisil. Ma rÀÀgin sellest veidi hiljem. ĂhesĂ”naga, tal on faas, mil ta lihtsalt vĂ”ttis taotluse vastu, millal ta töötles ja millal andis sisu kasutajale.
Nginx on lahe, kuid sellel on ĂŒks probleem: see pole piisavalt paindlik isegi kĂ”igi nende lahedate funktsioonidega, mille poisid konfiguratsiooni sisse lĂŒkkasid, hoolimata asjaolust, et seda saab kohandada. Sellest vĂ”imust ei piisa. SeetĂ”ttu ehitasid Taobao kutid kunagi, ma arvan, et umbes kaheksa aastat tagasi Lua sinna sisse. Mida ta annab?
- Suurus. See on vÀike. LuaJIT annab kuskil 100-200 kilobaiti mÀlu ja minimaalse jÔudluse.
- Kiirus. LuaJIT-i tĂ”lk on paljudes olukordades C-le lĂ€hedal, mĂ”nes olukorras kaotab Java-le, mĂ”nes möödub sellest. MĂ”nda aega peeti seda tipptasemel, kĂ”ige lahedamaks JIT-i koostajaks. NĂŒĂŒd on jahedamad, aga need on vĂ€ga rasked, nĂ€iteks seesama V8. MĂ”ned JS-i tĂ”lgid ja Java HotSpot on mĂ”nel hetkel kiiremad, kuid siiski kaotavad mĂ”nes punktis.
- Lihtne Ă”ppida. Kui teil on nĂ€iteks Perli koodibaas ja te ei ole Bookingis, ei leia te Perli programmeerijaid. Kuna neid seal pole, viidi nad kĂ”ik Ă€ra ning nende Ă”petamine on pikk ja raske. Kui soovite programmeerijaid millekski muuks, tuleb nad vĂ”ib-olla ka ĂŒmber koolitada vĂ”i leida. Lua puhul on kĂ”ik lihtne. Lua saab Ă”ppida iga juunior kolme pĂ€evaga. Mul kulus umbes kaks tundi, et sellest aru saada. Kaks tundi hiljem kirjutasin juba tootmises koodi. Umbes nĂ€dal hiljem lĂ€ks ta otse tootmisse ja lahkus.
Selle tulemusena nÀeb see vÀlja jÀrgmine:

Siin on palju. OpenResty on kokku pannud hulga mooduleid, nii luashi kui ka mootoreid. Ja teil on kĂ”ik valmis â kasutusele vĂ”etud ja töökorras.
nÀited
Aitab laulusÔnadest, liigume edasi koodi juurde. Siin on vÀike Hello World:

Mis seal on? see on mootorite asukoht. Me ei muretse, me ei kirjuta oma marsruutimist, me ei vÔta valmis marsruutimist - meil on see juba NGINXis, elame hÀsti ja laisalt.
content_by_lua_block on plokk, mis ĂŒtleb, et pakume sisu Lua skripti abil. VĂ”tame mootorite muutuja remote_addr ja libistage see sisse string.format. See on sama, mis sprintf, ainult Lua keeles, ainult Ă”ige. Ja me anname selle kliendile.
Selle tulemusena nÀeb see vÀlja jÀrgmine:

Aga tagasi pÀrismaailma. Tootmises ei kasuta keegi Hello Worldi. Meie rakendus lÀheb tavaliselt andmebaasi vÔi kuhugi mujale ja ootab enamasti vastust.

Lihtsalt istub ja ootab. See ei ole vĂ€ga hea. Kui tuleb 100.000 XNUMX kasutajat, on meil vĂ€ga raske. SeetĂ”ttu kasutame nĂ€itena lihtsat rakendust. Otsime pilte, nĂ€iteks kasse. Ainult me ââei hakka lihtsalt otsima, vaid laiendame mĂ€rksĂ”nu ja kui kasutaja otsis "kassipojad", siis leiame kassid, kohevad jne. KĂ”igepealt peame hankima taustaprogrammi pĂ€ringuandmed. See nĂ€eb vĂ€lja selline:

Kaks rida vÔimaldavad teil korjata GET-i parameetreid, ilma komplikatsioonideta. Siis saame selle teabe nÀiteks andmebaasist koos tabeliga mÀrksÔna ja laienduse kaupa tavalise SQL-pÀringu abil. KÔik on lihtne. See nÀeb vÀlja selline:

Ăhendame raamatukogu resty.mysql, mis meil juba komplektis on. Meil pole vaja midagi paigaldada, kĂ”ik on valmis. MÀÀrake ĂŒhenduse loomine ja SQL-pĂ€ringu tegemine:

See on natuke hirmutav, kuid see töötab. Siin on piir 10. TÔmbame vÀlja 10 plaati, oleme laisad, rohkem ei taha nÀidata. SQL-is unustasin limiidi Àra.
SeejÀrel leiame kÔigi pÀringute jaoks pildid. Kogume hunniku taotlusi ja tÀidame Lua tabeli nimega reqs, ja teha ngx.location.capture_multi.

KÔik need pÀringud lÀhevad paralleelselt ja vastused saadetakse meile tagasi. Tööaeg vÔrdub kÔige aeglasema reageerimisajaga. Kui me kÔik tulistame tagasi 50 millisekundiga ja saatsime sada pÀringut, siis saame vastuse 50 millisekundiga.
Kuna oleme laisad ega taha HTTP-kÀsitlust ja vahemÀllu kirjutada, siis paneme NGINX-i meie eest kÔik Àra tegema. Nagu nÀgite, oli taotlus url/fetch, siin ta on:

Teeme lihtsaks proxy_pass, tÀpsustage, kuhu vahemÀllu salvestada, kuidas seda teha ja kÔik töötab meie jaoks.
Kuid sellest ei piisa, me peame ikkagi andmed kasutajale andma. Lihtsaim idee on serialiseerida kĂ”ik lihtsalt kahes reas JSON-i. Anname sisutĂŒĂŒbi, anname JSON-i.
Kuid on ĂŒks raskus: kasutaja ei taha JSON-i lugeda. Peame meelitama esiotsa arendajaid. MĂ”nikord ei taha me alguses seda teha. Jah, ja SEO spetsialistid ĂŒtlevad, et kui me otsime pilte, siis nad ei hooli. Ja kui anname neile sisu, ĂŒtlevad nad, et meie otsingumootorid ei indekseeri midagi.
Mida sellega teha? Loomulikult anname kasutajale HTML-i. KĂ€epidemetega genereerimine ei ole comme il faut, seega tahame kasutada malle. Selle jaoks on raamatukogu lua-resty-template.

Olete kindlasti nÀinud kolme kardetud tÀhte OPM. OpenRestyga on kaasas oma paketihaldur, mille kaudu saate installida hulga erinevaid mooduleid, eriti lua-resty-template. See on lihtne mallimootor, mis sarnaneb Django mallidele. Seal saate kirjutada koodi ja teha muutujate asendusi.
Selle tulemusena nÀeb kÔik vÀlja umbes selline:

VĂ”tsime andmed ja renderdasime malli uuesti kahes reas. Kasutaja on rahul, sai kassid. Kuna me sooviavaldust laiendasime, sai ta ka kassipoegade karvahĂŒlge. Kunagi ei tea, vĂ”ib-olla ta otsis seda, aga ei osanud oma palvet Ă”igesti sĂ”nastada.
KÔik on lahe, kuid oleme arendusjÀrgus ja me ei taha veel kasutajatele nÀidata. Teeme volituse. Selleks vaatame, kuidas NGINX taotlust OpenResty osas kÀsitleb:
- Esimene etapp - juurdepÀÀs, kui kasutaja just tuli ja me vaatasime teda pĂ€iste, IP-aadressi ja muude andmete jĂ€rgi. VĂ”ite selle kohe Ă€ra lĂ”igata, kui see meile ei meeldi. Seda saab kasutada autoriseerimiseks vĂ”i kui saame palju pĂ€ringuid, saame need selles etapis hĂ”lpsasti tĂŒkeldada.
- ĂŒmber kirjutama. MĂ”nede pĂ€ringuandmete ĂŒmberkirjutamine.
- sisu. Anname sisu kasutajale.
- pÀise filter. Muutke vastuse pÀiseid. Kui kasutaksime
proxy_pass, saame mĂ”ned pĂ€ised enne kasutajale andmist ĂŒmber kirjutada. - keha filter. Me saame muuta keha.
- logi - metsaraie. Elasticsearchis on vÔimalik logisid kirjutada ilma lisakihita.
Meie volitus nÀeb vÀlja umbes selline:

Lisame selle sellele location, mida me varem kirjeldasime, ja panime sinna jÀrgmise koodi:

Vaatame, kas meil on kĂŒpsisemĂ€rk. Kui ei, siis anname volituse. Kasutajad on kavalad ja vĂ”ivad arvata, et tuleb seadistada kĂŒpsisemĂ€rk. SeetĂ”ttu paneme selle ka Redisesse:

Redisega töötamise kood on vĂ€ga lihtne ega erine teistest keeltest. Samal ajal kogu sisend / vĂ€ljund, mis seal on, mis siin on, see ei blokeeri. Kui kirjutate sĂŒnkroonset koodi, töötab see asĂŒnkroonselt. Nagu gevent, ainult hĂ€sti tehtud.

Teeme autoriseerimise ise:

Ătleme, et peame lugema pĂ€ringu sisu. Saame vastu POST-argumendid, kontrollime sisselogimise ja parooli Ă”igsust. Kui see on vale, anname volituse. Ja kui need on Ă”iged, kirjutame mĂ€rgi Redisele:

Ărge unustage kĂŒpsist seadistada, seda tehakse ka kahes reas:

NÀide on lihtne, spekulatiivne. Muidugi ei tee me teenust, mis inimestele kasse nÀitab. Aga kes meid tunneb. Nii et vaatame, mida saab tootmises teha.
- Minimalistlik taustaprogramm. MĂ”nikord peame taustaprogrammile vĂ€lja andma ĂŒsna palju andmeid: kuskil peame asendama kuupĂ€eva, kuskil peame kuvama mingi loendi, ĂŒtlema, mitu kasutajat saidil praegu on, keerama loenduri vĂ”i statistika. Midagi nii vĂ€ikest. MĂ”ned minimaalsed tĂŒkid saab teha vĂ€ga lihtsalt. See saab olema kiire, lihtne ja suurepĂ€rane.
- Andmete eeltöötlus. MÔnikord tahame oma lehele reklaame manustada ja vÔtame need reklaamid vastu API pÀringutega. Seda on siin vÀga lihtne teha. Me ei laadi oma taustaprogrammi, mis juba praegu kÔvasti töötab. Siin saate jÀrgi tulla ja koguda. Saame mÔnda JS-i vormida vÔi, vastupidi, lahti kleepida, enne kasutajale andmist midagi eeltöödelda.
- Fassaad mikroteenuse jaoks. See on ka vÀga hea juhtum, viisin selle ellu. Enne seda töötasin elektroonilises aruandlusettevÔttes Tenzor, mis annab aruandlust umbes poolte riigi juriidiliste isikute kohta. Oleme teinud teenuse, seal tehakse paljusid asju sama mehhanismi abil: marsruutimine, autoriseerimine ja palju muud.
OpenRestyt saab kasutada teie mikroteenuste liimina, et pakkuda kĂ”igele ĂŒhtset juurdepÀÀsu ja ĂŒhtset liidest. Kuna mikroteenuseid saab kirjutada nii, et siin on Node.js, siin on PHP, siin on Python, siin on mingi Erlangi asi, siis saame aru, et me ei taha sama koodi igal pool ĂŒmber kirjutada. SeetĂ”ttu saab OpenResty esikĂŒljele ĂŒhendada. - Statistika ja analĂŒĂŒtika. Tavaliselt on NGINX sissepÀÀsu juures ja kĂ”ik pĂ€ringud lĂ€hevad selle kaudu. Just selles kohas on seda vĂ€ga mugav koguda. Saab kohe midagi vĂ€lja arvutada ja kuhugi visata, nĂ€iteks seesama Elasticsearch, Logstash vĂ”i lihtsalt logisse kirjutada ja siis kuhugi saata.
- Mitme kasutaja sĂŒsteemid. NĂ€iteks vĂ”rgumĂ€nge on vĂ€ga hea teha. TĂ€na Kaplinnas rÀÀgib Alexander Gladysh teile, kuidas OpenResty abil kiiresti mitme mĂ€ngijaga mĂ€ngu prototĂŒĂŒpi luua.
- Filtreerimise taotlemine (WAF). NĂŒĂŒd on moes teha kĂ”ikvĂ”imalikke veebirakenduste tulemĂŒĂŒre, neid pakuvad palju teenuseid. OpenResty abil saad teha endale veebirakenduste tulemĂŒĂŒri, mis lihtsalt ja lihtsalt filtreerib pĂ€ringuid vastavalt Sinu vajadustele. Kui teil on Python, siis saate aru, et PHP-d teile kindlasti ei sĂŒstita, vĂ€lja arvatud juhul, kui te seda konsoolist kuhugi ei loo. Teate, et teil on MySQL ja Python. TĂ”enĂ€oliselt saavad nad siin proovida teha mingit kataloogi lĂ€bimist ja sisestada midagi andmebaasi. SeetĂ”ttu saate rumalad taotlused kiiresti ja odavalt vĂ€lja filtreerida otse esikĂŒljel.
- Kogukond. Kuna OpenResty pĂ”hineb NGINX-il, on sellel boonus - see on NGINX kogukond. See on vĂ€ga suur ja NGINX-i kogukond on juba vastanud paljudele teie esmalt tekkivatele kĂŒsimustele.
Lua arendajad. Eile rÀÀkisin kuttidega, kes tulid HighLoad ++ koolituspĂ€evale ja kuulsid, et Lua keeles on ainult Tarantool kirjutatud. See pole nii, palju asju on kirjutatud lua keeles. NĂ€ited: OpenResty, Prosody XMPP server, Love2D mĂ€ngumootor, Lua on skriptitud Warcraftis ja mujal. Lua arendajaid on palju, neil on suur ja vastutulelik kogukond. KĂ”igile minu Lua kĂŒsimustele vastati mĂ”ne tunni jooksul. Meililistile kirjutades on sĂ”na otseses mĂ”ttes mĂ”ne minuti pĂ€rast juba hunnik vastuseid, kirjeldatakse, mis ja kuidas, mis on mis. See on suurepĂ€rane. Kahjuks pole sellist lahket siirast kogukonda igal pool.
OpenRestyl on GitHub, kus saate probleemi avada, kui midagi lĂ€heb katki. Google'i gruppides on meililist, kus saate arutada ĂŒldisi probleeme, on olemas hiinakeelne meililist â kunagi ei tea, vĂ”ib-olla ei rÀÀgi te inglise keelt, aga oskate hiina keelt.
Tulemused
- Loodan, et suutsin öelda, et OpenResty on vÀga mugav veebiraamistik.
- Sellel on madal sisenemislĂ€vi, kuna kood sarnaneb meie kirjutatule, keel on ĂŒsna lihtne ja minimalistlik.
- See pakub asĂŒnkroonset sisendit/vĂ€ljundit ilma tagasihelistamisteta, meil ei ole nuudleid, nagu saame mĂ”nikord NodeJS-is kirjutada.
- Seda on lihtne juurutada, sest vajame ainult Ôige mooduli ja meie koodiga NGINX-i ning kÔik töötab koheselt.
- Suur ja vastutulelik kogukond.
Ma ei rÀÀkinud tÀpsemalt, kuidas marsruutimist tehakse, see osutus vÀga pikaks jutuks.
TÀnan teid tÀhelepanu eest!

Allikas: www.habr.com
