Veebirakendusi kasutatakse praegu igal pool ja HTTP domineeib kĂ”iki edastusprotokolle. Veebirakenduste arendamise nĂŒansse uurides pööravad paljud tĂ€helepanu vĂ€ga vĂ€he sellele operatsioonisĂŒsteemile, kus need rakendused tegelikult töötavad. Arenduse (Dev) ja opereerimise (Ops) eristaminen on olukorda veelgi halvendanud. Kuid DevOpsi kultuuri levikuga hakkavad arendajad vastutama oma rakenduste kĂ€ivitamise eest pilves, seega on vĂ€ga kasulik sĂŒveneda operatsioonisĂŒsteemi taustsĂŒsteemi tundmisse. See on eriti kasulik, kui proovite ĂŒles seada sĂŒsteemi tuhandete vĂ”i kĂŒmnete tuhandete samaaegsete ĂŒhenduste jaoks.
Veebiteenuste piirangud on vĂ€ga sarnased teiste rakenduste piirangutega. Olgu need koormuse tasakaalustajad vĂ”i andmebaasiserverid, kĂ”ikidel neil rakendustel on sarnased probleemid kĂ”rge jĂ”udlusega keskkonnas. Nende pĂ”hiliste piirangute mĂ”istmine ja nende ĂŒletamise viiside leidmine vĂ”imaldab ĂŒldiselt hinnata teie veebirakenduste jĂ”udlust ja skaleeritavust.
Kirjutan seda artiklite seeriat vastuseks noorte arendajate kĂŒsimustele, kes soovivad saada teadlikeks sĂŒsteemi arhitektideks. Linuxi rakenduste optimeerimise meetodeid ei saa selgelt mĂ”ista, kui ei sĂŒĂŒvi nende aluspĂ”himĂ”tetesse, kuidas need töötavad operatsioonisĂŒsteemi tasemel. Kuigi rakenduste tĂŒĂŒpe on palju, soovin antud tsĂŒklis uurida just vĂ”rgu rakendusi, mitte töölauarakendusi nagu brauserid vĂ”i tekstiredaktorid. See materjal on mĂ”eldud arendajatele ja arhitektidele, kes soovivad mĂ”ista, kuidas töötavad Linuxi vĂ”i Unix programmid ning kuidas neid kĂ”rge jĂ”udluse nimel struktureerida.
Linux on serveripĂ”hine operatsioonisĂŒsteem, ja kĂ”ige sagedamini töötavad teie rakendused just sellel OS-il. Kuigi rÀÀgin "Linuxist", vĂ”ite suurema osa ajast kindlalt eeldada, et silmas peetakse kĂ”iki Unix-tĂŒĂŒpi operatsioonisĂŒsteeme. Siiski, ma ei ole kaasnevat koodi testinud teistel sĂŒsteemidel. Nii et kui teid huvitab FreeBSD vĂ”i OpenBSD, vĂ”ivad tulemused erineda. Kui proovin midagi, mis on Linuxile spetsiifiline, annan sellest teada.
Kuigi saate omandatud teadmisi kasutada rakenduse loomiseks nullist, mis on suurepĂ€raselt optimeeritud, ei ole soovitatav seda teha. Kui kirjutate oma organisatsiooni Ă€rirakendusele uue veebi-serveri C vĂ”i C++ keeles, vĂ”ib see olla teie viimane tööpĂ€ev. Siiski aitab selliste rakenduste struktuuri tundmine valida juba olemasolevaid programme. Saate vĂ”rrelda protsessipĂ”hiseid sĂŒsteeme voogude- ja sĂŒndmuspĂ”histe sĂŒsteemidega. Te mĂ”istate ja hindate, miks Nginx töötab paremini kui Apache httpd, miks Python Tornado baasil töötav rakendus suudab teenindada rohkem kasutajaid vĂ”rreldes Python Django baasil töötava rakendusega.
ZeroHTTPd: Ôppevahend
 â veebi-server, mille kirjutasin nullist C keeles Ă”ppevahendina. Sellel ei ole vĂ€liseid sĂ”ltuvusi, sealhulgas juurdepÀÀsu Redis'ele. KĂ€ivitame oma Redise protseduurid. Lisainfot leiate allpool.
