Veebirakendused on tĂ€napĂ€eval laialdaselt kasutusel ning HTTP hĂ”lmab suure osa kĂ”igist transpordiprotokollidest. Veebirakenduste arendamise nĂŒansse uurides pöörab enamik inimesi vĂ€ga vĂ€he tĂ€helepanu operatsioonisĂŒsteemile, kus need rakendused tegelikult töötavad. Arenduse (Dev) ja operaatori (Ops) eristamine on olukorda ainult halvendanud. Kuid DevOpsi kultuuri levikuga hakkavad arendajad vĂ”tma vastutust oma rakenduste kĂ€ivitamise eest pilves, seega on neile vĂ€ga kasulik pĂ”hjalikult tutvuda operatsioonisĂŒsteemi tagumise poolega. See on eriti oluline, kui proovite sĂŒsteemi seadistada tuhandete vĂ”i kĂŒmnete tuhandete samaaegsete ĂŒhenduste jaoks.
Veebiteenuste piirangud on vĂ€ga sarnased teiste rakenduste piirangutega. Olgu need koormuse tasakaalustajad vĂ”i andmebaasirakendused, kĂ”igil neil rakendustel on sarnased probleemid kĂ”rgvĂ”imekuses keskkonnas. Nende pĂ”hipiirangute ja nende ĂŒletamise meetodite mĂ”istmine aitab ĂŒldiselt hinnata teie veebirakenduste jĂ”udlust ja skaleeritavust.
Ma kirjutan seda artiklite seeriat vastuseks noorte arendajate kĂŒsimustele, kes soovivad saada hĂ€sti informeeritud sĂŒsteemi arhitektideks. Pole vĂ”imalik selgelt mĂ”ista Linuxi rakenduste optimeerimise meetodeid, ilma et sukelduda aluspĂ”himĂ”tetesse, kuidas need töötavad operatsioonisĂŒsteemi tasandil. Kuigi rakenduste tĂŒĂŒpe on palju, tahan selles tsĂŒklis uurida vĂ”rgurakendusi, mitte töölauarakendusi nagu brauserid vĂ”i tekstiredaktorid. See materjal on suunatud arendajatele ja arhitektidele, kes soovivad mĂ”ista, kuidas Linuxi vĂ”i Unix rakendused töötavad ja kuidas neid kĂ”rge jĂ”udluse saavutamiseks struktureerida.
Linux on serveri operatsioonisĂŒsteem, ning enamasti töötavad teie rakendused just sellel OS-il. Kuigi ma rÀÀgin 'Linuxist', vĂ”ite enamiku ajast kindlalt eeldada, et mĂ”eldakse kĂ”iki Unixiga sarnaseid operatsioonisĂŒsteeme tervikuna. Siiski ei ole ma kaasasolevat koodi testinud teistes sĂŒsteemides. Seega, kui teid huvitab FreeBSD vĂ”i OpenBSD, vĂ”ivad tulemused erineda. Kui proovin midagi Linuxiga seotud, siis mainin seda.
Kuigi saate omandatud teadmisi kasutada rakenduse loomiseks nullist ja see vĂ”ib olla suurepĂ€raselt optimeeritud, on parem seda mitte teha. Kui kirjutate oma organisatsiooni Ă€ri rakenduse jaoks uue veebiserveri C vĂ”i C++ keeles, vĂ”ib see olla teie viimane tööpĂ€ev. Siiski aitab nende rakenduste struktuuri tundmine valida juba olemasolevaid programme. Saate vĂ”rrelda protsessidele pĂ”hinevaid sĂŒsteeme, voogude ja sĂŒndmuste pĂ”hiseid sĂŒsteeme. Te mĂ”istate ja hindate, miks Nginx töötab paremini kui Apache httpd ning miks Tornado pĂ”hinev Python rakendus suudab teenindada rohkem kasutajaid vĂ”rreldes Django pĂ”hise Python rakendusega.
ZeroHTTPd: Ôppimistööriist
 â veebiserver, mille ma kirjutasin nullist C keeles kui Ă”ppevahend. Sellel ei ole vĂ€liseid sĂ”ltuvusi, sealhulgas juurdepÀÀsu Redis'ile. KĂ€ivitame oma Redis protseduurid. Lisateave allpool.
