Aplikacionet web tani përdoren kudo, dhe ndër të gjithë protokollet e transportit, HTTP zë një pjesë të madhe. Duke studiuar nuancat e zhvillimit të aplikacioneve web, shumica e zhvilluesve i kushtojnë shumë pak vëmendje sistemit operativ ku këto aplikacione realisht ekzekutohen. Ndara e zhvillimit (Dev) dhe operacioneve (Ops) vetëm sa e përkeqësonte situatën. Por me përhapjen e kulturës DevOps, zhvilluesit fillojnë të marrin përgjegjësinë për ekzekutimin e aplikacioneve të tyre në cloud, prandaj është shumë e dobishme për ta të njohin në thellësi backend-in e sistemit operativ. Kjo është veçanërisht e dobishme nëse po përpiqeni të implementoni një sistem për mijëra apo dhjetëra mijëra lidhje simultane.
Kufizimet në shërbimet web janë shumë të ngjashme me kufizimet në aplikacione të tjera. Qoftë përballësit e ngarkesës apo serverët e DB, të gjitha këto aplikacione kanë probleme të ngjashme në një ambient me performancë të lartë. Kuptimi i këtyre kufizimeve themelore dhe mënyrave për t'i tejkaluar ato në përgjithësi do t'ju ndihmojë të vlerësoni performancën dhe shkallëzueshmërinë e aplikacioneve tuaja web.
Po shkrimin e kĂ«saj serie artikujsh nĂ« pĂ«rgjigje tĂ« pyetjeve tĂ« zhvilluesve tĂ« rinj qĂ« dĂ«shirojnĂ« tĂ« bĂ«hen arkitektĂ« sistemesh tĂ« informuar mirĂ«. ĂshtĂ« e pamundur tĂ« kuptohet qartĂ« metodat e optimizimit tĂ« aplikacioneve Linux, pa e pĂ«rmbushur thelbin se si ato funksionojnĂ« nĂ« nivelin e sistemit operativ. MegjithĂ«se ka shumĂ« lloje aplikacionesh, nĂ« kĂ«tĂ« cikĂ«l dĂ«shiroj tĂ« studioj aplikacione rrjetesh, e jo ato desktop, si shfletuesit apo redaktuesit e tekstit. Ky material Ă«shtĂ« i dedikuar pĂ«r zhvilluesit dhe arkitektĂ«t qĂ« duan tĂ« kuptojnĂ« se si funksionojnĂ« programet Linux ose Unix dhe si t'i strukturojnĂ« ato pĂ«r performancĂ« tĂ« lartĂ«.
Linux është sistemi operacional , dhe shpesh herë aplikacionet tuaja punojnë pikërisht në këtë OS. Edhe pse po flas për "Linux", shumicën e kohës mund të supozoni me besim se po i referohem të gjitha sistemet operacionale të ngjashme me Unix në përgjithësi. Megjithatë, unë nuk e kam testuar kodin shoqërues në sisteme të tjera. Pra, nëse jeni të interesuar për FreeBSD ose OpenBSD, rezultatet mund të ndryshojnë. Kur të provoj diçka specifike për Linux, e theksoj këtë.
Edhe pse mund të përdorni njohuritë e fituara për të krijuar një aplikacion nga fillimi dhe ai do të jetë optimalisht i optimizuar, është më mirë të mos e bëni këtë. Nëse shkruani një server të ri web në C ose C++ për aplikacionin e biznesit të organizatës suaj, ndoshta do të jetë dita juaj e fundit në punë. Megjithatë, njohja e strukturës së këtyre aplikacioneve do t'ju ndihmojë në zgjedhjen e programeve ekzistuese. Do të jeni në gjendje të krahasoni sisteme bazuar në procese me sisteme bazuar në rrjedha, si dhe me ato bazuar në ngjarje. Do ta kuptoni dhe vlerësoni pse Nginx funksionon më mirë se Apache httpd, pse aplikacioni Python i bazuar në Tornado mund të shërbejë më shumë përdorues krahasuar me aplikacionin Python të bazuar në Django.
ZeroHTTPd: mjeti i mësimit
 â server web qĂ« e kam shkruar nga zero nĂ« C si mjet mĂ«simi. Ai nuk ka varĂ«si tĂ« jashtme, duke pĂ«rfshirĂ« aksesin nĂ« Redis. Ne drejtojmĂ« procedurat tona tĂ« Redis. MĂ« shumĂ« informacion mĂ« poshtĂ«.
