OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveriAtkal publicējam konferences ziņojuma stenogrammu HighLoad++ 2016, kas notika Skolkovā pie Maskavas pagājušā gada 7.-8.novembrī. Vladimirs Protasovs paskaidrots, kā paplašināt NGINX funkcionalitāti, izmantojot OpenResty un Lua.

Sveiki visiem, mani sauc Vladimirs Protasovs, es strādāju Parallels. Pastāstīšu mazliet par sevi. Trīs ceturtdaļas savas dzīves pavadu, rakstot kodu. Es kļuvu par programmētāju līdz sirds dziļumiem tiešā nozīmē: dažreiz sapņos redzu kodu. Ceturtā daļa dzīves ir rūpnieciskā attīstība, rakstot kodu, kas nonāk ražošanā. Kods, ko daži no jums izmanto, bet to neapzinās.

Tātad jūs saprotat, cik slikti tas bija. Kad es biju mazs, es atnācu un man iedeva šīs divu terabaitu datu bāzes. Tagad šeit visiem ir liela slodze. Es devos uz konferencēm un jautāju: “Puiši, sakiet man, jums ir lieli dati, vai viss ir forši? Cik bāzu tev tur ir? Viņi man atbildēja: "Mums ir 100 gigabaiti!" Es teicu: "Forši, 100 gigabaiti!" Un es pie sevis domāju, kā rūpīgi uzturēt savu pokera seju. Jūs domājat, jā, puiši ir forši, un tad jūs atgriežaties un ķeraties pie šīm vairāku terabaitu datubāzēm. Un šī ir būt junioram. Vai varat iedomāties, kāds tas ir trieciens?

Es zinu vairāk nekā 20 programmēšanas valodas. Tas ir kaut kas, kas man bija jāizdomā, strādājot. Viņi dod jums kodu Erlang, C, C++, Lua, Python, Ruby un kaut ko citu, un jums tas viss ir jāizgriež. Vispār man vajadzēja. Precīzu skaitli izrēķināt neizdevās, bet kaut kur ap 20. skaitlis pazuda.

Tā kā visi klātesošie zina, kas ir Parallels un ko mēs darām, es nerunāšu par to, cik mēs esam forši un ko mēs darām. Es tikai pastāstīšu, ka mums ir 13 biroji visā pasaulē, vairāk nekā 300 darbinieku, attīstība Maskavā, Tallinā un Maltā. Ja vēlaties, varat to ņemt un pārcelties uz Maltu, ja ziemā ir auksts un jums ir nepieciešams sasildīt muguru.

Konkrēti, mūsu nodaļa raksta Python 2. Mēs esam biznesā un nav laika ieviest modernas tehnoloģijas, tāpēc mēs ciešam. Mēs izmantojam Django, jo tajā ir viss, un mēs paņēmām nevajadzīgo un izmetām to. Arī MySQL, Redis un NGINX. Mums ir arī daudz citu foršu lietu. Mums ir MongoDB, mums skraida truši, mums ir viss, bet tas nav mans, un es to nedaru.

OpenResty

Es stāstīju par sevi. Izdomāsim, par ko es šodien runāšu:

  • Kas ir OpenResty un ar ko to ēd?
  • Kāpēc no jauna izgudrot citu riteni, ja mums ir Python, NodeJS, PHP, Go un citas lieliskas lietas, ar kurām visi ir apmierināti?
  • Un daži piemēri no dzīves. Man bija ļoti jāsagriež atskaite, jo tas aizņēma 3,5 stundas, tāpēc piemēru būs maz.

OpenResty ir NGINX. Pateicoties viņam, mums ir pilnvērtīgs tīmekļa serveris, kas ir labi uzrakstīts un darbojas ātri. Es domāju, ka lielākā daļa no mums ražošanā izmanto NGINX. Jūs visi zināt, ka viņš ir ātrs un foršs. Viņi tajā izveidoja foršu sinhrono I/O, tāpēc mums nekas nav jāpārvieto, tāpat kā viņi to darīja programmā Python. Gevent ir foršs, lielisks, bet, ja uzrakstīsit C kodu un kaut kas noiet greizi, tad ar Gevent jūs traki atkļūdosit. Man bija pieredze: vajadzēja veselas divas dienas, lai saprastu, kas tur nogāja greizi. Ja kāds nebūtu rakņājies vairākas nedēļas, atradis problēmu, rakstījis internetā un Google nebūtu atradis, tad mēs būtu galīgi traki.