Kuigi me vĂ”iksime pikka aega arutada teooriat, ei ole miski parem kui kirjutada kood, kĂ€ivitada see ja vĂ”rrelda erinevaid serveri arhitektuure. See on kĂ”ige nĂ€itlikum meetod. SeetĂ”ttu kirjutame lihtsa veebiserveri ZeroHTTPd, rakendades igat mudelit: protsesside, niitide ja sĂŒndmuste pĂ”hjal. Kontrollime igaĂŒht neist serveritest ja vaatame, kuidas nad omavahel vĂ”rreldes toimivad. ZeroHTTPd on teostatud ĂŒhes C-failis. SĂŒndmuspĂ”hise serveri koosseisu kuulub , suurepĂ€rane hash-tabeli teostus, mis tarnitakse ĂŒhes pĂ€istefailis. Muude osade puhul ei ole mingeid sĂ”ltuvusi, et mitte projekti keeruliseks teha.
Koodis on palju kommentaare, mis aitavad arusaamist. ZeroHTTPd on lihtne veebiserver, mis koosneb vaid mĂ”nest koodireast ja esindab ka minimaalset raamistikku veebiarenduseks. Selle funktsionaalsus on piiratud, kuid see suudab serveerida 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. Ăldiselt ootavad enamik veebiteenuseid pĂ€ringute tĂ€itmist, kontrollivad neid ja töötlevad. Just seda teebki ZeroHTTPd. See on Ă”ppevahend, mitte tootmisriist. See ei ole tugev vigade töötlemises ja ei pruugi uhkustada parimate turvapraktikatega (oh jah, ma kasutasin strcpy) vĂ”i keerukate C-keele trikkidega. Kuid ma loodan, et see tĂ€idab oma ĂŒlesannet hĂ€sti.

ZeroHTTPd pealeht. See suudab esitada erinevaid failitĂŒĂŒpe, sealhulgas pilte.
KĂŒlastusraamatu rakendus
Kaasaegsed veebirakendused ei piirdu tavaliselt staatiliste failidega. Neil on keerukad interaktsioonid erinevate andmebaaside, cache'ide jne. SeetĂ”ttu loome lihtsa veebirakenduse nimega âKĂŒlastusraamatâ, kus kĂŒlastajad saavad jĂ€tta oma nime all kirjeid. KĂŒlastusraamat hoiab varasemaid kirjeid. Lehe alumises osas on ka kĂŒlastajate loendur.

Veebirakendus âKĂŒlastusraamatâ ZeroHTTPd
KĂŒlastuste arvesti ja kĂŒlalisteraamatu salvestamine toimub Redis'is. Kommunikatsioonide haldamiseks Redis'iga on vĂ€lja töötatud kohandatud protseduurid, mis ei sĂ”ltu vĂ€listest raamatukogudest. Ma ei ole suur kodarenduse koodi pooldaja, kui on olemas avalikult saadaval ja hĂ€sti testitud lahendusi. Kuid ZeroHTTPd eesmĂ€rk on uurida Linuxi jĂ”udlust ja juurdepÀÀsu vĂ€listel teenustele, samas kui HTTP-pĂ€ringute töötlemine mĂ”jutab jĂ”udlust tĂ”siselt. Me peame tĂ€ielikult kontrollima suhtlust Redis'iga igas meie serveri arhitektuuris. Ăhes arhitektuuris kasutame blokeerivaid kalle, teistes aga sĂŒndmuste pĂ”hiseid protseduure. VĂ€list Redis'i kliendi raamatukogu kasutamine ei anna sellist kontrolli. Lisaks tĂ€idab meie vĂ€ike Redis'i klient vaid mĂ”ningaid funktsioone (vĂ”tme saamine, seadmine ja suurendamine; massiivi saamine ja lisamine). Samuti on Redis'i protokoll ÀÀrmiselt elegantne ja lihtne. Selle Ă”ppimiseks ei pea isegi spetsiaalselt pingutama. Fakt, et kogu töö protokoll teeb umbes sada koodi rida, nĂ€itab, kui hĂ€sti see on lĂ€bi mĂ”eldud.
JÀrgmises joonises on nÀidatud rakenduse toimingud, kui klient (brauser) teeb pÀringu /guestbookURL.

KĂŒlalisraamatukirjelduste rakenduse töömehhanism
Kui kĂŒlalisraamatu lehte tuleb vĂ€lja anda, toimub ĂŒks failisĂŒsteemi kutsumine ŃĐ°Đ±Đ»ĐŸĐœite lugemiseks mĂ€llu ning kolm vĂ”rgu kutsumist Redis'esse. ĐšĐ°Đ±Đ»ĐŸĐœifail sisaldab suure osa HTML-i sisust, mis on ĂŒlemisel ekraanipildil. Seal on ka spetsiaalsed tĂ€itjatel dĂŒnaamilise sisu osa jaoks: postitused ja kĂŒlastajate loendur. Me saame need Redis'est, paigutame lehele ja vĂ€ljastame kliendile tĂ€ielikult vormistatud sisu. Kolmandat Redis'e kutsumist saab vĂ€ltida, kuna Redis tagastab vĂ”tme uue vÀÀrtuse suurendamisel. Kuid meie sĂŒndmustepĂ”hise asĂŒnkroonne arhitektuuri korral pakuvad paljud vĂ”rgu kutsumised hĂ€sti Ă”ppimise eesmĂ€rkidel. Seega ei kasuta me kĂŒlastajate arvu Redis'elt tagastatud vÀÀrtust, vaid kĂŒsime seda eraldi kutsumisega.
Serveri arhitektuurid ZeroHTTPd
Me ehitame seitse ZeroHTTPd versiooni sama funktsionaalsusega, kuid erineva arhitektuuriga:
- Iteratiivne
- Fork server (ĂŒks alamprotsess pĂ€ringu kohta)
- Eelseise server (protsesside eelne vormimine)
- Server, kus on tĂ€itmisvoogudes (ĂŒks lĂ”ng pĂ€ringu kohta)
- Server, kus on eelnevalt loodud vood
- Arhitektuur, millel on
poll() - Arhitektuur, millel on
epoll
MÔÔdame iga arhitektuuri jÔudlust, laadides serverit HTTP pÀringutega. Kuid kÔrge paralleelsuse korral suureneb pÀringute arv. Testime kolm korda ja arvutame keskmise.
Testimise metoodika

