Linux-netwerktoepassingsprestasie. Inleiding

Webtoepassings word nou oral gebruik, en onder alle vervoerprotokolle beslaan HTTP die grootste deel. Wanneer hulle die nuanses van webtoepassingsontwikkeling bestudeer, skenk die meeste mense baie min aandag aan die bedryfstelsel waar hierdie toepassings werklik loop. Die skeiding van ontwikkeling (Dev) en bedrywighede (Ops) het die situasie net vererger. Maar met die opkoms van DevOps-kultuur word ontwikkelaars verantwoordelik om hul toepassings in die wolk te laat loop, so dit is baie nuttig vir hulle om deeglik vertroud te raak met die agterkant van die bedryfstelsel. Dit is veral nuttig as jy probeer om 'n stelsel vir duisende of tienduisende gelyktydige verbindings te ontplooi.

Die beperkings in webdienste is baie soortgelyk aan dié in ander toepassings. Of dit nou lasbalanseerders of databasisbedieners is, al hierdie toepassings het soortgelyke probleme in 'n hoëprestasie-omgewing. Om hierdie fundamentele beperkings te verstaan ​​en hoe om dit in die algemeen te oorkom, sal jou help om die werkverrigting en skaalbaarheid van jou webtoepassings te evalueer.

Ek skryf hierdie reeks artikels in antwoord op vrae van jong ontwikkelaars wat goed ingeligte stelselargitekte wil word. Dit is onmoontlik om Linux-toepassingsoptimeringstegnieke duidelik te verstaan ​​sonder om in die basiese beginsels te duik van hoe hulle op die bedryfstelselvlak werk. Alhoewel daar baie soorte toepassings is, wil ek in hierdie reeks webgebaseerde toepassings verken eerder as rekenaartoepassings soos 'n blaaier of teksredigeerder. Hierdie materiaal is bedoel vir ontwikkelaars en argitekte wat wil verstaan ​​hoe Linux- of Unix-programme werk en hoe om dit te struktureer vir hoë werkverrigting.

Linux is bediener kamer bedryfstelsel, en meestal loop jou toepassings op hierdie bedryfstelsel. Alhoewel ek "Linux" sê, kan jy die meeste van die tyd veilig aanvaar dat ek alle Unix-agtige bedryfstelsels in die algemeen bedoel. Ek het egter nie die meegaande kode op ander stelsels getoets nie. Dus, as jy in FreeBSD of OpenBSD belangstel, kan jou resultate verskil. Wanneer ek iets Linux-spesifiek probeer, wys ek dit uit.

Alhoewel jy hierdie kennis kan gebruik om 'n toepassing van nuuts af te bou en dit sal perfek geoptimaliseer word, is dit die beste om dit nie te doen nie. As jy 'n nuwe webbediener in C of C++ vir jou organisasie se besigheidstoepassing skryf, is dit dalk jou laaste dag by die werk. Om die struktuur van hierdie toepassings te ken, sal egter help om bestaande programme te kies. Jy sal in staat wees om proses-gebaseerde stelsels te vergelyk met draad-gebaseerde stelsels sowel as gebeurtenis-gebaseerde. Jy sal verstaan ​​en waardeer hoekom Nginx beter presteer as Apache httpd, waarom 'n Tornado-gebaseerde Python-toepassing meer gebruikers kan bedien in vergelyking met 'n Django-gebaseerde Python-toepassing.

ZeroHTTPd: Leerinstrument

ZeroHTTPd is 'n webbediener wat ek van nuuts af in C geskryf het as 'n onderrighulpmiddel. Dit het geen eksterne afhanklikhede nie, insluitend toegang tot Redis. Ons bestuur ons eie Redis-prosedures. Sien hieronder vir meer besonderhede.

Alhoewel ons teorie breedvoerig kan bespreek, is daar niks beter as om kode te skryf, dit uit te voer en alle bedienerargitekture met mekaar te vergelyk nie. Dit is die mees voor die hand liggende metode. Daarom sal ons 'n eenvoudige ZeroHTTPd-webbediener skryf deur elke model te gebruik: prosesgebaseer, draadgebaseerd en gebeurtenisgebaseer. Kom ons kyk na elkeen van hierdie bedieners en kyk hoe hulle presteer in vergelyking met mekaar. ZeroHTTPd is geïmplementeer in 'n enkele C-lêer. Die gebeurtenis-gebaseerde bediener sluit in uthash, 'n wonderlike hash-tabelimplementering wat in 'n enkele koplêer kom. In ander gevalle is daar geen afhanklikhede nie, om nie die projek te bemoeilik nie.