Megjithëse mund të diskutojmë gjatë mbi teorinë, nuk ka gjë më të mirë se të shkruash kod, ta ekzekutosh dhe të krahasosh të gjitha arkitekturët e serverëve. Ky është metoda më e qartë. Prandaj, do të shkruajmë një server web të thjeshtë ZeroHTTPd, duke aplikuar çdo model: bazuar në procese, thread-e dhe ngjarje. Do të kontrollojmë secilin prej këtyre serverëve dhe do të shohim se si funksionojnë në krahasim me njëri-tjetrin. ZeroHTTPd është implementuar në një skedar C. Serveri i bazuar në ngjarje përmban , një realizim të shkëlqyer të tabelës hash, e cila ofrohet në një skedar titulli. Në raste të tjera, nuk ka asnjë varësi për të mos e komplikuar projektin.
Kodi përmban shumë komentare për të ndihmuar në kuptim. Duke qenë një server i thjeshtë web me disa rreshta kodi, ZeroHTTPd gjithashtu paraqet një kornizë minimale për zhvillimin e uebit. Ai ka funksionalitet të kufizuar, por është në gjendje të dorëzojë skedarë statikë dhe faqe "dinamike" shumë të thjeshta. Duhet të them se ZeroHTTPd është shumë i përshtatshëm për të mësuar si të krijoni aplikacione Linux me performancë të lartë. Në thelb, shumica e shërbimeve web presin kërkesa, i kontrollojnë ato dhe i përpunojnë. Kështu do të veprojë ZeroHTTPd. Ky është një mjet mësimor, jo për prodhim. Ai nuk është i fortë në përpunimin e gabimeve dhe me siguri nuk do të mburret me praktikat më të mira të sigurisë (o, po, e kam përdorur strcpy) ose me truket e sofistikuara të gjuhës C. Por shpresoj se ai do ta kryejë mirë detyrën e tij.

Faqja kryesore e ZeroHTTPd. Ai mund të dorëzojë lloje të ndryshme skedarësh, duke përfshirë imazhe
Aplikacioni i librit të vizitorëve
Aplikacionet moderne web zakonisht nuk kufizohen në skedarë statik. Ato kanë ndërveprime komplekse me bazat e të dhënave të ndryshme, cache-et etj. Prandaj, ne do të krijojmë një aplikacion të thjeshtë web me emrin "Libri i Vizitorëve", ku vizitorët lënë shënime nën emrat e tyre. Në librin e vizitorëve ruhen shënimet e lëna më parë. Ka gjithashtu një numërues vizitorësh në fund të faqes.

Aplikacioni web "Libri i Vizitorëve" ZeroHTTPd
Numri i vizitorëve dhe regjistrimi i librit të mysafirëve ruhen në Redis. Për komunikimet me Redis, janë implementuar procedura të veçanta, të cilat nuk varen nga ndonjë bibliotekë të jashtme. Nuk jam një adhurues i madh i hedhjes së kodit të bërë vetë në prodhim, kur ka zgjidhje të publikuara dhe të testuara mirë. Por qëllimi i ZeroHTTPd është të studiojë performancën e Linux-it dhe qasjen në shërbime të jashtme, ndërsa trajtimi i kërkesave HTTP ndikon ndjeshëm në performancë. Ne duhet të kemi kontroll të plotë mbi komunikimet me Redis në secilën nga arkitekturën tona serverike. Në një arkitekturë, ne përdorim thirrje bllokuese, në të tjerat - procedura të bazuara në ngjarje. Përdorimi i një biblioteke klienti të jashtëm për Redis nuk do të ofrojë një kontroll të tillë. Për më tepër, klienti ynë i vogël për Redis kryen vetëm disa funksione (marrja, konfigurimi dhe rritja e çelësit; marrja dhe shtimi në një masë). Po ashtu, protokolli i Redis është jashtëzakonisht elegant dhe i thjeshtë. Nuk ka nevojë madje të mësohet posaçërisht. Fakti që i gjithë puna e protokollit realizohet në rreth njëqind rreshta kodi tregon për sa mirë është menduar.
Në figurën e mëposhtme janë treguar veprimet e aplikacionit, kur klienti (shfletuesi) bën një kërkesë /guestbookURL.

