Aplikacionet web tani përdoren kudo, dhe mes të gjithë protokollave të transportit, HTTP zë një pjesë të madhe. Kur studiojnë nuancat e zhvillimit të aplikacioneve web, shumica i jep shumë pak vëmendje sistemit operativ ku këto aplikacione realisht funksionojnë. Ndarja e zhvillimit (Dev) dhe operacioneve (Ops) vetëm sa ka përkeqësuar situatën. Por me përhapjen e kulturës DevOps, zhvilluesit filluan të marrin përgjegjësinë për funksionimin e aplikacioneve të tyre në cloud, prandaj është shumë e dobishme për ta të njohin në thellësi bllokun e sistemit operativ. Kjo është veçanërisht e dobishme nëse po përpiqeni të vendosni një sistem për mijëra ose dhjetëra mijëra lidhje të njëkohshme.
Kufizimet në shërbimet web janë shumë të ngjashme me kufizimet në aplikacione të tjera. Qoftë për balancuesit e ngarkesës ose serverët e DB, të gjithë këto aplikacione kanë probleme të ngjashme në një mjedis me performancë të lartë. Kuptimi i këtyre kufizimeve themelore dhe mënyrave të kapërcimit të tyre në përgjithësi do të lejojë vlerësimin e performancës dhe shkallëzueshmërisë së aplikacioneve tuaja web.
Po shkruaj kĂ«tĂ« seri artikujsh si pĂ«rgjigje ndaj pyetjeve tĂ« zhvilluesve tĂ« rinj qĂ« dĂ«shirojnĂ« tĂ« bĂ«hen arkitektĂ« sistemesh tĂ« informuar mirĂ«. Nuk Ă«shtĂ« e mundur tĂ« kuptohet qartĂ« metodat e optimizimit tĂ« aplikacioneve Linux pa u zhytur nĂ« bazat, sesi ato funksionojnĂ« nĂ« nivelin e sistemit operativ. Edhe pse ka shumĂ« lloje aplikacionesh, nĂ« kĂ«tĂ« cikĂ«l dua tĂ« shqyrtoj aplikacione rrjetesh, dhe jo desktop, siç janĂ« shfletuesit ose redaktorĂ«t e teksteve. Ky material Ă«shtĂ« 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 operativ server, dhe më së shpeshti aplikacionet tuaja punojnë pikërisht në këtë OS. Edhe pse po flas për 'Linux', gjatë shumicës së kohës mund të supozoni me besim se po kemi parasysh të gjitha sistemet operativë të ngjashme me Unix në përgjithësi. Megjithatë, unë nuk e kam testuar kodin shoqërues në sisteme të tjera. Prandaj, nëse jeni të interesuar për FreeBSD ose OpenBSD, rezultati mund të jetë ndryshe. Kur provoj diçka specifike për Linux, unë e shpjegoj atë.
Megjithëse mund të përdorni njohuritë e marra për të krijuar një aplikacion nga fillimi dhe ai do të jetë i optimizuar mjaft mirë, më mirë është 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 strukturave të këtyre aplikacioneve do t'ju ndihmojë në zgjedhjen e programeve që tashmë ekzistojnë. Do të jeni në gjendje të krahasoni sistemi të bazuar në procese me sistemet të bazuara në gjendje dhe gjithashtu me ato të bazuara në ngjarje. Do të kuptoni dhe vlerësoni pse Nginx funksionon më mirë se Apache httpd dhe pse një aplikacion Python i bazuar në Tornado mund të shërbejë më shumë përdorues se një aplikacion Python i bazuar në Django.
ZeroHTTPd: mjet për mësim
 â njĂ« server web qĂ« e shkrova nga fillimi nĂ« C si njĂ« mjet mĂ«simi. Nuk ka varĂ«si tĂ« jashtme, pĂ«rfshirĂ« qasje nĂ« Redis. Ne ekzekutojmĂ« procedurat tona tĂ« Redis. MĂ« shumĂ« informacion mĂ« poshtĂ«.