Daar is baie opmerkings in die kode om jou te help verstaan. Omdat dit 'n eenvoudige webbediener in 'n paar reëls kode is, is ZeroHTTPd ook 'n minimale raamwerk vir webontwikkeling. Dit het beperkte funksionaliteit, maar is in staat om statiese lêers en baie eenvoudige "dinamiese" bladsye te bedien. Ek moet sê dat ZeroHTTPd goed is om te leer hoe om hoëprestasie Linux-toepassings te skep. Oor die algemeen wag die meeste webdienste vir versoeke, kontroleer dit en verwerk dit. Dit is presies wat ZeroHTTPd sal doen. Dit is 'n hulpmiddel vir leer, nie produksie nie. Dit is nie goed met fouthantering nie en sal waarskynlik nie met die beste sekuriteitspraktyke spog nie (o ja, ek het gebruik strcpy) of die slim truuks van die taal C. Maar ek hoop dit doen sy werk goed.

Linux-netwerktoepassingsprestasie. Inleiding
ZeroHTTPd tuisblad. Dit kan verskillende lêertipes uitvoer, insluitend beelde

Gasteboek Aansoek

Moderne webtoepassings is gewoonlik nie beperk tot statiese lêers nie. Hulle het komplekse interaksies met verskeie databasisse, kas, ens. Ons sal dus 'n eenvoudige webtoepassing genaamd "Gasteboek" skep waar besoekers inskrywings onder hul name laat. Die gasteboek stoor inskrywings wat vroeër gelaat is. Daar is ook 'n besoekertoonbank onderaan die bladsy.

Linux-netwerktoepassingsprestasie. Inleiding
Webtoepassing "Gasteboek" ZeroHTTPd

Die besoekerstoonbank en gasteboekinskrywings word in Redis gestoor. Vir kommunikasie met Redis word eie prosedures geïmplementeer; dit is nie afhanklik van die eksterne biblioteek nie. Ek is nie 'n groot aanhanger daarvan om homebrew-kode uit te voer wanneer daar publieke beskikbare en goed getoetste oplossings is nie. Maar die doel van ZeroHTTPd is om Linux-werkverrigting en toegang tot eksterne dienste te bestudeer, terwyl die bediening van HTTP-versoeke 'n ernstige prestasie-impak het. Ons moet kommunikasie met Redis ten volle beheer in elkeen van ons bedienerargitekture. In sommige argitekture gebruik ons ​​blokkeeroproepe, in ander gebruik ons ​​gebeurtenisgebaseerde prosedures. Die gebruik van 'n eksterne Redis-kliëntbiblioteek sal nie hierdie beheer verskaf nie. Boonop voer ons klein Redis-kliënt net 'n paar funksies uit (kry, stel en verhoog 'n sleutel; kry en voeg by 'n skikking). Boonop is die Redis-protokol uiters elegant en eenvoudig. Jy hoef dit nie eens spesiaal te leer nie. Die feit dat die protokol al die werk in ongeveer honderd reëls kode doen, wys hoe goed deurdag dit is.

Die volgende figuur wys wat die toepassing doen wanneer die kliënt (blaaier) versoek /guestbookURL.

Linux-netwerktoepassingsprestasie. Inleiding
Hoe die gasteboek-toepassing werk

Wanneer 'n gasteboekbladsy uitgereik moet word, is daar een oproep na die lêerstelsel om die sjabloon in die geheue te lees en drie netwerkoproepe na Redis. Die sjabloonlêer bevat die meeste van die HTML-inhoud vir die bladsy in die skermkiekie hierbo. Daar is ook spesiale plekhouers vir die dinamiese deel van die inhoud: plasings en besoekersteller. Ons ontvang dit van Redis, plaas dit in die bladsy en voorsien die kliënt van volledig gevormde inhoud. Die derde oproep na Redis kan vermy word omdat Redis die nuwe sleutelwaarde terugstuur wanneer dit verhoog word. Vir ons bediener, wat 'n asynchrone gebeurtenis-gebaseerde argitektuur het, is baie netwerkoproepe egter 'n goeie toets vir leerdoeleindes. Ons gooi dus die Redis-terugsendingwaarde van die aantal besoekers weg en bevraagteken dit met 'n aparte oproep.

Bedienerargitekture ZeroHTTPd