ZeroHTTPd koormustestimise seadistamine
Oluline on, et kĂ”iki komponente ei kĂ€itataks samal masinal testide ajal. Sel juhul kannab operatsioonisĂŒsteem tĂ€iendavaid kulusid ajakava tĂ”ttu, kuna komponendid konkureerivad CPU ĂŒle. OperatsioonisĂŒsteemi kulude mÔÔtmine igas valitud serveri arhitektuuris on selle harjutuse ĂŒks olulisemaid eesmĂ€rke. Rohkemate muutujate lisamine halvendab protsessi. Seega töötab ĂŒlaltoodud seadistus kĂ”ige paremini.
Mis teeb iga nende serverite puhul
- load.unixism.net: siin kÀitame
ab, Apache Benchmark utiliiti. See genereerib koormuse, mis on vajalik meie serveri arhitektuuride testimiseks. - nginx.unixism.net: mĂ”nikord soovime kĂ€itada rohkem kui ĂŒhte serveriprogrammi eksemplari. Selleks töötab Nginx server koos vastavate seadistustega koormuse jaoturina, mis jagab koormust ab meie serveriprotsessidele.
- zerohttpd.unixism.net: siin kĂ€itame meie serveriprogramme seitsme erineva arhitektuuri peal, ĂŒhte korraga.
- redis.unixism.net: sel serveril töötab Redis deemon, kus hoitakse kĂŒlalisteraamatu kirjeid ja kĂŒlastajate arvestit.
KĂ”ik serverid töötavad ĂŒhe protsessori tuuma peal. Idee on hinnata iga arhitektuuri maksimaalset jĂ”udlust. Kuna kĂ”ik serveriprogrammid testitakse sama riistvaral, on see nende vĂ”rdlemiseks alus. Minu testimisseade koosneb Digitaalsetest Ookeanist renditud virtuaalserveritest.
Mida me mÔÔdame?
Saame mÔÔta erinevaid nÀitajaid. Hindame iga arhitektuuri jÔudlust antud konfiguratsioonis, koormates servereid erinevatel tasanditel: koormus tÔuseb 20-st kuni 15 000 samal ajal oleva kasutaja juurde.
Testide tulemused
JĂ€rgmisel diagrammil on kujutatud serverite jĂ”udlust erinevates arhitektuurides erinevatel paralleelsuse tasemetel. Y-telg nĂ€itab sekundis tehtavaid pĂ€ringute arvu, X-telg aga paralleelseid ĂŒhendusi.