Megjithëse mund të flasim gjatë për teorinë, nuk ka asgjë më të mirë se të shkruash kod, ta ekzekutosh dhe të krahasosh të gjitha arkitekturën e serverëve. Ky është metoda më vizuale. Prandaj, do të shkruajmë një server të thjeshtë web ZeroHTTPd, duke aplikuar çdo model: të bazuar në procese, janë dhe ngjarje. Do të verifikojmë secilin nga këta serverë dhe do të shohim se si punojnë në krahasim me njëri-tjetrin. ZeroHTTPd është i realizuar në një skedë të vetme C. Në përbërje të serverit të bazuar në ngjarje përfshihet , një implementim i shkëlqyer i tabelës hash e cila ofrohet në një skedë header. Në rastet e tjera, nuk ka varësi që e komplikon projektin.
Në kod ka shumë komente për të ndihmuar në kuptimin. Duke qenë një server web i thjeshtë në disa linja kodi, ZeroHTTPd gjithashtu paraqet një kornizë minimale për zhvillimin e web. Ka funksionalitet të kufizuar, por është në gjendje të shërbejë skedarë statikë dhe faqe "dinamike" shumë të thjeshta. Duhet të them se ZeroHTTPd është shumë i përshtatshëm për të mësuar se si të krijoni aplikacione me performancë të lartë në Linux. Në thelb, shumica e shërbimeve web presin kërkesat, i verifikojnë ato dhe i përpunojnë. Kjo është ajo që do të bëjë ZeroHTTPd. Ky është një instrument për mësim, jo për prodhim. Ai nuk është i fortë në trajtimin e gabimeve dhe është e vështirë të mburret me praktikat më të mira të sigurisë (o, po, e kam përdorur strcpy) ose për truqet e gjuhës C. Por, shpresoj se do të përmbushë detyrën e tij mirë.

Faqja kryesore e ZeroHTTPd. Ai mund të shërbejë lloje të ndryshme skedarësh, duke përfshirë imazhe.
Aplikacioni i librit të vizitorëve
Aplikacionet moderne në internet zakonisht nuk kufizohen vetëm në skedarë statikë. Ato kanë ndërveprime të ndërlikuara me baza të ndryshme të të dhënave, cache, etj. Prandaj, ne do të krijojmë një aplikacion të thjeshtë në internet të quajtur 'Libri i Vizitorëve', ku vizitorët mund të lënë shënime me emrat e tyre. Në librin e vizitorëve ruhen shënime të lëna më parë. Ka gjithashtu një numëruar të vizitorëve në fund të faqes.

Aplikacioni në internet 'Libri i Vizitorëve' ZeroHTTPd
Numëruari i vizitorëve dhe shënimet e librit të vizitorëve ruhen në Redis. Për komunikimet me Redis janë realizuar procedura të veta, të cilat nuk varen nga biblioteka të jashtme. Unë nuk jam një fan i madh i krijimit të kodit të veçantë kur ka zgjidhje të mira dhe të testuara në mënyrë publike. Por qëllimi i ZeroHTTPd është të studiojë performancën e Linux-it dhe qasjen në shërbime të jashtme, ndërsa shërbimi i kërkesave HTTP ndikon ndjeshëm në performancë. Ne duhet të kontrollojmë plotësisht komunikimet me Redis në secilën nga arkitekturën tona serverike. Në një arkitekturë ne përdorim thirrje bllokuese, në të tjerat procedura me bazë ngjarjesh. Përdorimi i një biblioteke klienti të jashtëm për Redis nuk do të ofrojë një të tillë kontroll. Për më tepër, klienti ynë i vogël Redis kryen vetëm disa funksione (marrja, konfigurimi dhe rritja e çelësit; marrja dhe shtimi në një array). Për më tepër, protokolli Redis është jashtëzakonisht elegant dhe i thjeshtë. Nuk ka nevojë të mësohet posaçërisht. Fakti vetë se i gjithë punimi i protokollit kryhet me rreth njëqind rreshta kodi tregon se sa mirë është menduar.
Në figurën e ardhshme tregohen veprimet e aplikacionit kur klienti (shfletuesi) bën një kërkesë /guestbookURL.

Mekanizmi i funksionimit të aplikacionit të librit të vizitorëve
Kur ndodhet nevoja për të ofruar faqen e librit të mysafirëve, ndodh një thirrje për sistemin e skedarëve për të lexuar skedarin në memorie dhe tri thirrje rrjeti në Redis. Skedari i modelit përmban shumicën e përmbajtjes HTML për faqen në screenshotin lart. Ka gjithashtu mbushës të veçantë për pjesën dinamike të përmbajtjes: regjistrime dhe numërues vizitorësh. Ne i marrim ato nga Redis, i vendosim në faqe dhe ia ofrojmë klientit përmbajtjen e plotë të formuar. Thirrjen e tretë në Redis mund ta evitoni, pasi Redis ktheu një vlerë të re të çelësit kur rritet. Megjithatë, për serverin tonë me arkitekturë asinkrone të bazuar në ngjarje, një sasi e madhe thirrjesh rrjeti është një provë e mirë për qëllime mësimore. Kështu, ne e hedhim vlerën e kthyere nga Redis për numrin e vizitorëve dhe e kërkojmë atë në një thirrje të veçantë.
Arkitekturat Serveri ZeroHTTPd
Ne ndërtojmë shtatë versione të ZeroHTTPd me funksionalitet të njëjtë, por me arkitektura të ndryshme:
- Iterative
- Server Fork (një proces i vogël për thirrje)
- Server Pre-fork (forkim i përparshëm i proceseve)
- Server me fije ekzekutimi (një fije për thirrje)
- Server me krijim të përparshëm të fijeve
- Arkitektura e bazuar në
poll() - Arkitektura e bazuar në
epoll
Ne masim performancën e çdo arkitekture duke ngarkuar serverin me kërkesa HTTP. Por gjatë krahasimit të arkitekturave me një shkallë të lartë paralelizmi, numri i kërkesave rritet. Ne testojmë tri herë dhe llogarisim mesataren.
Metodologjia e testimit