Ons bou sewe weergawes van ZeroHTTPd met dieselfde funksionaliteit maar verskillende argitekture:

  • Iteratief
  • Vurkbediener (een kinderproses per versoek)
  • Voorvurkbediener (voorvurk van prosesse)
  • Bediener met uitvoeringsdrade (een draad per versoek)
  • Bediener met pre-thread skepping
  • Argitektuur gebaseer poll()
  • Argitektuur gebaseer epoll

Ons meet die werkverrigting van elke argitektuur deur die bediener met HTTP-versoeke te laai. Maar wanneer hoogs parallelle argitekture vergelyk word, neem die aantal navrae toe. Ons toets drie keer en bereken die gemiddelde.

Toetsmetodologie

Linux-netwerktoepassingsprestasie. Inleiding
ZeroHTTPd-ladingtoetsopstelling

Dit is belangrik dat wanneer toetse uitgevoer word, alle komponente nie op dieselfde masjien werk nie. In hierdie geval het die bedryfstelsel addisionele skeduleringsbokoste, aangesien komponente om SVE meeding. Die meting van die bedryfstelsel se bokoste van elk van die geselekteerde bedienerargitekture is een van die belangrikste doelwitte van hierdie oefening. Die toevoeging van meer veranderlikes sal nadelig vir die proses wees. Daarom werk die instelling in die prent hierbo die beste.

Wat doen elkeen van hierdie bedieners?

  • load.unixism.net: Dit is waar ons hardloop ab, Apache Benchmark-nut. Dit genereer die las wat nodig is om ons bedienerargitekture te toets.
  • nginx.unixism.net: Soms wil ons meer as een geval van 'n bedienerprogram laat loop. Om dit te doen, werk die Nginx-bediener met die toepaslike instellings as 'n lasbalanseerder vandaan ab na ons bedienerprosesse.
  • zerohttpd.unixism.net: Hier loop ons ons bedienerprogramme op sewe verskillende argitekture, een op 'n slag.
  • redis.unixism.net: Hierdie bediener loop die Redis-demon, waar gasteboekinskrywings en besoekertellers gestoor word.

Alle bedieners loop op dieselfde verwerkerkern. Die idee is om die maksimum prestasie van elke argitektuur te evalueer. Aangesien alle bedienerprogramme op dieselfde hardeware getoets word, is dit 'n basislyn vir vergelyking. My toetsopstelling bestaan ​​uit virtuele bedieners wat van Digital Ocean gehuur word.

Wat meet ons?

U kan verskillende aanwysers meet. Ons evalueer die werkverrigting van elke argitektuur in 'n gegewe konfigurasie deur die bedieners te laai met versoeke op verskillende vlakke van parallelisme: die las groei van 20 tot 15 000 gelyktydige gebruikers.

Toetsuitslae

Die volgende grafiek toon die werkverrigting van bedieners op verskillende argitekture op verskillende vlakke van parallelisme. Die y-as is die aantal versoeke per sekonde, die x-as is parallelle verbindings.

Linux-netwerktoepassingsprestasie. Inleiding

Linux-netwerktoepassingsprestasie. Inleiding

Linux-netwerktoepassingsprestasie. Inleiding

Hieronder is 'n tabel met die resultate.

versoeke per sekonde

parallelisme
iteratief
vurk
voorvurk
stroom
voorafstroom
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
groot verspreiding
2138

5000
-
groot verspreiding
1600
1100
2519
-
2235

8000
-
-
1200
groot verspreiding
2451
-
2100

10 000
-
-
groot verspreiding
-
2200
-
2200

11 000
-
-
-
-
2200
-
2122

12 000
-
-
-
-
970
-
1958

13 000
-
-
-
-
730
-
1897

14 000
-
-
-
-
590
-
1466

15 000
-
-
-
-
532
-
1281

Uit die grafiek en tabel is dit duidelik dat bo 8000 gelyktydige versoeke ons net twee spelers oor het: voorvurk en epoll. Namate die vrag toeneem, vaar 'n meningspeilingsgebaseerde bediener slegter as 'n stroom een. Die draad-voor-skepping-argitektuur is 'n waardige mededinger vir epoll, 'n bewys van hoe goed die Linux-kern groot getalle drade skeduleer.

ZeroHTTPd-bronkode

ZeroHTTPd-bronkode hier. Daar is 'n aparte gids vir elke argitektuur.

