Wy publisearje wer it transkripsje fan it konferinsjerapport 2016, dy't plakfûn yn Skolkovo by Moskou op 7-8 novimber ferline jier. ferklearret hoe't jo NGINX-funksjonaliteit útwreidzje mei OpenResty en Lua.
Hallo elkenien, myn namme is Vladimir Protasov, ik wurkje by Parallels. Ik sil dy wat oer mysels fertelle. Ik besteegje trijekwart fan myn libben skriuwen koade. Ik waard programmeur ta de kearn yn 'e letterlike sin: soms sjoch ik koade yn myn dreamen. In kwart fan it libben is yndustriële ûntwikkeling, it skriuwen fan koade dy't direkt yn produksje giet. In koade dy't guon fan jo brûke, mar it net realisearje.
Dat jo begripe hoe slim it wie. Doe't ik in lyts jonkje wie, kaam ik en krige dizze databases fan twa terabyte. It is hjir no hege lading foar elkenien. Ik gie nei konferinsjes en frege: "Jongens, sis my, jo hawwe grutte gegevens, is alles cool? Hoefolle bases hawwe jo dêr? Se antwurden my: "Wy hawwe 100 gigabyte!" Ik sei: "Cool, 100 gigabytes!" En ik tocht oan mysels hoe't ik soarchfâldich ûnderhâlde myn poker gesicht. Jo tinke, ja, de jonges binne cool, en dan geane jo werom en tinken mei dizze multi-terabyte databases. En dit is in junior wêze. Kin jo yntinke wat in klap dit is?
Ik ken mear as 20 programmeartalen. Dit is wat ik moast útfine as ik wurke. Se jouwe jo koade yn Erlang, C, C ++, Lua, Python, Ruby, wat oars, en jo moatte it allegear snije. Yn 't algemien moast ik. It wie net mooglik om it krekte oantal te berekkenjen, mar earne om de 20e hinne gie it nûmer ferlern.
Sûnt elkenien oanwêzich wit wat Parallels is en wat wy dogge, sil ik net prate oer hoe cool wy binne en wat wy dogge. Ik sil jo gewoan fertelle dat wy 13-kantoaren om 'e wrâld hawwe, mear as 300 meiwurkers, ûntwikkeling yn Moskou, Tallinn en Malta. As jo wolle, kinne jo it nimme en nei Malta ferhúzje as it kâld is yn 'e winter en jo moatte jo rêch waarmje.
Spesifyk skriuwt ús ôfdieling yn Python 2. Wy binne yn bedriuw en hawwe gjin tiid om modieuze technologyen út te fieren, sadat wy lije. Wy brûke Django om't it alles hat, en wy namen wat net nedich wie en smieten it fuort. Ek MySQL, Redis en NGINX. Wy hawwe ek in protte oare leuke dingen. Wy hawwe MongoDB, wy hawwe konijnen dy't rûnom rinne, wy hawwe alles - mar it is net fan my, en ik doch it net.
OpenResty
Ik fertelde oer mysels. Litte wy útfine wêr't ik hjoed oer sil prate:
- Wat is OpenResty en wêrmei wurdt it iten?
- Wêrom opnij in oar tsjil as wy hawwe Python, NodeJS, PHP, Gean en oare koele dingen dy't elkenien is bliid mei?
- En in pear foarbylden út it libben. Ik moast it rapport in protte besunigje om't it my 3,5 oeren koste, dus der sille in pear foarbylden wêze.
OpenResty is NGINX. Mei tank oan him hawwe wy in folsleine webserver dy't goed skreaun is en fluch wurket. Ik tink dat de measten fan ús NGINX brûke yn produksje. Jo witte allegear dat hy rap en cool is. Se makken der koele syngroane I/O yn, dus wy hoege neat te fytsen, krekt sa't se dien hawwe yn Python. Gevent is cool, geweldich, mar as jo C-koade skriuwe en der giet wat mis, dan sille jo mei Gevent gek wurde om it te debuggen. Ik hie de ûnderfining: it duorre twa hiele dagen om út te finen wat der mis gie. As immen in pear wiken net groeven hie, it probleem fûn, op it ynternet skreau, en Google hie it net fûn, dan soene wy folslein gek west hawwe.
NGINX hat al caching en statyske ynhâld dien. Jo hoege jo gjin soargen te meitsjen oer hoe't jo dit minsklik dwaan, sadat jo net earne fertrage, sadat jo gjin descriptors earne ferlieze. Nginx is heul handich om yn te setten, jo hoege net te tinken oer wat jo moatte nimme - WSGI, PHP-FPM, Gunicorn, Unicorn. Nginx waard ynstalleare, jûn oan de admins, se witte hoe't se dermei wurkje. Nginx ferwurket oanfragen op in strukturearre manier. Ik sil it hjir noch efkes oer ha. Koartsein, it hat in faze doe't it krekt akseptearre it fersyk, doe't it ferwurke, en as it tsjinne de ynhâld oan de brûker.
Nginx is cool, mar d'r is ien probleem: it is net fleksibel genôch, sels mei alle coole funksjes dy't de jonges yn 'e konfiguraasje hawwe stutsen, nettsjinsteande it feit dat it kin wurde konfigureare. Dizze krêft is net genôch. Dêrom bouden de jonges út Taobao, lang lyn, it liket acht jier lyn, Lua yn. Wat jout it?
- grutte. It is lyts. LuaJIT jout sawat 100-200 kilobytes oan ûnthâldoverhead en minimale prestaasjesoverhead.
- Speed. De LuaJIT-tolk is yn in protte situaasjes tichtby C, yn guon situaasjes ferliest it oan Java, yn oaren prestearret it it better. Foar in skoft waard it beskôge as de state of art, de coolste JIT-kompiler. No binne d'r koeler, mar se binne heul swier, bygelyks deselde V8. Guon JS-tolken en Java HotSpot binne op guon punten flugger, mar op guon plakken ferlieze se noch.
- Maklik te learen. As jo hawwe, sizze, in Perl koade basis, en do bist net Booking, do silst net fine Perl programmeurs. Om't se net besteane, waarden se allegear fuorthelle, en learje se is lang en dreech. As jo programmeurs foar wat oars wolle, moatte jo se miskien ek opnij opliede of fine. Yn it gefal fan Lua is alles ienfâldich. Elke junior kin Lua yn trije dagen leare. It duorre my sawat twa oeren om it út te finen. Twa oeren letter skreau ik al koade yn produksje. Sawat in wike letter gie er direkt nei de produksje en gie er fuort.
As resultaat sjocht it der sa út:

Der is in protte hjir. OpenResty hat in boskje modules sammele, sawol luash as motor. En jo hawwe alles klear - ynset en wurkje.
foarbylden
Genôch fan 'e teksten, lit ús gean nei de koade. Hjir is in bytsje Hello World:

Wat is der? Dit is in Engins-lokaasje. Wy meitsje ús gjin soargen, wy skriuwe ús eigen routing net, wy nimme gjin inkele klear - wy hawwe it al yn NGINX, wy libje in goed en loai libben.
content_by_lua_block is in blok dat seit dat wy ynhâld tsjinje mei in Lua-skript. Wy nimme de Engines fariabele remote_addr en set it yn string.format. Dit is itselde as sprintf, allinnich yn Lua, allinne korrekt. En wy jouwe it oan de klant.
As resultaat sil it der sa útsjen:

Mar litte wy weromgean nei de echte wrâld. Nimmen set Hello World yn foar produksje. Us applikaasje giet normaal nei de databank of earne oars en wachtet meastentiids op in antwurd.

Hy sit mar te wachtsjen. It is net hiel goed. As 100.000 brûkers komme, is it foar ús heul lestich. Lit ús dus in ienfâldige applikaasje as foarbyld brûke. Wy sille sykje foar foto's, bygelyks, fan katten. Mar wy sille net allinich sykje, wy sille de kaaiwurden útwreidzje en, as de brûker socht nei "kitten", sille wy katten, furry katten, ensfh. Earst moatte wy de fersykgegevens krije op 'e efterkant. It sjocht der sa út:

Twa rigels kinne jo GET parameters ophelje, gjin komplikaasjes. Litte wy dan sizze, fan in databank mei in teken foar in kaaiwurd en útwreiding, krije wy dizze ynformaasje mei in gewoane SQL-query. It is ienfâldich. It sjocht der sa út:

Ferbine de biblioteek resty.mysql, dy't wy al yn 'e kit hawwe. Wy hoege neat te ynstallearjen, alles is klear. Wy jouwe oan hoe't jo ferbine en in SQL-query meitsje:

It is hjir in bytsje eng, mar alles wurket. Hjir is 10 de limyt. Wy lûke 10 ynstjoerings út, wy binne lui, wy wolle net mear sjen litte. Ik fergeat oer de limyt yn SQL.
Folgjende fine wy foto's foar alle fragen. Wy sammelje in boskje fersiken en folje in Lua tafel neamd reqs,en wy ngx.location.capture_multi.

Al dizze oanfragen wurde parallel stjoerd, en antwurden wurde ús weromjûn. De wurktiid is lyk oan de reaksjetiid fan de stadichste. As wy allegear sjitte yn 50 millisekonden, en wy stjoere hûndert oanfragen, dan krije wy in antwurd yn 50 millisekonden.
Om't wy lui binne en gjin HTTP en caching-ôfhanneling wolle skriuwe, sille wy NGINX alles foar ús dwaan. Sa't jo seagen, wie der in fersyk foar url/fetch, hjir is hy:

Wy meitsje it ienfâldich proxy_pass, Wy jouwe oan wêr't te cache, hoe te dwaan, en alles wurket foar ús.
Mar dit is net genôch, wy moatte noch de gegevens oan de brûker jaan. It ienfâldichste idee is om alles yn JSON te serialisearjen, maklik, yn twa rigels. Wy jouwe Content-Type, wy jouwe JSON.
Mar d'r is ien muoite: de brûker wol JSON net lêze. Wy moatte front-end ûntwikkelders oanlûke. Soms wolle wy dit earst net dwaan. En SEO-spesjalisten sille sizze dat as wy nei foto's sykje, dan makket it har net út. En as wy har wat ynhâld jouwe, sille se sizze dat ús sykmasines neat yndeksearje.
Wat der oan te dwaan? Fansels sille wy de brûker HTML jaan. Generearje mei de hân is net comme il faut, dus wy wolle sjabloanen brûke. Dêr is in bibleteek foar lua-resty-template.

Jo hawwe wierskynlik de trije skriklike letters OPM sjoen. OpenResty komt mei in eigen pakketbehearder, wêrmei jo in boskje ferskate modules kinne ynstallearje, benammen, lua-resty-template. Dit is in ienfâldige sjabloanmotor, fergelykber mei Django-sjabloanen. Dêr kinne jo koade skriuwe en fariabele ferfanging útfiere.
As resultaat sil alles der sa útsjen:

Wy namen de gegevens en rendered it sjabloan, wer yn twa rigels. De brûker is bliid, hy krige katten. Sûnt wy it fersyk útwreide, krige hy ek in bontseal foar kittens. Jo witte noait, miskien socht er krekt dit, mar koe syn fersyk net goed formulearje.
Alles is cool, mar wy binne yn ûntwikkeling en wolle it noch net oan brûkers sjen litte. Litte wy de autorisaasje dwaan. Om dit te dwaan, litte wy sjen hoe't NGINX it fersyk behannelet yn OpenResty-termen:
- Earste faze - tagong, doe't de brûker krekt oankaam, en wy seagen him troch kopteksten, troch IP-adres, en troch oare gegevens. Wy kinne it fuortendaliks ôfsnije as wy it net leuk fine. Dit kin brûkt wurde foar autorisaasje, of as wy in protte oanfragen krije, kinne wy se yn dizze faze maklik ôfsnije.
- rewrite. Wy skriuwe wat fersykgegevens oer.
- ynhâld. Wy leverje de ynhâld oan de brûker.
- koptekst filter. Wy ferfange de antwurdkoppen. As wy brûkten
proxy_pass, kinne wy wat kopteksten opnij skriuwe foardat jo it oan de brûker jouwe. - lichem filter. Wy kinne it lichem feroarje.
- lochboek - logging. Jo kinne logs skriuwe yn elasticsearch sûnder in ekstra laach.
Us autorisaasje sil der sa útsjen:

Wy sille dit tafoegje oan dy location, dy't wy earder beskreaun hawwe, en sette de folgjende koade dêr:

Wy sjogge om te sjen oft wy in koekje token hawwe. Sa net, dan freegje wy om autorisaasje. Brûkers binne slûch en kinne riede dat se in koekje token moatte ynstelle. Dêrom sille wy it ek yn Redis sette:

De koade foar it wurkjen mei Redis is heul ienfâldich en is net oars fan oare talen. Tagelyk is alle ynfier / útfier, hjir en dêr, net blokkearje. As jo skriuwe syngroane koade, it wurket asynchronously. Hast as jaant, mar goed dien.

Litte wy de autorisaasje sels dwaan:

Wy sizze dat wy it lichem fan it fersyk moatte lêze. Wy ûntfange POST-arguminten en kontrolearje dat de oanmelding en wachtwurd goed binne. As se ferkeard binne, dan daagje wy jo út foar autorisaasje. En as it goed is, skriuw dan it token yn Redis:

Ferjit net it koekje yn te stellen, dit wurdt ek dien yn twa rigels:

It foarbyld is ienfâldich en spekulatyf. Fansels sille wy gjin tsjinst meitsje dy't minsken katten sjen litte. Mar wa ken ús. Dus litte wy gean oer wat kin wurde dien yn produksje.
- Minimalistyske backend. Soms moatte wy mar in bytsje gegevens útfiere nei de efterkant: earne moatte wy in datum ynfoegje, earne moatte wy in list sjen litte, sizze hoefolle brûkers no op 'e side binne, in teller of statistiken taheakje. Wat sa lyts. Guon minimale stikken kinne heul maklik makke wurde. Dit sil it fluch, maklik en geweldich meitsje.
- Gegevens foarferwurking. Soms wolle wy advertinsjes ynsette yn ús side, en wy ûntfange dizze advertinsjes mei API-oanfragen. Dit is hjir hiel maklik te dwaan. Wy laden ús backend net, dy't al hurd sit en wurket. Jo kinne it hjir ophelje en sammelje. Wy kinne wat JS byinoar skodzje of, oarsom, it ûntkoppele en wat foarferwurkje foardat jo it oan de brûker jouwe.
- Gevel foar mikroservice. Dit is ek in heul goede saak, ik haw it útfierd. Dêrfoar wurke ik by Tenzor, in bedriuw dat him dwaande hâldt mei elektroanyske rapportaazje en rapportaazje leveret oan likernôch de helte fan de juridyske entiteiten yn it lân. Wy hawwe in tsjinst makke, in protte dingen waarden dêr dien mei itselde meganisme: routing, autorisaasje en mear.
OpenResty kin brûkt wurde as de lijm foar jo mikrotsjinsten, en biedt ien tagong ta alles en in inkele ynterface. Sûnt mikrotsjinsten kinne wurde skreaun op sa'n manier dat jo Node.js hjir, PHP hjir, Python hjir, wat Erlang ding hjir, wy begripe dat wy net wolle herskriuwe deselde koade oeral. Dêrom kin OpenResty yn 'e foarkant wurde pluggen. - Statistiken en analytics. Meastal is NGINX by de yngong, en alle fersiken geane troch it. It is op dit plak dat it heul handich is om te sammeljen. Jo kinne fuortendaliks berekkenje wat en upload it earne, bygelyks, Elasticsearch, Logstash, of gewoan skriuwe it oan it log en dan stjoer it earne.
- Multi-brûker systemen. Bygelyks, online games binne ek hiel goed in make. Hjoed yn Kaapstêd sil Alexander Gladysh prate oer hoe't jo in multiplayer-spiel fluch prototype kinne mei OpenResty.
- Request Filtering (WAF). Tsjintwurdich is it moade om allerhanne firewalls foar webapplikaasjes te meitsjen; d'r binne in protte tsjinsten dy't se leverje. Mei OpenResty kinne jo sels in firewall foar webapplikaasje meitsje dy't fersiken ienfâldich en maklik sil filterje neffens jo easken. As jo Python hawwe, dan begripe jo dat PHP perfoarst net yn jo ynjeksje sil, útsein as jo it fansels oeral fan 'e konsole spawnje. Jo witte dat jo MySQL en Python hawwe. Wierskynlik, se kinne besykje te dwaan wat soarte fan triemtafel traversal en inject wat yn de databank. Dêrom kinne jo frjemde fragen fluch en goedkeap direkt oan 'e foarkant filterje.
- Mienskip. Sûnt OpenResty is boud op NGINX, hat it in bonus - dit NGINX mienskip. It is heul grut, en in fatsoenlik diel fan 'e fragen dy't jo earst sille hawwe binne al oplost troch de NGINX-mienskip.
Lua ûntwikkelders. Juster praat ik mei de jonges dy't nei de HighLoad++ trainingsdei kamen en hearden dat allinich Tarantool yn Lua skreaun waard. Dit is net wier, in protte dingen binne skreaun yn Lua. Foarbylden: OpenResty, Prosody XMPP-tsjinner, Love2D-spielmotor, Lua skreaun yn Warcraft en op oare plakken. D'r binne in protte Lua-ûntwikkelders, se hawwe in grutte en responsive mienskip. Al myn Lua-fragen waarden binnen in pear oeren oplost. As jo nei de mailinglist skriuwe, binne d'r letterlik binnen in pear minuten al in bulte reaksjes, dy't beskriuwe wat en hoe, wat is wat. It is geweldich. Spitigernôch is sa'n soarte, geastlike mienskip net oeral.
D'r is GitHub foar OpenResty, wêr't jo in probleem kinne iepenje as der wat is brutsen. D'r is in mailinglist op Google Groups, wêr't jo algemiene problemen kinne besprekke, d'r is in mailinglist yn it Sineesk - jo witte it noait, miskien prate jo gjin Ingelsk, mar jo kinne Sineesk.
Resultaten
- Ik hoopje dat ik koe oerbringe dat OpenResty in heul handich ramt is op maat foar it web.
- It hat in lege barriêre foar yngong, om't de koade fergelykber is mei wat wy yn skriuwe, is de taal frij ienfâldich en minimalistysk.
- It leveret asynchrone I/O sûnder callbacks, wy sille gjin noedels hawwe lykas wy soms kinne skriuwe yn NodeJS.
- It hat maklike ynset, om't wy allinich NGINX nedich binne mei de nedige module en ús koade, en alles wurket direkt.
- Grutte en responsive mienskip.
Ik haw net yn detail ferteld hoe't routing dien wurdt, it waard in heul lang ferhaal.
Спасибо за внимание!

Boarne: www.habr.com