NGINX jau ir izveidota kešatmiņa un statiskais saturs. Jums nav jāuztraucas par to, kā to izdarīt cilvēciski, lai jūs kaut kur nepalēninātu ātrumu, lai jūs kaut kur nepazaudētu deskriptorus. Nginx ir ļoti ērti izvietot, jums nav jādomā, ko ņemt - WSGI, PHP-FPM, Gunicorn, Unicorn. Nginx tika instalēts, iedots adminiem, viņi zina, kā ar to strādāt. Nginx apstrādā pieprasījumus strukturētā veidā. Par to es runāšu nedaudz vēlāk. Īsāk sakot, tam ir fāze, kad tas tikko pieņēma pieprasījumu, kad tas to apstrādāja un kad tas sniedza saturu lietotājam.

Nginx ir foršs, taču ir viena problēma: tas nav pietiekami elastīgs, pat ar visām lieliskajām funkcijām, kuras puiši ir pieblīvējuši konfigurācijā, neskatoties uz to, ko var konfigurēt. Ar šo spēku nepietiek. Tāpēc puiši no Taobao sen, šķiet, pirms astoņiem gadiem, tajā iebūvēja Lua. Ko tas dod?

  • Izmērs. Tas ir mazs. LuaJIT nodrošina aptuveni 100–200 kilobaitu atmiņas un minimālu veiktspēju.
  • Ātrums. LuaJIT tulks daudzās situācijās ir tuvu C, dažās situācijās tas zaudē Java, citās pārspēj to. Kādu laiku tas tika uzskatīts par modernāko, stilīgāko JIT kompilatoru. Tagad ir vēsāki, bet tie ir ļoti smagi, piemēram, tas pats V8. Daži JS tulki un Java HotSpot dažos punktos ir ātrāki, taču dažviet tie joprojām zaudē.
  • Viegli iemācīties. Ja jums ir, teiksim, Perl koda bāze un jūs neesat Booking, jūs neatradīsit Perl programmētājus. Tā kā viņi neeksistē, tie visi tika atņemti, un to mācīšana ir ilga un sarežģīta. Ja vēlaties programmētājus kaut kam citam, jums var nākties viņus pārkvalificēt vai atrast. Lua gadījumā viss ir vienkārši. Jebkurš juniors var apgūt Lua trīs dienās. Man vajadzēja apmēram divas stundas, lai to izdomātu. Pēc divām stundām es jau rakstīju kodu ražošanā. Apmēram pēc nedēļas viņš uzreiz devās uz ražošanu un aizgāja.

Rezultātā tas izskatās šādi:

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Šeit ir daudz. OpenResty ir savācis virkni moduļu, gan luash, gan motorus. Un jums viss ir gatavs — izvietots un darbojas.

piemēri

Pietiek ar dziesmu vārdiem, pāriesim pie koda. Šeit ir mazs Hello World:

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Kas tur ir? Šī ir Enginsas atrašanās vieta. Mēs neuztraucamies, mēs nerakstām paši savu maršrutēšanu, mēs neņemam gatavu — mums tas jau ir NGINX, mēs dzīvojam labi un laiski.

content_by_lua_block ir bloks, kurā teikts, ka mēs apkalpojam saturu, izmantojot Lua skriptu. Mēs ņemam Engins mainīgo remote_addr un ielieciet to string.format. Tas ir tāds pats kā sprintf, tikai Lua valodā, tikai pareizi. Un mēs to dodam klientam.