Kuigi me saaksime kaua arutada teooriat, pole midagi paremat kui koodi kirjutamine, selle kĂ€ivitamine ja kĂ”ikide serveri arhitektuuride omavaheline vĂ”rdlemine. See on kĂ”ige ilmsem meetod. SeetĂ”ttu kirjutame lihtsa veebiserveri ZeroHTTPd, rakendades iga mudelit: protsesside, voogude ja sĂŒndmuste pĂ”hjal. Kontrollime igat nende serverit ja vaatame, kuidas nad ĂŒksteisega vĂ”rreldes toimivad. ZeroHTTPd on rakendatud ĂŒhes C-failis. SĂŒndmuste pĂ”hise serveri koosseis sisaldab , suurepĂ€rane hash-tabeli teostus, mis tuleb ĂŒhes pealkirjafailis. Muudel juhtudel ei ole mingeid sĂ”ltuvusi, et projekti mitte keerulisemaks muuta.
Koodis on palju kommentaare, et aidata mĂ”ista. Tulles vĂ€lismaailmast, on ZeroHTTPd ka lihtne veebiarenduse raamistik. Selle funktsionaalsus on piiratud, kuid see suudab edastada staatilisi faile ja vĂ€ga lihtsaid âdĂŒnaamilisiâ lehti. Pean ĂŒtlema, et ZeroHTTPd sobib hĂ€sti Ă”ppimiseks, kuidas luua kĂ”rge jĂ”udlusega Linuxi rakendusi. Suures plaanis ootavad enamik veebiteenuseid pĂ€ringute esitamist, kontrollimist ja töötlemist. Just seda teebki ZeroHTTPd. See on Ă”ppimistööriist, mitte tootmisvahend. See ei ole tugev vigade töötlemisel ja tĂ”enĂ€oliselt ei uhkusta see parimate turvapraktikatega (jah, ma kasutasin strcpy) vĂ”i keerukate keelte trikiga C. Kuid ma loodan, et ta teeb oma ĂŒlesannet hĂ€sti.

ZeroHTTPd eelolev leht. See suudab edastada erinevat tĂŒĂŒpi faile, sealhulgas pilte.
KĂŒlastuste raamat rakendus
Kaasaegsed veebirakendused ei piirduma lihtsalt staatiliste failidega. Neil on keerulised suhted erinevate andmebaaside, vahemĂ€cachede jne. SeetĂ”ttu loome lihtsa veebirakenduse nimega âKĂŒlastuste raamatâ, kus kĂŒlastajad jĂ€tavad oma nimede all sĂ”numeid. KĂŒlastuste raamatus salvestatakse varem jĂ€etud sĂ”numid. Lehe allosas on samuti kĂŒlastajate loend.

ZeroHTTPd KĂŒlastuste raamat veebirakendus
KĂŒlastajate loend ja kĂŒlastuste raamatu sĂ”numid salvestatakse Redis. Redisiga suhtlemiseks on rakendatud meie enda protseduurid, need ei sĂ”ltu vĂ€listest raamatukogudest. Ma ei ole suur sĂ”ber, kes kirjutab koju tellitud koodi, kui olemas on avalikud ja hĂ€sti testitud lahendused. Kuid ZeroHTTPdi eesmĂ€rk on Ă”ppida Linuxi jĂ”udlust ja juurdepÀÀsu vĂ€listest teenustest, samas kui HTTP-pĂ€ringute haldamine mĂ”jutab tĂ”siselt jĂ”udlust. Me peame saama tĂ€ieliku kontrolli Redisiga suhtlemise ĂŒle meie serveri arhitektuurides. Ăhes arhitektuuris kasutame blokeerivaid kutsunge, teistes - sĂŒndmuste pĂ”hiseid protseduure. VĂ€line Redis klientraamatukogu ei anna sellist kontrolli. Lisaks tĂ€idab meie vĂ€ike Redis klient vaid mĂ”nda funktsiooni (saamine, seadistamine ja vĂ”tme suurendamine; saamine ja lisamine massiivi). Lisaks sellele on Redis protokoll ÀÀrmiselt elegantne ja lihtne. Selle Ă”ppimiseks ei pea isegi erilist vaeva nĂ€gema. Fakt, et kogu töö, mida protokoll tĂ€idab, on umbkaudu sadades lĂ€htekoodiread, nĂ€itab, kui hĂ€sti see on lĂ€bi mĂ”eldud.
JÀrgmises joonises on nÀidatud rakenduse tegevust, kui klient (brauser) teeb taotluse /guestbookURL.