Mekanizmi i funksionimit të aplikacionit të librit të vizitorëve
Kur duhet të dorëzohet një faqe e librit të vizitorëve, ndodh një thirrje në sistemin e skedarëve për të lexuar përshkrimin në memorie dhe tri thirrje rrjeti në Redis. Skedari i përshkrimit përmban pjesën më të madhe të përmbajtjes HTML për faqen në skenën e mësipërme. Aty ka gjithashtu vendmbushës të veçantë për pjesën dinamike të përmbajtjes: shënimet dhe numëruesin e vizitorëve. Ne i marrim ato nga Redis, i vendosim në faqe dhe i dorëzojmë klientit përmbajtjen e formuar plotësisht. Thirrja e tretë në Redis mund të shmanget, pasi Redis kthen një vlerë të re të çelësit kur rritet. Megjithatë, për serverin tonë me një arkitekturë të asinkronizuar të bazuar në ngjarje, shumë thirrje rrjeti janë një provë e mirë për qëllime mësimore. Kështu, ne e heqim vlerën e kthyer nga Redis për numrin e vizitorëve dhe e kërkojmë atë me një thirrje të veçantë.
Arkitekturat serverike ZeroHTTPd
Ne ndërtojmë shtatë versione të ZeroHTTPd me funksionalitete të njëjta, por me arkitektura të ndryshme:
- Iterative
- Server fork (një proces dytësor për kërkesë)
- Serveri pre-fork (parashikimi i proceseve)
- Serveri me rrjedha ekzekutimi (një thread për kërkesë)
- Serveri me krijim paraprak të rrjedhave
- Arkitektura e bazuar në
poll() - Arkitektura e bazuar në
epoll
Kemi matur performancën e secilës arkitekturë duke ngarkuar serverin me kërkesa HTTP. Por që kur krahasojmë arkitektura me një shkallë të lartë paralelizmi, numri i kërkesave rritet. E testojmë tri herë dhe llogarisim mesataren.
Metodologjia e testimit

Instalimi për testim ngarkese ZeroHTTPd
ĂshtĂ« e rĂ«ndĂ«sishme qĂ« gjatĂ« realizimit tĂ« testeve, tĂ« gjitha komponentĂ«t tĂ« mos funksionojnĂ« nĂ« tĂ« njĂ«jtĂ«n makinĂ«. NĂ« kĂ«tĂ« rast, OS ka shpenzime shtesĂ« pĂ«r planifikimin, pasi komponentĂ«t garojnĂ« pĂ«r CPU. Matja e ngarkesave tĂ« sistemit operativ me secilĂ«n nga arkitekturat serverike tĂ« zgjedhura Ă«shtĂ« njĂ« nga qĂ«llimet mĂ« tĂ« rĂ«ndĂ«sishme tĂ« kĂ«tij ushtrimi. Shtimi i mĂ« shumĂ« variablave do tĂ« ishte dĂ«mtues pĂ«r procesin. Prandaj, konfigurimi nĂ« figurĂ«n e mĂ«sipĂ«rme funksionon mĂ« mirĂ«.
ĂfarĂ« bĂ«n secili nga kĂ«ta servera
- load.unixism.net: këtu ne e lançojmë
ab, utilitarin Apache Benchmark. Ajo krijon ngarkesën e nevojshme për testimin e arkitekturave tona serverike. - nginx.unixism.net: ndonjëherë duam të drejtojmë më shumë se një ekzemplar të programit server. Për këtë, serveri Nginx me cilësimet përkatëse punon si një balancues ngarkese, që vjen nga ab proceset tona serverike.
- zerohttpd.unixism.net: këtu ne drejtojmë programet tona serverike në shtatë arkitektura të ndryshme, nga njëra në tjetrën.
- redis.unixism.net: në këtë server punon një demon Redis, ku ruhen regjistrimet në libër vizitash dhe numri i vizitorëve.
Të gjitha serverët punojnë në një bërthamë procesori. Ideja është të vlerësojmë performancën maksimale të çdo arkitekture. Duke qenë se të gjitha programet serverike testohet në një pajisje të vetme, ky është niveli bazë për krahasimin e tyre. Instalimi im i testimit përbëhet nga serverë virtualë të marrë me qira nga Digital Ocean.
ĂfarĂ« matim?
Mund të maten tregues të ndryshëm. Ne vlerësojmë performancën e çdo arkitekture në këtë konfigurim duke ngarkuar serverët me kërkesa në nivele të ndryshme të paralelizmës: ngarkesa rritet nga 20 në 15,000 përdorues paralel.
Rezultatet e testeve
NĂ« diagramin e mĂ«poshtĂ«m tregohet performanca e serverĂ«ve me arkitekturĂ« tĂ« ndryshme nĂ« nivele tĂ« ndryshme paralelismi. NĂ« boshtin y â numri i kĂ«rkesave pĂ«r sekondĂ«, nĂ« boshtin x â lidhjet paralel.