Rezultātā tas izskatīsies šādi:

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Bet atgriezīsimies reālajā pasaulē. Neviens neizvieto Hello World ražošanā. Mūsu pieteikums parasti nonāk datu bāzē vai kaut kur citur un lielāko daļu laika gaida atbildi.

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Viņš vienkārši sēž un gaida. Tas nav ļoti labi. Kad nāk 100.000 XNUMX lietotāju, mums ir ļoti grūti. Tāpēc kā piemēru izmantosim vienkāršu lietojumprogrammu. Meklēsim attēlus, piemēram, kaķus. Taču mēs ne tikai meklēsim, bet arī paplašināsim atslēgvārdus, un, ja lietotājs meklēja “kaķēni”, mēs atradīsim kaķus, pūkainus kaķus utt. Pirmkārt, mums ir jāiegūst pieprasījuma dati aizmugursistēmā. Tas izskatās šādi:

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Divas līnijas ļauj uzņemt GET parametrus, bez sarežģījumiem. Tālāk, pieņemsim, no datu bāzes ar zīmi atslēgvārdam un paplašinājumam mēs iegūstam šo informāciju, izmantojot parastu SQL vaicājumu. Tas ir vienkārši. Tas izskatās šādi:

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Bibliotēkas savienošana resty.mysql, kas mums jau ir komplektā. Mums nekas nav jāinstalē, viss ir gatavs. Mēs norādām, kā izveidot savienojumu un veikt SQL vaicājumu:

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Šeit ir nedaudz biedējoši, bet viss darbojas. Šeit 10 ir robeža. Izvelkam 10 ierakstus, esam slinki, negribam vairāk rādīt. Es aizmirsu par ierobežojumu SQL.

Tālāk mēs atrodam attēlus visiem jautājumiem. Mēs apkopojam virkni pieprasījumu un aizpildām Lua tabulu ar nosaukumu reqs, un mēs to darām ngx.location.capture_multi.

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Visi šie pieprasījumi tiek nosūtīti paralēli, un atbildes tiek atgrieztas mums. Darbības laiks ir vienāds ar lēnākās reakcijas laiku. Ja mēs visi nošaujam 50 milisekundēs un nosūtīsim simts pieprasījumu, tad atbildi saņemsim 50 milisekundēs.

Tā kā mēs esam slinki un nevēlamies rakstīt HTTP un kešatmiņas apstrādi, mēs liksim NGINX visu izdarīt mūsu vietā. Kā jūs redzējāt, bija pieprasījums pēc url/fetch, lūk, viņš ir:

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Mēs to padarām vienkāršu proxy_pass, mēs norādām, kur saglabāt kešatmiņu, kā to izdarīt, un viss darbojas mūsu labā.

Bet ar to nepietiek, mums joprojām ir jāsniedz dati lietotājam. Vienkāršākā ideja ir serializēt visu JSON, vienkārši, divās rindās. Mēs piešķiram satura veidu, mēs piešķiram JSON.

Bet ir viena grūtība: lietotājs nevēlas lasīt JSON. Mums ir jāpiesaista priekšgala izstrādātāji. Dažreiz mēs nevēlamies to darīt sākumā. Un SEO speciālisti teiks, ja mēs meklējam attēlus, tad viņiem tas nav svarīgi. Un, ja mēs viņiem piešķirsim saturu, viņi teiks, ka mūsu meklētājprogrammas neko neindeksē.

Ko darīt ar to? Protams, lietotājam dosim HTML. Ar roku ģenerēšana nav nekas neparasts, tāpēc mēs vēlamies izmantot veidnes. Tam ir bibliotēka lua-resty-template.

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Jūs droši vien esat redzējuši trīs biedējošus burtus OPM. OpenResty ir aprīkots ar savu pakotņu pārvaldnieku, caur kuru varat instalēt virkni dažādu moduļu, jo īpaši, lua-resty-template. Šis ir vienkāršs veidņu dzinējs, kas līdzīgs Django veidnēm. Tur jūs varat rakstīt kodu un veikt mainīgo aizstāšanu.

Rezultātā viss izskatīsies apmēram šādi:

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Mēs paņēmām datus un atveidojām veidni, atkal divās rindās. Lietotājs ir apmierināts, viņš saņēma kaķus. Tā kā pieprasījumu paplašinājām, viņš saņēma arī kažoku kažokādu. Nekad nevar zināt, varbūt viņš meklēja tieši to, bet nevarēja pareizi formulēt savu lūgumu.