KĂŒlastuste raamat rakenduse töömehhanism
Kui tuleb vĂ€lja anda kĂŒlalisraamatuleht, toimub ĂŒks sĂŒsteemikutsung faili sĂŒsteemile, et lugeda mall mĂ€lu ning kolm vĂ”rgu kutsungit Redisâesse. Mallifail sisaldab suure osa HTML-i sisust lehe jaoks, mis on ĂŒlaltoodud ekraanipildil. Seal on ka spetsiaalsed kohandajad dĂŒnaamilise sisu osa jaoks: postitused ja kĂŒlastajate loendur. Saame need Redis'est, sisestame lehele ja edastame kliendile tĂ€ielikult vormistatud sisu. Kolmandast Redis'e kutsungist saab loobuda, kuna Redis tagastab vĂ”tme uue vÀÀrtuse ka siis, kui seda suurendame. Siiski on meie sĂŒndmustepĂ”hise asĂŒnkroonse arhitektuuri jaoks palju vĂ”rgu kutseid hea katse eesmĂ€rkidel. Seega loobume Redis'e tagastatud vÀÀrtusest kĂŒlastajate arvu kohta ja kĂŒsime selle eraldi kutsega.
ZeroHTTPd serveri arhitektuurid
Ehime seitse versiooni ZeroHTTPdâst, millel on sama funktsionaalsus, kuid erinevad arhitektuurid:
- Iteratiivne
- Fork server (ĂŒks tĂŒtartöötlus pĂ€ringu kohta)
- Pre-fork server (protsesside eelne kogumine)
- Server tĂ€itmisniidiga (ĂŒks niit pĂ€ringu kohta)
- Server eelnevalt loodud niitidega
- Arhitektuur, mis pÔhineb
poll() - Arhitektuur, mis pÔhineb
epoll
KÀime iga arhitektuuri jÔudlust HTTP-pÀringutega koormates. Kuid kÔrge paralleelsuse arhitektuuride vÔrdlemisel suureneb pÀringute arv. Testime kolm korda ja arvutame keskmise.
Testimise metodologia

ZeroHTTPd koormustestimise seadmed
Oluline on, et testimise ajal ei töötaks kĂ”ik komponendid ĂŒhes masinas. Sel juhul kannab operatsioonisĂŒsteem lisakoormust ajastamisel, kuna komponendid konkureerivad CPU pĂ€rast. OperatsioonisĂŒsteemi koormuse mÔÔtmine igas valitud serveri arhitektuuris on see harjutuse ĂŒks olulisemaid eesmĂ€rke. Liigsete muutujate lisamine kahjustab protsessi. Seega töötab ĂŒlaltoodud seade kĂ”ige paremini.
Mida igaĂŒks neist serveritest teeb
- load.unixism.net: siin kÀivitame
ab, Apache Benchmarki tööriista. See genereerib koormuse, mis on vajalik meie serveri arhitektuuride testimiseks. - nginx.unixism.net: mĂ”nikord soovime kĂ€ivitada rohkem kui ĂŒhe serveriprogrammi koopia. Selleks töötab Nginx server koos vastavate seadistustega koormuse tasakaalustajana, mis tuleb ab meie serveriprotsessidesse.
- zerohttpd.unixism.net: siin kĂ€ivitame meie serveriprogrammid seitsmes erinevas arhitektuuris, ĂŒhte korraga.
- redis.unixism.net: sellel serveril töötab Redis deemon, kus talletatakse kĂŒlalisteraamat ja kĂŒlastajate arvesti.
Kogu serverid töötavad ĂŒhes protsessori tuumas. Idee on hinnata igas arhitektuuris maksimaalset jĂ”udlust. Kuna kĂ”ik serveriprogrammid testitakse samal riistvaral, on see nende vĂ”rdlemise baas. Minu testimist seadistus koosneb Digital Ocean'ilt renditud virtuaalserveritest.
Mida me mÔÔdame?
Erinevaid nÀitajaid on vÔimalik mÔÔta. Hinnatakse iga arhitektuuri jÔudlust antud konfiguratsioonis, koormates servereid pÀringutega erinevatel paralleelsuse tasemetel: koormus kasvab 20-st kuni 15 000 samaaegse kasutajani.
Testi tulemused
JĂ€rgmises diagrammis on kujutatud serverite jĂ”udlust erinevates arhitektuurides erinevatel paralleelsuse tasemetel. Y-teljel on pĂ€ringud sekundis, X-teljel on paralleelsed ĂŒhendused.



