Webapplikaasjes wurde no oeral brûkt, en ûnder alle transportprotokollen nimt HTTP it liuw syn oandiel yn. By it bestudearjen fan 'e nuânses fan ûntwikkeling fan webapplikaasjes jouwe de measte minsken heul lyts omtinken oan it bestjoeringssysteem wêr't dizze applikaasjes eins rinne. De skieding fan ûntwikkeling (Dev) en operaasjes (Ops) makke de situaasje allinich slimmer. Mar mei de opkomst fan DevOps-kultuer wurde ûntwikkelders ferantwurdlik foar it útfieren fan har applikaasjes yn 'e wolk, dus it is heul nuttich foar har om goed fertroud te wurden mei de efterkant fan it bestjoeringssysteem. Dit is benammen nuttich as jo besykje in systeem yn te setten foar tûzenen of tsientûzenen simultane ferbiningen.
De beheiningen yn webtsjinsten binne heul gelyk oan dy yn oare applikaasjes. Oft it no load balancers of databaseservers binne, al dizze applikaasjes hawwe ferlykbere problemen yn in omjouwing mei hege prestaasjes. Begryp fan dizze fûnemintele beheiningen en hoe't jo se yn 't algemien kinne oerwinnen sil jo helpe om de prestaasjes en skalberens fan jo webapplikaasjes te evaluearjen.
Ik skriuw dizze searje artikels yn antwurd op fragen fan jonge ûntwikkelders dy't goed ynformeare systeemarsjitekten wolle wurde. It is ûnmooglik om Linux-applikaasje-optimisaasjetechniken dúdlik te begripen sûnder te dûken yn 'e basis fan hoe't se wurkje op it bestjoeringssysteemnivo. Hoewol d'r in protte soarten applikaasjes binne, wol ik yn dizze searje web-basearre applikaasjes ferkenne ynstee fan buroblêdapplikaasjes lykas in browser of tekstbewurker. Dit materiaal is bedoeld foar ûntwikkelders en arsjitekten dy't wolle begripe hoe't Linux- of Unix-programma's wurkje en hoe't se se strukturearje foar hege prestaasjes.
Linux is tsjinner keamer bestjoeringssysteem, en meastentiids rinne jo applikaasjes op dit OS. Hoewol ik "Linux" sis, kinne jo meastentiids feilich oannimme dat ik alle Unix-like bestjoeringssystemen yn 't algemien bedoel. Ik haw lykwols net hifke de byhearrende koade op oare systemen. Dus, as jo ynteressearre binne yn FreeBSD of OpenBSD, kinne jo resultaten ferskille. As ik wat Linux-spesifyk besykje, wiis ik it op.
Wylst jo dizze kennis kinne brûke om in app fanôf it begjin te bouwen en it sil perfekt optimalisearre wurde, is it it bêste om dat net te dwaan. As jo in nije webserver skriuwe yn C of C++ foar de bedriuwsapplikaasje fan jo organisaasje, kin dit jo lêste dei wêze op 'e baan. It kennen fan 'e struktuer fan dizze applikaasjes sil lykwols helpe by it kiezen fan besteande programma's. Jo sille proses-basearre systemen kinne fergelykje mei thread-basearre systemen lykas evenemint-basearre. Jo sille begripe en wurdearje wêrom Nginx better prestearret dan Apache httpd, wêrom in Tornado basearre Python-applikaasje mear brûkers kin tsjinje yn ferliking mei in Django-basearre Python-applikaasje.
ZeroHTTPd: Learning Tool
ZeroHTTPd is in webserver dy't ik fanôf it begjin skreau yn C as learmiddel. It hat gjin eksterne ôfhinklikens, ynklusyf tagong ta Redis. Wy rinne ús eigen Redis-prosedueres. Sjoch hjirûnder foar mear details.
Hoewol wy teory lang kinne beprate, is d'r neat better dan koade te skriuwen, it út te fieren en alle serverarsjitektueren mei elkoar te fergelykjen. Dit is de meast foar de hân lizzende metoade. Dêrom sille wy in ienfâldige ZeroHTTPd-webserver skriuwe mei elk model: proses-basearre, thread-basearre, en evenemint-basearre. Litte wy elk fan dizze servers kontrolearje en sjen hoe't se prestearje yn ferliking mei elkoar. ZeroHTTPd wurdt ymplementearre yn ien C-bestân. De op eveneminten basearre tsjinner omfettet uthash, in geweldige hash-tabel-ymplemintaasje dy't komt yn ien kopteksttriem. Yn oare gefallen binne d'r gjin ôfhinklikens, om it projekt net te komplisearjen.
D'r binne in protte opmerkingen yn 'e koade om jo te helpen begripe. As in ienfâldige webserver yn in pear rigels koade, is ZeroHTTPd ek in minimaal ramt foar webûntwikkeling. It hat beheinde funksjonaliteit, mar is yn steat om statyske bestannen en heul ienfâldige "dynamyske" siden te tsjinjen. Ik moat sizze dat ZeroHTTPd goed is om te learen hoe't jo Linux-applikaasjes mei hege prestaasjes meitsje kinne. Yn 't algemien wachtsje de measte webtsjinsten op oanfragen, kontrolearje se en ferwurkje se. Dit is krekt wat ZeroHTTPd sil dwaan. Dit is in ark foar learen, net produksje. It is net geweldig yn it behanneljen fan flaters en it is net wierskynlik dat it de bêste feiligenspraktiken hat (oh ja, ik brûkte strcpy) of de tûke trúkjes fan de taal C. Mar ik hoopje dat it syn wurk goed docht.
ZeroHTTPd thússide. It kin ferskate bestânstypen útfiere, ynklusyf ôfbyldings
Gastboekapplikaasje
Moderne webapplikaasjes binne normaal net beheind ta statyske bestannen. Se hawwe komplekse ynteraksjes mei ferskate databases, caches, ensfh Sa sille wy meitsje in ienfâldige web applikaasje neamd "Guest Book" dêr't besikers litte ynstjoerings ûnder harren nammen. It gastboek bewarret ynstjoerings earder ferlitten. D'r is ek in besikerteller ûnderoan de side.
Webapplikaasje "Gastboek" ZeroHTTPd
De besikersloket en yngongen yn it gastboek wurde opslein yn Redis. Foar kommunikaasje mei Redis wurde eigen prosedueres útfierd; se binne net ôfhinklik fan de eksterne bibleteek. Ik bin gjin grutte fan fan it útroljen fan homebrew-koade as d'r iepenbier beskikber en goed hifke oplossingen binne. Mar it doel fan ZeroHTTPd is om Linux-prestaasjes te studearjen en tagong ta eksterne tsjinsten, wylst it tsjinjen fan HTTP-oanfragen in serieuze prestaasjesynfloed hat. Wy moatte kommunikaasje mei Redis folslein kontrolearje yn elk fan ús serverarsjitektuer. Yn guon arsjitektuer brûke wy blokkearjende oproppen, yn oaren brûke wy op eveneminten basearre prosedueres. It brûken fan in eksterne Redis-kliïntbibleteek sil dizze kontrôle net leverje. Derneist fiert ús lytse Redis-kliïnt mar in pear funksjes út (in kaai krije, ynstelle en ferheegje; in array krije en taheakje). Derneist is it Redis-protokol ekstreem elegant en ienfâldich. Jo hoege it net iens spesjaal te learen. It feit dat it protokol al it wurk docht yn sawat hûndert rigels koade lit sjen hoe goed trochtocht it is.
De folgjende figuer lit sjen wat de applikaasje docht as de kliïnt (blêder) oanfragen /guestbookURL.
Hoe't de gastboekapplikaasje wurket
As in gastboekside moat wurde útjûn, is der ien oprop oan it bestânsysteem om it sjabloan yn it ûnthâld te lêzen en trije netwurkoproppen nei Redis. It sjabloanbestân befettet de measte HTML-ynhâld foar de side yn 'e skermprint hjirboppe. Der binne ek spesjale plakhâlders foar it dynamyske diel fan de ynhâld: berjochten en besikerteller. Wy ûntfange se fan Redis, foegje se yn 'e side en jouwe de klant folslein foarme ynhâld. De tredde oprop nei Redis kin foarkommen wurde, om't Redis de nije kaaiwearde werombringt as it ferhege wurdt. Foar ús server, dy't in asynchrone op eveneminten basearre arsjitektuer hat, binne in protte netwurkoproppen lykwols in goede test foar leardoelen. Dat wy ferwiderje de Redis-returnwearde fan it oantal besikers en freegje it mei in aparte oprop.
Server arsjitektuer ZeroHTTPd
Wy bouwe sân ferzjes fan ZeroHTTPd mei deselde funksjonaliteit, mar ferskate arsjitektuer:
Iteratyf
Forkserver (ien bernproses per fersyk)
Pre-fork-tsjinner (pre-forking fan prosessen)
Tsjinner mei útfieringsthreads (ien thread per fersyk)
Server mei pre-thread oanmeitsjen
Arsjitektuer basearre poll()
Arsjitektuer basearre epoll
Wy mjitte de prestaasjes fan elke arsjitektuer troch de server te laden mei HTTP-oanfragen. Mar by it fergelykjen fan heul parallelle arsjitektueren nimt it oantal fragen ta. Wy testje trije kear en berekkenje it gemiddelde.
Testmetoade
ZeroHTTPd load test opset
It is wichtich dat by it útfieren fan testen, alle komponinten net op deselde masine rinne. Yn dit gefal komt it OS ekstra scheduling-overhead op as komponinten konkurrearje foar CPU. It mjitten fan it bestjoeringssysteem-overhead fan elk fan 'e selekteare serverarsjitektueren is ien fan' e wichtichste doelen fan dizze oefening. It tafoegjen fan mear fariabelen sil skealik wurde foar it proses. Dêrom wurket de ynstelling yn 'e foto hjirboppe it bêste.
Wat docht elk fan dizze tsjinners?
load.unixism.net: Dit is wêr't wy rinne ab, Apache Benchmark utility. It genereart de lading dy't nedich is om ús serverarsjitektueren te testen.
nginx.unixism.net: Soms wolle wy mear as ien eksimplaar fan in serverprogramma útfiere. Om dit te dwaan, wurket de Nginx-tsjinner mei de passende ynstellings as in load balancer út ab oan ús serverprosessen.
zerohttpd.unixism.net: Hjir rinne wy ús serverprogramma's op sân ferskillende arsjitektueren, ien foar ien.
redis.unixism.net: Dizze tsjinner rint de Redis-daemon, dêr't gastboek-yngongen en besikertellers opslein wurde.
Alle tsjinners rinne op deselde prosessor kearn. It idee is om de maksimale prestaasjes fan elke arsjitektuer te evaluearjen. Sûnt alle serverprogramma's wurde hifke op deselde hardware, is dit in basisline foar fergeliking. Myn test opset bestiet út firtuele servers ferhierd fan Digital Ocean.
Wat mjitte wy?
Jo kinne ferskate yndikatoaren mjitte. Wy evaluearje de prestaasjes fan elke arsjitektuer yn in opjûne konfiguraasje troch de servers te laden mei fersiken op ferskate nivo's fan parallelisme: de lading groeit fan 20 nei 15 tagelyk brûkers.
Testresultaten
De folgjende grafyk toant de prestaasjes fan servers op ferskate arsjitektueren op ferskate nivo's fan parallelisme. De y-as is it oantal oanfragen per sekonde, de x-as is parallelle ferbiningen.
Ut de grafyk en tabel kin sjoen wurde dat boppe 8000 simultane fersiken wy hawwe mar twa spilers: pre-fork en epoll. As de lading tanimt, docht in poll-basearre server minder dan in streaming. De arsjitektuer foar pre-oanmeitsjen fan thread is in weardige konkurrint foar epoll, in testamint fan hoe goed de Linux-kernel in grutte oantal threaden plant.
ZeroHTTPd Boarnekoade
ZeroHTTPd Boarnekoade hjir. D'r is in aparte map foar elke arsjitektuer.
Neist sân mappen foar alle arsjitektueren, binne d'r twa mear yn 'e map op topnivo: iepenbier en sjabloanen. De earste befettet de index.html triem en de ôfbylding fan de earste skermprint. Jo kinne dêr oare bestannen en mappen pleatse, en ZeroHTTPd soe dizze statyske bestannen sûnder problemen moatte tsjinje. As it paad yn 'e browser oerienkomt mei it paad yn' e iepenbiere map, dan siket ZeroHTTPd nei it index.html-bestân yn dizze map. De ynhâld foar it gastboek wurdt dynamysk oanmakke. It hat allinich in thússide, en de ynhâld is basearre op it bestân 'templates/guestbook/index.html'. ZeroHTTPd foeget maklik dynamyske siden ta foar útwreiding. It idee is dat brûkers sjabloanen kinne tafoegje oan dizze map en ZeroHTTPd as nedich útwreidzje.
Om alle sân servers te bouwen, rinne make all út de map op topnivo - en alle builds sille ferskine yn dizze map. Utfierbere bestannen sykje nei de iepenbiere mappen en sjabloanen yn 'e map wêrút se wurde lansearre.
Linux API
Jo hoege net goed te wêzen yn 'e Linux API om de ynformaasje yn dizze artikelsearje te begripen. Ik advisearje lykwols mear te lêzen oer dit ûnderwerp; d'r binne in protte referinsjeboarnen op it ynternet. Hoewol wy ferskate kategoryen fan Linux API's sille oanreitsje, sil ús fokus primêr wêze op prosessen, diskusjes, eveneminten en de netwurkstapel. Neist boeken en artikels oer de Linux API advisearje ik ek it lêzen fan mana foar systeemoproppen en bibleteekfunksjes brûkt.
Prestaasje en Scalability
Ien opmerking oer prestaasjes en skaalberens. Teoretysk is der gjin ferbining tusken harren. Jo kinne in webtsjinst hawwe dy't heul goed wurket, mei in reaksjetiid fan in pear millisekonden, mar it skaalfergrutting hielendal net. Likemin kin d'r in min prestearjende webapplikaasje wêze dy't in pear sekonden duorret om te reagearjen, mar it skaal mei tsientallen om tsientûzenen tagelyk brûkers te behanneljen. De kombinaasje fan hege prestaasjes en skalberens is lykwols in heul krêftige kombinaasje. Applikaasjes mei hege prestaasjes brûke yn 't algemien boarnen sparsam en tsjinje sa effisjint mear tagelyk brûkers op' e tsjinner, wêrtroch't kosten ferminderje.
CPU en I / O taken
Uteinlik binne d'r by it berekkenjen altyd twa mooglike soarten taken: foar I / O en CPU. Untfange oanfragen oer it ynternet (netwurk I/O), bestannen tsjinje (netwurk en skiif I/O), kommunisearje mei de databank (netwurk en skiif I/O) binne allegear I/O-aktiviteiten. Guon databankfragen kinne in bytsje CPU-yntinsyf wêze (sortearje, gemiddeld in miljoen resultaten, ensfh.). De measte webapplikaasjes wurde beheind troch de maksimale mooglike I / O, en de prosessor wurdt selden brûkt op folsleine kapasiteit. As jo sjogge dat guon I / O-taak in protte CPU brûkt, is it wierskynlik in teken fan minne applikaasje-arsjitektuer. Dit kin betsjutte dat CPU-boarnen fergriemd wurde op prosesbehear en kontekstwikseling - en dit is net hielendal nuttich. As jo wat dogge lykas ôfbyldingsferwurking, audiobestânkonverzje, of masine learen, dan fereasket de applikaasje krêftige CPU-boarnen. Mar foar de measte applikaasjes is dit net it gefal.