Viss ir forši, taču mēs esam izstrādes stadijā un vēl nevēlamies to rādīt lietotājiem. Izdarīsim autorizāciju. Lai to izdarītu, apskatīsim, kā NGINX apstrādā pieprasījumu OpenResty izteiksmē:

  • Pirmā fāze - pieeja, kad lietotājs tikko ieradās, un mēs viņu aplūkojām pēc galvenēm, pēc IP adreses un citiem datiem. Mēs varam to nekavējoties pārtraukt, ja mums tas nepatīk. To var izmantot autorizācijai, vai, ja saņemam daudz pieprasījumu, mēs varam tos vienkārši pārtraukt šajā posmā.
  • pārrakstīt. Mēs pārrakstām dažus pieprasījuma datus.
  • saturs. Mēs piegādājam saturu lietotājam.
  • galvenes filtrs. Mēs nomainām atbilžu galvenes. Ja mēs izmantotu proxy_pass, mēs varam pārrakstīt dažas galvenes pirms tās piešķiršanas lietotājam.
  • ķermeņa filtrs. Mēs varam mainīt ķermeni.
  • log — mežizstrāde. Jūs varat rakstīt žurnālus elasticearch bez papildu slāņa.

Mūsu autorizācija izskatīsies apmēram šādi:

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Mēs pievienosim šo location, kuru mēs aprakstījām iepriekš, un ievietojiet tur šādu kodu:

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Mēs skatāmies, vai mums ir sīkdatnes marķieris. Ja nē, tad mēs lūdzam atļauju. Lietotāji ir viltīgi un var uzminēt, ka viņiem ir jāiestata sīkfaila marķieris. Tāpēc mēs to ievietosim arī Redis:

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Kods darbam ar Redis ir ļoti vienkāršs un neatšķiras no citām valodām. Tajā pašā laikā visa ievade/izvade šeit un tur netiek bloķēta. Ja rakstāt sinhrono kodu, tas darbojas asinhroni. Gandrīz kā gevents, bet paveikts labi.

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Veiksim pašu autorizāciju:

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Mēs sakām, ka mums ir jāizlasa pieprasījuma pamatteksts. Mēs saņemam POST argumentus un pārbaudām, vai pieteikšanās un parole ir pareiza. Ja tie ir nepareizi, mēs izaicinām jūs, lai saņemtu atļauju. Un, ja tas ir pareizi, ierakstiet tokenu Redis:

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Neaizmirstiet iestatīt sīkfailu, tas tiek darīts arī divās rindās:

OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Piemērs ir vienkāršs un spekulatīvs. Protams, mēs netaisīsim servisu, kas rāda cilvēkiem kaķus. Bet kas mūs pazīst. Tāpēc apskatīsim, ko var izdarīt ražošanā.

  • Minimālistiska aizmugure. Dažreiz mums ir jāievada tikai nedaudz datu aizmugursistēmai: kaut kur jāievieto datums, kaut kur jāparāda saraksts, jāpasaka, cik lietotāju pašlaik ir vietnē, jāpievieno skaitītājs vai statistika. Kaut kas tik mazs. Dažus minimālos gabalus var izgatavot ļoti vienkārši. Tas padarīs to ātri, vienkārši un lieliski.
  • Datu priekšapstrāde. Dažreiz mēs vēlamies iegult reklāmu savā lapā, un mēs saņemam šo reklāmu, izmantojot API pieprasījumus. Šeit to ir ļoti viegli izdarīt. Neuzlādējam savu aizmuguri, kas jau sēž un smagi strādā. Jūs varat to paņemt un savākt šeit. Mēs varam bruģēt dažus JS vai, gluži pretēji, to atsaistīt un kaut ko iepriekš apstrādāt, pirms to nododam lietotājam.
  • Fasāde mikroservisam. Šis arī ir ļoti labs gadījums, es to īstenoju. Pirms tam strādāju uzņēmumā Tenzor, kas nodarbojas ar elektronisko pārskatu sagatavošanu un nodrošina atskaites aptuveni pusei valsts juridisko personu. Mēs izveidojām pakalpojumu, daudzas lietas tika veiktas, izmantojot vienu un to pašu mehānismu: maršrutēšana, autorizācija un daudz kas cits.
    OpenResty var izmantot kā līmi jūsu mikropakalpojumiem, nodrošinot vienotu piekļuvi visam un vienu saskarni. Tā kā mikropakalpojumus var rakstīt tā, ka jums ir Node.js šeit, PHP šeit, Python šeit, kaut kāda Erlang lieta, mēs saprotam, ka mēs nevēlamies pārrakstīt vienu un to pašu kodu visur. Tāpēc OpenResty var pievienot priekšpusē.
  • Statistika un analītika. Parasti NGINX atrodas pie ieejas, un visi pieprasījumi tiek nosūtīti caur to. Tieši šajā vietā ir ļoti ērti savākt. Varat uzreiz kaut ko aprēķināt un kaut kur augšupielādēt, piemēram, Elasticsearch, Logstash, vai vienkārši ierakstīt žurnālā un pēc tam kaut kur nosūtīt.
  • Daudzlietotāju sistēmas. Piemēram, tiešsaistes spēles ir arī ļoti labas. Šodien Keiptaunā Aleksandrs Gladišs runās par to, kā ātri izveidot vairāku spēlētāju spēles prototipu, izmantojot OpenResty.
  • Pieprasījumu filtrēšana (WAF). Tagad ir modē veidot visu veidu tīmekļa lietojumprogrammu ugunsmūrus, ir daudz pakalpojumu, kas tos nodrošina. Izmantojot OpenResty, varat izveidot sev tīmekļa lietojumprogrammu ugunsmūri, kas vienkārši un viegli filtrēs pieprasījumus atbilstoši jūsu prasībām. Ja tev ir Python, tad tu saproti, ka PHP tev noteikti netiks iepludināts, ja vien, protams, tu to nekur no konsoles nepanesīsi. Jūs zināt, ka jums ir MySQL un Python. Iespējams, viņi varētu mēģināt veikt kādu direktoriju šķērsošanu un kaut ko ievadīt datu bāzē. Tāpēc jūs varat ātri un lēti filtrēt dīvainus vaicājumus tieši priekšpusē.
  • Kopiena. Tā kā OpenResty ir veidots uz NGINX, tam ir bonuss - šis NGINX kopiena. Tas ir ļoti liels, un NGINX kopiena jau ir atrisinājusi pienācīgu daļu no jautājumiem, kas jums vispirms radīsies.

    Lua izstrādātāji. Vakar runāju ar puišiem, kuri ieradās uz HighLoad++ treniņu dienu un dzirdēja, ka Lua valodā ir rakstīts tikai Tarantool. Tā nav taisnība, daudz kas ir rakstīts lua valodā. Piemēri: OpenResty, Prosody XMPP serveris, Love2D spēļu dzinējs, Lua skripts Warcraft un citur. Lua izstrādātāju ir daudz, viņiem ir liela un atsaucīga kopiena. Visi mani Lua jautājumi tika atrisināti dažu stundu laikā. Kad tu raksti uz adresātu sarakstu, burtiski dažu minūšu laikā jau ir virkne atbilžu, kas apraksta, kas un kā, kas ir kas. Tas ir lieliski. Diemžēl šāda laipna, garīga kopiena nav visur.
    Ir pieejams GitHub for OpenResty, kurā varat atvērt problēmu, ja kaut kas ir bojāts. Google grupās ir adresātu saraksts, kurā varat apspriest vispārīgus jautājumus, ir adresātu saraksts ķīniešu valodā — jūs nekad nezināt, varbūt jūs nerunājat angliski, bet jūs zināt ķīniešu valodu.

Rezultāti

  • Es ceru, ka varēju pateikt, ka OpenResty ir ļoti ērts ietvars, kas pielāgots tīmeklim.
  • Tam ir zema barjera ienākšanai, jo kods ir līdzīgs tam, ko mēs rakstām, valoda ir diezgan vienkārša un minimālistiska.
  • Tas nodrošina asinhronu I/O bez atzvanīšanas, mums nebūs tādu nūdeļu, kā mēs dažreiz varam rakstīt NodeJS.
  • To ir viegli izvietot, jo mums ir nepieciešams tikai NGINX ar nepieciešamo moduli un mūsu kodu, un viss darbojas uzreiz.
  • Liela un atsaucīga kopiena.

Sīkāk nestāstīju, kā notiek maršrutēšana, tas izrādījās ļoti garš stāsts.

Спасибо за внимание!

Play video

Vladimirs Protasovs - OpenResty: pārvēršot NGINX par pilnvērtīgu lietojumprogrammu serveri

Avots: www.habr.com

Pievieno komentāru