Allpool on tabel tulemustega.
pÀringud sekundis
paralleelsus
iteratiivne
fork
ennehargne
sugemetoodika
enne-sugemetoodika
poll
epoll
20
7
112
2100
1800
2250
1900
2050
50
7
190
2200
1700
2200
2000
2000
100
7
245
2200
1700
2200
2150
2100
200
7
330
2300
1750
2300
2200
2100
300
â
380
2200
1800
2400
2250
2150
400
â
410
2200
1750
2600
2000
2000
500
â
440
2300
1850
2700
1900
2212
600
â
460
2400
1800
2500
1700
2519
700
â
460
2400
1600
2490
1550
2607
800
â
460
2400
1600
2540
1400
2553
900
â
460
2300
1600
2472
1200
2567
1000
â
475
2300
1700
2485
1150
2439
1500
â
490
2400
1550
2620
900
2479
2000
â
350
2400
1400
2396
550
2200
2500
â
280
2100
1300
2453
490
2262
3000
â
280
1900
1250
2502
suurem hajuvus
2138
5000
â
suurem hajuvus
1600
1100
2519
â
2235
8000
â
â
1200
suurem hajuvus
2451
â
2100
10Â 000
â
â
suurem hajuvus
â
2200
â
2200
11Â 000
â
â
â
â
2200
â
2122
12Â 000
â
â
â
â
970
â
1958
13Â 000
â
â
â
â
730
â
1897
14Â 000
â
â
â
â
590
â
1466
15Â 000
â
â
â
â
532
â
1281
Diagrammist ja tabelist nĂ€htub, et ĂŒle 8000 samaaegse pĂ€ringu korral jÀÀb meil alles vaid kaks mĂ€ngijat: ennehargne ja epoll. Koormuse kasvades töötab poll-pĂ”hine server halvemini kui sugemetoodika. Enehargne arhitektuur on epollile vÀÀriliseks konkurendiks: see tĂ”estab, kui hĂ€sti Linuxi tuum suudab planeerida suurtes kogustes niite.
ZeroHTTPd lÀhtekood
ZeroHTTPd lÀhtekood . Iga arhitektuuri jaoks eraldi kataloog.
ZeroHTTPd
â
âââ 01_iteratiivne
â âââ main.c
âââ 02_hargnev
â âââ main.c
âââ 03_ennehargnev
â âââ main.c
âââ 04_sugemetoodika
â âââ main.c
âââ 05_enne-sugemetoodika
â âââ main.c
âââ 06_poll
â âââ main.c
âââ 07_epoll
â âââ main.c
âââ Makefile
âââ public
â âââ index.html
â âââ tux.png
âââ templates
âââ guestbook
âââ index.htmlLisaks seitsmele kataloogile, mis on mĂ”eldud kĂ”igile arhitektuuridele, on ĂŒlemises kataloogis veel kaks: public ja templates. Esimese sees asub fail index.html ja pilt esimeselt ekraanipildilt. Sinna vĂ”ib panna ka teisi faile ja kaustu, ning ZeroHTTPd peaks need staatilised failid probleemideta vĂ€lja andma. Kui brauseri path vastab public kaustas olevale teele, siis otsib ZeroHTTPd sellest kataloogist faili index.html. KĂŒlastusraamatule mĂ”eldud sisu genereeritakse dĂŒnaamiliselt. Sellel on ainult avaleht, mille sisu pĂ”hineb failil âtemplates/guestbook/index.htmlâ. ZeroHTTPd-sse on lihtne lisada dĂŒnaamilisi lehti laiendamiseks. Idee seisneb selles, et kasutajad saavad selle katalooge lisada malle ja laiendada ZeroHTTPd-d vastavalt vajadusele.
Seitsme serveri kokkupanekuks kĂ€ivitage make all ĂŒlemise kataloogi sees â ja kĂ”ik buildid ilmuvad sellesse kataloogi. TĂ€idetavad failid otsivad public ja templates kaustu selles kataloogis, kust need kĂ€ivitatakse.
Linux API
Selle artiklite seeria teabe mĂ”istmiseks ei pea Linux API-s vĂ€ga hĂ€sti orienteeruma. Soovitan siiski lugeda selle kohta rohkem, veebis on palju abimaterjale. Kuigi me kĂ€sitleme mitmeid Linux API kategooriaid, keskendub meie tĂ€helepanu peamiselt protsessidele, lĂ”imele, sĂŒndmustele ja vĂ”rgu kihtidele. Peale raamatute ja artiklite Linux API-st soovitan ka lugeda sĂŒsteemikĂ”nede ja kasutatavate teekide funktsioonide manasid.
JÔudlus ja skaleeritavus
Ăks mĂ€rkus jĂ”udluse ja skaleeritavuse kohta. Teoreetiliselt pole nende vahel mingit seost. Teil vĂ”ib olla veebiteenus, mis töötab vĂ€ga hĂ€sti, vastusaegadega mĂ”ne millisekundi jooksul, kuid see ei skaleeru ĂŒldse. Samuti vĂ”ib olla halvasti toimiv veebirakendus, mis vajab vastamiseks mitu sekundit, kuid see on skaleeritav kĂŒmnete suhtes, et hallata kĂŒmneid tuhandeid samaaegseid kasutajaid. Teiselt poolt, kĂ”rge jĂ”udluse ja skaleeritavuse kombinatsioon on vĂ€ga vĂ”imas. KĂ”rge jĂ”udlusega rakendused kasutavad ressursse ĂŒldiselt sÀÀstlikult ja seega teenindavad tĂ”husalt rohkem samaaegseid kasutajaid serveris, vĂ€hendades kulusid.
CPU ja I/O ĂŒlesanded
LĂ”puks on arvutustes alati kaks vĂ”imalikku ĂŒlesannet: I/O ja CPU jaoks. Interneti kaudu pĂ€ringute saamine (vĂ”rgu sisend-vĂ€ljund), failide haldamine (vĂ”rgu ja kettasisend-vĂ€ljund), andmebaasiga suhtlemine (vĂ”rgu ja kettasisend-vĂ€ljund) - kĂ”ik need on I/O tegevused. MĂ”ned andmebaasi pĂ€ringud vĂ”ivad veidi koormata CPU-d (jĂ€rjestamine, miljoni tulemuse keskmise arvutamine jne). Enamik veebirakendusi on piiratud maksimaalse vĂ”imaliku I/O-ga, samas kui protsessorit harva kasutatakse tĂ€ielikult. Kui mĂ€rkate, et mĂ”nes sisend-vĂ€ljundi ĂŒlesandes kasutatakse palju CPU-d, on tĂ”enĂ€oliselt tegemist halva rakenduse arhitektuuri tunnusega. See vĂ”ib tĂ€hendada, et CPU ressursid kuluvad protsesside juhtimisele ja konteksti vahetamisele - ja see pole kuigi kasulik. Kui teete midagi nagu pilditöötlus, helifailide konverteerimine vĂ”i masinĂ”pe, siis nĂ”uab rakendus vĂ”imsaid CPU ressursse. Kuid enamik rakendusi ei nĂ”ua seda.
Ăksikasjalikumalt serveri arhitektuuridest
Allikas: habr.com