Më poshtë është tabela me rezultatet.
kërkesa për sekondë
paralelism
iterativ
fork
pre-fork
ndërthurrës
pre-tëndës
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
shkallëzim të madh
2138
5000
â
shkallëzim të madh
1600
1100
2519
â
2235
8000
â
â
1200
shkallëzim të madh
2451
â
2100
10Â 000
â
â
shkallëzim të madh
â
2200
â
2200
11Â 000
â
â
â
â
2200
â
2122
12Â 000
â
â
â
â
970
â
1958
13Â 000
â
â
â
â
730
â
1897
14Â 000
â
â
â
â
590
â
1466
15Â 000
â
â
â
â
532
â
1281
Nga grafiku dhe tabela shihet se mbi 8000 kërkesa të njëkohshme na mbeten vetëm dy lojtarë: pre-fork dhe epoll. Ndërsa ngarkohet, serveri në bazë të poll punon më keq se ndërruesi. Arkitektura me krijim të paraprak të ndërruesve ofron një konkurrencë të denjë ndaj epoll: kjo është një dëshmi se sa mirë bërthama Linux planifikon një numër të madh të ndërruesve.
Kodi origjinal ZeroHTTPd
Kodi origjinal ZeroHTTPd . Ădo arkitekturĂ« ka njĂ« katalog tĂ« veçantĂ«.
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.htmlPĂ«rveç shtatĂ« direktorive pĂ«r tĂ« gjitha arkitekturat, nĂ« katalogun e nivelit tĂ« lartĂ« ka edhe dy tĂ« tjera: public dhe templates. NĂ« tĂ« parin ndodhet skedari index.html dhe imazhi nga screenshoti i parĂ«. Aty mund tĂ« vendosen skedarĂ« dhe dosje tĂ« tjera, dhe ZeroHTTPd duhet t'i ofrojĂ« kĂ«to skedarĂ« statikĂ« pa asnjĂ« problem. NĂ«se rruga nĂ« shfletues pĂ«rputhet me rrugĂ«n nĂ« dosjen public, atĂ«herĂ« ZeroHTTPd kĂ«rkon skedarin index.html nĂ« kĂ«tĂ« katalog. PĂ«rmbajtja pĂ«r librin e mysafirĂ«ve gjenerohet dinamikisht. Ai ka vetĂ«m njĂ« faqe kryesore, e cila bazohet nĂ« skedarin âtemplates/guestbook/index.htmlâ. ZeroHTTPd lehtĂ«son shtimin e faqeve dinamike pĂ«r zgjerim. Ideja Ă«shtĂ« qĂ« pĂ«rdoruesit mund tĂ« shtojnĂ« nĂ« kĂ«tĂ« katalog shabllone dhe tĂ« zgjerohen ZeroHTTPd sipas nevojĂ«s.
Për të ndërtuar të shtatë serverët, aktivizoni make all nga katalogu kryesor - dhe të gjitha ndërtimet do të shfaqen në këtë katalog. Skedarët ekzekutivë kërkojnë katalogët public dhe templates në katalogun nga ku ato aktivizohen.
Linux API
Për të kuptuar informacionin në këtë cikël artikujsh, nuk është e nevojshme të keni njohuri të thella në Linux API. Megjithatë, rekomandoj të lexoni më shumë rreth kësaj teme, pasi ka shumë burime referuese në internet. Edhe pse ne do të prekim disa kategori të Linux API, vëmendja jonë do të fokusohet kryesisht në procese, rrjedha, ngjarje dhe stek rrjeti. Përveç librave dhe artikujve mbi Linux API, rekomandoj gjithashtu të lexoni man-in për thirrjet sistemore dhe funksionet e përdorura në biblioteka.
Performanca dhe shkallëzueshmëria
Një vërejtje në lidhje me performancën dhe shkallëzueshmërinë. Teorikisht, nuk ka asnjë lidhje mes tyre. Mund të keni një shërbim web-i që punon shumë mirë, me një kohë përgjigjeje disa milisekonda, por që nuk shkallëzohet fare. Po ashtu, mund të ketë një aplikacion web që punon keq, që kërkon disa sekonda për të përgjigjur, por që shkallëzohet për të trajtuar dhjetëra mijëra përdorues në të njëjtën kohë. Megjithatë, kombinimi i performancës së lartë dhe shkallëzueshmërisë është një kombinim shumë i fuqishëm. Aplikacionet me performancë të lartë në përgjithësi përdorin në mënyrë efikase burimet dhe, kështu, shërbejnë më shumë përdorues në të njëjtën kohë në server, duke reduktuar kostot.
Detyrat CPU dhe I/O
NĂ« computing, gjithmonĂ« ka dy lloje tĂ« mundshme tĂ« detyrave: pĂ«r I/O dhe CPU. Marrja e kĂ«rkesave pĂ«rmes internetit (I/O rrjeti), administrimi i skedarĂ«ve (I/O rrjeti dhe disku), komunikimi me bazĂ«n e tĂ« dhĂ«nave (I/O rrjeti dhe disku) â tĂ« gjitha kĂ«to janĂ« aktivitete I/O. Disa kĂ«rkesa ndaj BDs mund tĂ« ngarkojnĂ« pak CPU-nĂ« (renditja, llogaritja e mesatares sĂ« njĂ« milioni rezultateve etj.). Shumica e aplikacioneve web janĂ« tĂ« kufizuara nĂ« I/O-nin maksimal tĂ« mundshĂ«m, ndĂ«rsa procesori pĂ«rdoret rrallĂ« nĂ« kapacitetin e tij tĂ« plotĂ«. Kur sheh qĂ« njĂ« detyrĂ« I/O po pĂ«rdor shumĂ« CPU, kjo ka tĂ« ngjarĂ« tĂ« jetĂ« njĂ« shenjĂ« e njĂ« arkitekture aplikacioni tĂ« keqe. Kjo mund tĂ« nĂ«nkuptojĂ« se burimet e CPU-sĂ« po shpenzohen pĂ«r menaxhimin e proceseve dhe pĂ«r kalimin e kontekstit â dhe kjo nuk Ă«shtĂ« shumĂ« e dobishme. NĂ«se jeni duke bĂ«rĂ« diçka si pĂ«rpunimi i imazheve, konvertimi i skedarĂ«ve audio apo mĂ«simi automatik, atĂ«herĂ« aplikacioni kĂ«rkon burime tĂ« fuqishme CPU-je. Por pĂ«r shumicĂ«n e aplikacioneve, nuk Ă«shtĂ« kĂ«shtu.
Më shumë detaje mbi arkitekturat e serverëve
Burimi: habr.com