ZeroHTTPd │ ├── 01_iteratief │ ├── hoof.c ├── 02_vurk │ ├── hoof.c ├── 03_voorvurk ── ─ ─ ─ ─ ─ ─ │ _ inryg │ ├── hoof.c ├── 04_prethreading │ ├── main.c ├── 05_poll │ ├── main.c ├── 06_epoll │ └── ── ─e hoof.c ├e ├── indeks .html │ └── tux . png └── sjablone └── gasteboek └── index.html

Benewens sewe gidse vir alle argitekture, is daar nog twee in die topvlakgids: publiek en sjablone. Die eerste bevat die index.html-lêer en die prent van die eerste skermskoot. Jy kan ander lêers en gidse daar plaas, en ZeroHTTPd behoort daardie statiese lêers sonder enige probleme te bedien. As die pad in die blaaier ooreenstem met die pad in die publieke gids, dan soek ZeroHTTPd vir die index.html lêer in hierdie gids. Die inhoud vir die gasteboek word dinamies gegenereer. Dit het net 'n tuisblad, en die inhoud daarvan is gebaseer op die lêer 'templates/guestbook/index.html'. ZeroHTTPd voeg maklik dinamiese bladsye vir uitbreiding by. Die idee is dat gebruikers sjablone by hierdie gids kan voeg en ZeroHTTPd kan uitbrei soos nodig.

Om al sewe bedieners te bou, hardloop make all vanaf die boonste vlak gids - en alle bouwerk sal in hierdie gids verskyn. Uitvoerbare lêers soek die publieke en sjablone-gidse in die gids waaruit hulle bekendgestel word.

Linux API

Jy hoef nie goed vertroud te wees met die Linux API om die inligting in hierdie artikelreeks te verstaan ​​nie. Ek beveel egter aan om meer oor hierdie onderwerp te lees; daar is baie verwysingsbronne op die internet. Alhoewel ons verskeie kategorieë Linux API's sal aanraak, sal ons fokus hoofsaaklik op prosesse, drade, gebeurtenisse en die netwerkstapel wees. Benewens boeke en artikels oor die Linux API, beveel ek ook aan om mana te lees vir stelseloproepe en biblioteekfunksies wat gebruik word.

Prestasie en skaalbaarheid

Een nota oor werkverrigting en skaalbaarheid. Teoreties is daar geen verband tussen hulle nie. Jy kan 'n webdiens hê wat baie goed werk, met 'n reaksietyd van 'n paar millisekondes, maar dit skaal glad nie. Net so kan daar 'n swak presterende webtoepassing wees wat 'n paar sekondes neem om te reageer, maar dit skaal met tiene om tienduisende gelyktydige gebruikers te hanteer. Die kombinasie van hoë werkverrigting en skaalbaarheid is egter 'n baie kragtige kombinasie. Hoëprestasie-toepassings gebruik hulpbronne oor die algemeen spaarsamig en bedien dus meer gelyktydige gebruikers op die bediener doeltreffend, wat koste verminder.

SVE en I/O take

Ten slotte, in rekenaar is daar altyd twee moontlike tipes take: vir I/O en SVE. Die ontvangs van versoeke oor die internet (netwerk-I/O), die bediening van lêers (netwerk- en skyf-I/O), kommunikasie met die databasis (netwerk en skyf-I/O) is alles I/O-aktiwiteite. Sommige databasisnavrae kan 'n bietjie SVE-intensief wees (sortering, gemiddeld 'n miljoen resultate, ens.). Die meeste webtoepassings word beperk deur die maksimum moontlike I/O, en die verwerker word selde op volle kapasiteit gebruik. As jy sien dat een of ander I/O-taak baie SVE gebruik, is dit heel waarskynlik 'n teken van swak toepassingsargitektuur. Dit kan beteken dat SVE-hulpbronne vermors word op prosesbestuur en kontekswisseling - en dit is nie heeltemal nuttig nie. As jy iets soos beeldverwerking, klanklêeromskakeling of masjienleer doen, benodig die toepassing kragtige SVE-hulpbronne. Maar vir die meeste toepassings is dit nie die geval nie.

Kom meer te wete oor bedienerargitekture

  1. Deel I: Iteratiewe argitektuur
  2. Deel II. Vurk bedieners
  3. Deel III. Voorvurk bedieners
  4. Deel IV. Bedieners met drade van uitvoering
  5. Deel V. Pre-threaded bedieners
  6. Deel VI. Pol-gebaseerde argitektuur
  7. Deel VII. epoll-gebaseerde argitektuur

Bron: will.com

Voeg 'n opmerking