Konfigurimi për testimin e ngarkesës ZeroHTTPd
ĂshtĂ« e rĂ«ndĂ«sishme qĂ« gjatĂ« ekzekutimit tĂ« testeve, tĂ« gjithĂ« komponentĂ«t tĂ« mos punojnĂ« nĂ« njĂ« makinĂ« tĂ« vetme. NĂ« kĂ«tĂ« rast, sistemi operativ ka ngarkesa shtesĂ« pĂ«r planifikimin, pasi komponentĂ«t garojnĂ« pĂ«r CPU. Matja e ngarkesave tĂ« sistemit operativ me secilĂ«n nga arkitekturat e zgjedhura tĂ« serverĂ«ve Ă«shtĂ« njĂ« nga qĂ«llimet mĂ« tĂ« rĂ«ndĂ«sishme tĂ« kĂ«saj ushtrimi. Shtimi i mĂ« shumĂ« variablave do tĂ« jetĂ« fatkeqĂ«si pĂ«r procesin. Prandaj, konfigurimi nĂ« figurĂ«n e mĂ«sipĂ«rme funksionon mĂ« mirĂ«.
ĂfarĂ« bĂ«n secili prej kĂ«tyre serverĂ«ve
- load.unixism.net: këtu ne ekzekutojmë
ab, utilitarin Apache Benchmark. Ai gjeneron ngarkesën e nevojshme për testimin e arkitekturave tona të serverëve. - nginx.unixism.net: ndonjëherë ne duam të ekzekutojmë më shumë se një instancë të programit server. Për këtë, serveri Nginx me cilësimet e duhura funksionon si një balancues ngarkese për kërkesat që vijnë nga ab proceset tona serverike.
- zerohttpd.unixism.net: këtu ne ekzekutojmë programet tona serverike në shtatë arkitektura të ndryshme, një për një.
- redis.unixism.net: në këtë server punon demon i Redis, ku ruhen të dhënat në librin e vizitorëve dhe numri i vizitorëve.
Të gjithë serverët punojnë në një bërthamë procesori. Ideja është të vlerësojmë performancën maksimale të secilës nga arkitekturat. Duke qenë se të gjitha programet serverike testohet në një pajisje, kjo është baza e krahasimit të tyre. Instala ime e testimit përbëhet nga servera virtualë, të marrë me qira nga Digital Ocean.
ĂfarĂ« po masim?
Mund të matim tregues të ndryshëm. Ne vlerësojmë performancën e secilës arkitekturë në këtë konfigurim duke ngarkuar serverët me kërkesa në nivele të ndryshme paralelisme: ngarkesa rritet nga 20 në 15,000 përdorues të njëkohshëm.
Rezultatet e testeve
NĂ« diagramin e ardhshĂ«m tregohet performanca e serverĂ«ve nĂ« arkitekturĂ« tĂ« ndryshme nĂ« nivele tĂ« ndryshme paralelisme. NĂ« boshtin y â numri i kĂ«rkesave pĂ«r sekondĂ«, nĂ« boshtin x â lidhjet paralel.