Allpool on tabel tulemuste kohta.
pÀringut sekundis
paralleelsus
iteraatiivne
forki
eelnevalt forkitud
keeruline
eelnevalt keeruline
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
suure ulatusega
2138
5000
â
suure ulatusega
1600
1100
2519
â
2235
8000
â
â
1200
suure ulatusega
2451
â
2100
10Â 000
â
â
suure ulatusega
â
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 on nĂ€ha, et ĂŒle 8000 samaaegse pĂ€ringu juures jÀÀvad meil alles vaid kaks arhitektuuri: eelnevalt forkitud ja epoll. Koormuse tĂ”ustes töötab poll-iga server halvemini kui keeruline. Eelnevalt loodud keerud pakkuvad kvaliteetset konkurentsi epoll-le: see tĂ”estab, kui hĂ€sti Linuxi kernel suudab hallata suurt hulka keerukaid ĂŒlesandeid.
ZeroHTTPd allikakood
ZeroHTTPd allikakood . Iga arhitektuuri jaoks on eraldi kataloog.
ZeroHTTPd
â
âââ 01_iterative
â âââ main.c
âââ 02_forking
â âââ main.c
âââ 03_preforking
â âââ main.c
âââ 04_threading
â âââ main.c
âââ 05_prethreading
â âââ main.c
âââ 06_poll
â âââ main.c
âââ 07_epoll
â âââ main.c
âââ Makefile
âââ public
â âââ index.html
â âââ tux.png
âââ templates
âââ guestbook
âââ index.htmlLisaks seitsmele kaustale kĂ”igi arhitektuuride jaoks on ĂŒlemises kataloogis veel kaks: public ja templates. Esimeses asub fail index.html ja pilt esimesest ekraanipildist. Siia saab paigutada teisi faile ja kaustu ning ZeroHTTPd peab nende staatiliste failide edastamisega ilma probleemideta toime tulema. Kui brauseri tee vastab tee public kaustas, otsib ZeroHTTPd selle katalooge faili index.html. KĂŒlalisteraamatu sisu genereeritakse dĂŒnaamiliselt. Sellel on ainult peamine leht, mille sisu pĂ”hineb failil âtemplates/guestbook/index.htmlâ. ZeroHTTPd-s on lihtne lisada dĂŒnaamilisi lehti laiendamiseks. Idee on, et kasutajad saavad selles kataloogis lisada malle ja laiendada ZeroHTTPd-d vastavalt vajadusele.
Seitsme serveri ehitamiseks kĂ€ivitage make all ĂŒlemisest kataloogist â ja kĂ”ik versioonid ilmuvad selle katalooge. TĂ€itevfailid otsivad kaustu public ja templates selles kataloogis, kust need kĂ€ivitatakse.
Linux API
Selle artiklite tsĂŒkli teabe mĂ”istmiseks ei ole vajalik vĂ€ga hĂ€sti tunda Linux API-d. Soovitan siiski selle teema kohta rohkem lugeda, internetis on palju abimaterjale. Kuigi kĂ€sitleme mitmeid Linux API kategooriaid, keskendume peamiselt protsessidele, lĂ”imedele, sĂŒndmustele ja vĂ”rgu stack'ile. Lisaks Linux API raamatutele ja artiklitele soovitan tutvuda ka sĂŒsteemikĂ”nede ja kasutatavate teegifunktsioonide manuaalidega.
Toimivus ja skaleeritavus
Ăks tĂ€helepanek jĂ”udluse ja mastaapsuse kohta. Teoreetiliselt ei ole nende vahel mingit seost. Teil vĂ”ib olla veebiteenus, mis töötab vĂ€ga hĂ€sti, reageerimisaeg mĂ”ne millisekundi jooksul, kuid see ei ole ĂŒldse mastaapne. Samuti vĂ”ib olla halvasti töötav veebirakendus, mis vajab vastamiseks mitmeid sekundeid, kuid see mastaapub kĂŒmneteks, et jagada kĂŒmneid tuhandeid samal ajal kasutajaid. Siiski on kĂ”rge jĂ”udluse ja mastaapsuse kombinatsioon vĂ€ga vĂ”imas. KĂ”rge jĂ”udlusega rakendused kasutavad ĂŒldiselt ressursse sÀÀstlikult ja seega suudavad tĂ”husalt teenindada rohkem samal ajal olevaid kasutajaid serveris, vĂ€hendades kulusid.
CPU ja I/O ĂŒlesanded
LĂ”puks on arvutustes alati kaks vĂ”imalikku ĂŒlesannete tĂŒĂŒpi: I/O ja CPU. Interneti kaudu pĂ€ringute saamine (vĂ”rgu sisend-vĂ€ljund), failide haldamine (vĂ”rgu ja ketta sisend-vĂ€ljund), andmebaasiga suhtlemine (vĂ”rgu ja ketta sisend-vĂ€ljund) â kĂ”ik need on I/O toimingud. MĂ”ned andmebaasi pĂ€ringud vĂ”ivad veidi koormata CPU-d (sorteerimine, miljoni tulemuse keskmise arvutamine jne). Enamik veebirakendusi on piiratud maksimaalse vĂ”imaliku I/O-ga, protsessorit kasutatakse harva tĂ€ielikult. Kui nĂ€ete, et mingisuguses sisend-vĂ€ljundi ĂŒlesandes kasutatakse palju CPU-d, on see tĂ”enĂ€oliselt halva rakenduse arhitektuuri mĂ€rk. See vĂ”ib tĂ€hendada, et CPU ressursse kasutatakse protsesside haldamiseks ja konteksti vahetamiseks â ja see ei ole kuigi kasulik. Kui teete midagi, nagu piltide töötlemine, helifailide konverteerimine vĂ”i masinĂ”pe, siis vajab rakendus vĂ”imsaid CPU ressursse. Aga enamik rakendusi ei vaja seda.
Rohkem teavet serveri arhitektuuride kohta
Allikas: habr.com