Më poshtë është një tabelë me rezultatet.
kërkesa për sekondë
paralelizmi
iterativ
fork
prefork
threading
pre-threading
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
shpërndarje e madhe
2138
5000
â
shpërndarje e madhe
1600
1100
2519
â
2235
8000
â
â
1200
shpërndarje e madhe
2451
â
2100
10Â 000
â
â
shpërndarje e madhe
â
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 tabelat duket se mbi 8000 kërkesa përkohshëm ne kemi vetëm dy lojtarë: prefork dhe epoll. Me rritjen e ngarkesës, serveri në bazë të poll punon më dobët se threading. Arkitektura me krijim të përparuar të thread-ve ofron një konkurrencë të dinjitetshme për epoll: kjo dëshmon se sa mirë bërthama Linux planifikon një numër të madh thread-esh.
Kodi burimor ZeroHTTPd
Kodi burimor ZeroHTTPd . Për çdo arkitekturë janë të veçanta katalog.
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Ă« drejtorive pĂ«r tĂ« gjitha arkitekturat, nĂ« katalogun kryesor ka edhe dy tĂ« tjera: public dhe templates. NĂ« tĂ« parin ndodhet skedari index.html dhe njĂ« imazh nga capture i parĂ«. Atje mund tĂ« vendosni skedarĂ« dhe dosje tĂ« tjera, dhe ZeroHTTPd duhet tĂ« japĂ« kĂ«to skedarĂ« statikĂ« pa probleme. 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 vizitorĂ«ve gjenerohet nĂ« mĂ«nyrĂ« dinamike. Ka vetĂ«m njĂ« faqe kryesore, dhe pĂ«rmbajtja e saj bazohet nĂ« skedarin âtemplates/guestbook/index.htmlâ. NĂ« ZeroHTTPd Ă«shtĂ« e lehtĂ« tĂ« shtoni faqe dinamike pĂ«r zgjerim. Ideja Ă«shtĂ« qĂ« pĂ«rdoruesit mund tĂ« shtojnĂ« nĂ« kĂ«tĂ« katalog shabllonĂ«t dhe tĂ« zgjedhin ZeroHTTPd sipas nevojĂ«s.
PĂ«r tĂ« ndĂ«rtuar tĂ« shtatĂ« serverĂ«t, startoni make all nga katalogu kryesor â dhe tĂ« gjitha ndĂ«rtimet do tĂ« shfaqen nĂ« kĂ«tĂ« katalog. SkedarĂ«t ekzekutiv kĂ«rkojnĂ« kataloget public dhe templates nĂ« katalogun nga i cili startohen.
API i Linux
Për të kuptuar informacionin në këtë cikël artikujsh, nuk është e nevojshme të keni njohuri të thella për API-në e Linux. Megjithatë, rekomandoj të lexoni më shumë mbi këtë temë, ka shumë burime referuese në internet. Megjithëse do të trajtojmë disa kategori të API-së së Linux, vëmendja jonë do të përqendrohet kryesisht në procese, kënaqësi, ngjarje dhe stek të rrjetit. Përveç librave dhe artikujve mbi API-në e Linux, rekomandoj gjithashtu të lexoni manualet për thirrjet sistemore dhe funksionet e bibliotecave që përdoren.
Performanca dhe shkallëzueshmëria
Një vërejtje për performancën dhe shkallëzueshmërinë. Teoretikisht nuk ka asnjë lidhje midis tyre. Mund të keni një shërbim web që funksionon shumë mirë, me një kohë përgjigjeje disa milisekonda, por nuk shkallëzohet fare. Në të njëjtën mënyrë, mund të ketë një aplikacion web që funksionon keq, që kërkon disa sekonda për të përgjigjur, por shkallëzohet në dhjetëra për të trajtuar dhjetëra mijëra përdorues të njëkohshëm. 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 burimet në mënyrë efikase dhe, kështu, shërbejnë në mënyrë efektive më shumë përdorues të njëkohshëm në server, duke ulur kostot.
Detyrat CPU dhe I/O
Në fund, në llogaritje ka gjithmonë dy lloje të mundshme të detyrave: për I/O dhe CPU. Marrja e kërkesave përmes internetit (input/output rrjeti), menaxhimi i skedarëve (input/output rrjeti dhe disk), komunikimi me bazën e të dhënave (input/output rrjeti dhe disk) - të gjitha këto janë aktivitete I/O. Disa kërkesa ndaj DB mund të ngarkojnë pak CPU-në (renditja, llogaritja e mesatares të një milioni rezultateve etj.). Shumica e aplikacioneve web janë të kufizuara në I/O-në e mundshme maksimale, ndërsa procesori rrallë përdoret në kapacitetin e tij të plotë. Kur shihni se një detyrë e caktuar e input/output përdor shumë CPU, për shumicën e rasteve, kjo është një shenjë e një arkitekture më të keqe të aplikacionit. Kjo mund të nënkuptojë se burimet e CPU-së po shpenzohen për menaxhimin e proceseve dhe ndërrimin e kontekstit - dhe kjo nuk është plotësisht e dobishme. Nëse bëni diçka si përpunimi i imazheve, konvertimi i skedarëve audio ose të mësuarit e makinës, atëherë aplikacioni kërkon burime të fuqishme CPU. Por për shumicën e aplikacioneve, kjo nuk është e vërtetë.
Më shumë detaje mbi arkitekturën e serverëve
Burimi: habr.com
