Výkon sieťových aplikácií Linux. Úvod

Webové aplikácie sa teraz používajú všade a spomedzi všetkých transportných protokolov zaberá najväčší podiel HTTP. Pri štúdiu nuancií vývoja webových aplikácií väčšina ľudí venuje veľmi malú pozornosť operačnému systému, kde tieto aplikácie skutočne bežia. Oddelenie vývoja (Dev) a prevádzky (Ops) situáciu len zhoršilo. Ale s nárastom kultúry DevOps sa vývojári stávajú zodpovednými za prevádzkovanie svojich aplikácií v cloude, takže je pre nich veľmi užitočné dôkladne sa oboznámiť s backendom operačného systému. To je obzvlášť užitočné, ak sa pokúšate nasadiť systém pre tisíce alebo desaťtisíce súčasných pripojení.

Obmedzenia vo webových službách sú veľmi podobné ako v iných aplikáciách. Či už ide o vyrovnávače zaťaženia alebo databázové servery, všetky tieto aplikácie majú podobné problémy vo vysokovýkonnom prostredí. Pochopenie týchto základných obmedzení a ako ich vo všeobecnosti prekonať vám pomôže vyhodnotiť výkon a škálovateľnosť vašich webových aplikácií.

Túto sériu článkov píšem ako odpoveď na otázky mladých vývojárov, ktorí sa chcú stať dobre informovanými systémovými architektmi. Je nemožné jasne pochopiť techniky optimalizácie aplikácií pre Linux bez toho, aby ste sa ponorili do základov toho, ako fungujú na úrovni operačného systému. Aj keď existuje veľa typov aplikácií, v tejto sérii chcem preskúmať webové aplikácie, a nie desktopové aplikácie, ako je prehliadač alebo textový editor. Tento materiál je určený pre vývojárov a architektov, ktorí chcú pochopiť, ako fungujú programy pre Linux alebo Unix a ako ich štruktúrovať pre vysoký výkon.

Linux je serverovňa operačný systém a vaše aplikácie najčastejšie bežia na tomto OS. Hoci hovorím „Linux“, väčšinou môžete bezpečne predpokladať, že mám na mysli všetky operačné systémy podobné Unixu vo všeobecnosti. Sprievodný kód som však netestoval na iných systémoch. Takže, ak máte záujem o FreeBSD alebo OpenBSD, vaše výsledky sa môžu líšiť. Keď skúšam niečo špecifické pre Linux, upozorním na to.

Aj keď tieto znalosti môžete použiť na vytvorenie aplikácie od začiatku a bude dokonale optimalizovaná, je lepšie to nerobiť. Ak napíšete nový webový server v C alebo C++ pre firemnú aplikáciu vašej organizácie, môže to byť váš posledný deň v práci. Poznanie štruktúry týchto aplikácií však pomôže pri výbere existujúcich programov. Budete môcť porovnávať systémy založené na procesoch so systémami založenými na vláknach, ako aj systémami založenými na udalostiach. Pochopíte a oceníte, prečo Nginx funguje lepšie ako Apache httpd, prečo aplikácia Python založená na Tornado môže slúžiť viacerým používateľom v porovnaní s aplikáciou Python založenou na Django.

ZeroHTTPd: Nástroj na učenie

ZeroHTTPd je webový server, ktorý som napísal od nuly v C ako učebný nástroj. Nemá žiadne externé závislosti vrátane prístupu k Redis. Prevádzkujeme vlastné postupy Redis. Ďalšie podrobnosti nájdete nižšie.

Hoci by sme mohli diskutovať o teórii dlho, nie je nič lepšie ako napísať kód, spustiť ho a porovnať všetky serverové architektúry medzi sebou. Toto je najzrejmejšia metóda. Preto napíšeme jednoduchý webový server ZeroHTTPd pomocou každého modelu: procesného, ​​vláknového a udalostí. Pozrime sa na každý z týchto serverov a uvidíme, ako fungujú v porovnaní s ostatnými. ZeroHTTPd je implementovaný v jednom súbore C. Server založený na udalostiach zahŕňa uthash, skvelá implementácia hašovacej tabuľky, ktorá sa dodáva v jednom hlavičkovom súbore. V ostatných prípadoch neexistujú žiadne závislosti, aby sa projekt nekomplikoval.

V kóde je veľa komentárov, ktoré vám pomôžu pochopiť. Ako jednoduchý webový server v niekoľkých riadkoch kódu je ZeroHTTPd tiež minimálnym rámcom pre vývoj webu. Má obmedzenú funkčnosť, ale dokáže obsluhovať statické súbory a veľmi jednoduché „dynamické“ stránky. Musím povedať, že ZeroHTTPd je dobré na to, aby ste sa naučili vytvárať vysokovýkonné linuxové aplikácie. Vo všeobecnosti väčšina webových služieb čaká na požiadavky, kontroluje ich a spracováva. Presne toto urobí ZeroHTTPd. Toto je nástroj na učenie, nie výrobu. Nie je skvelý na spracovanie chýb a je nepravdepodobné, že sa môže pochváliť najlepšími bezpečnostnými postupmi (ach áno, použil som strcpy) alebo šikovné triky jazyka C. Dúfam však, že svoju prácu robí dobre.

Výkon sieťových aplikácií Linux. Úvod
Domovská stránka ZeroHTTPd. Môže vydávať rôzne typy súborov vrátane obrázkov

Aplikácia Kniha návštev

Moderné webové aplikácie sa zvyčajne neobmedzujú len na statické súbory. Majú zložité interakcie s rôznymi databázami, vyrovnávacími pamäťami atď. Vytvoríme preto jednoduchú webovú aplikáciu s názvom „Kniha návštev“, kde návštevníci zanechajú záznamy pod svojimi menami. V knihe návštev sa ukladajú skôr zanechané záznamy. V spodnej časti stránky sa nachádza aj počítadlo návštevníkov.

Výkon sieťových aplikácií Linux. Úvod
Webová aplikácia "Kniha návštev" ZeroHTTPd

Počítadlo návštev a záznamy v knihe návštev sú uložené v Redis. Pre komunikáciu s Redis sú implementované vlastné postupy, ktoré nezávisia od externej knižnice. Nie som veľkým fanúšikom zavádzania homebrew kódu, keď existujú verejne dostupné a dobre otestované riešenia. Účelom ZeroHTTPd je však študovať výkon Linuxu a prístup k externým službám, zatiaľ čo obsluhovanie požiadaviek HTTP má vážny vplyv na výkon. Musíme plne kontrolovať komunikáciu s Redis v každej z našich serverových architektúr. V niektorých architektúrach používame blokovacie hovory, v iných používame procedúry založené na udalostiach. Použitie externej klientskej knižnice Redis neposkytuje túto kontrolu. Okrem toho náš malý klient Redis vykonáva iba niekoľko funkcií (získanie, nastavenie a zvýšenie kľúča; získanie a pripojenie k poli). Okrem toho je protokol Redis mimoriadne elegantný a jednoduchý. Netreba to ani špeciálne učiť. Samotný fakt, že protokol robí všetku prácu v približne stovke riadkov kódu, ukazuje, ako dobre je premyslený.

Nasledujúci obrázok ukazuje, čo aplikácia robí, keď klient (prehliadač) požaduje /guestbookURL.

Výkon sieťových aplikácií Linux. Úvod
Ako funguje aplikácia Kniha návštev

Keď je potrebné vydať stránku knihy návštev, existuje jedno volanie do systému súborov na načítanie šablóny do pamäte a tri sieťové volania do Redis. Súbor šablóny obsahuje väčšinu obsahu HTML pre stránku na snímke obrazovky vyššie. Existujú aj špeciálne zástupné symboly pre dynamickú časť obsahu: príspevky a počítadlo návštevníkov. Dostaneme ich od Redis, vložíme ich na stránku a poskytneme klientovi plne sformovaný obsah. Tretiemu volaniu do Redis sa dá vyhnúť, pretože Redis pri zvýšení vráti novú hodnotu kľúča. Avšak pre náš server, ktorý má asynchrónnu architektúru založenú na udalostiach, je veľa sieťových hovorov dobrým testom na vzdelávacie účely. Preto zahodíme návratovú hodnotu Redis počtu návštevníkov a spýtame sa na ňu samostatným volaním.

Serverové architektúry ZeroHTTPd

Vytvárame sedem verzií ZeroHTTPd s rovnakou funkcionalitou, ale rôznymi architektúrami:

  • Iteratívne
  • Fork server (jeden podriadený proces na požiadavku)
  • Pre-fork server (pre-forkovanie procesov)
  • Server s vykonávacími vláknami (jedno vlákno na požiadavku)
  • Server s vytvorením predbežného vlákna
  • Na základe architektúry poll()
  • Na základe architektúry epoll

Výkonnosť každej architektúry meriame načítaním servera HTTP požiadavkami. Ale pri porovnaní vysoko paralelných architektúr sa počet dopytov zvyšuje. Testujeme trikrát a vypočítame priemer.

Metodika testovania

Výkon sieťových aplikácií Linux. Úvod
Nastavenie testovania záťaže ZeroHTTPd

Je dôležité, aby pri spustení testov nebežali všetky komponenty na rovnakom stroji. V tomto prípade OS znáša dodatočnú réžiu plánovania, pretože komponenty súťažia o CPU. Meranie réžie operačného systému každej z vybraných serverových architektúr je jedným z najdôležitejších cieľov tohto cvičenia. Pridanie ďalších premenných bude pre proces škodlivé. Preto najlepšie funguje nastavenie na obrázku vyššie.

Čo robí každý z týchto serverov?

  • load.unixism.net: Toto je miesto, kde bežíme ab, nástroj Apache Benchmark. Generuje záťaž potrebnú na testovanie našich serverových architektúr.
  • nginx.unixism.net: Niekedy chceme spustiť viac ako jednu inštanciu serverového programu. Na tento účel server Nginx s príslušnými nastaveniami funguje ako vyrovnávač zaťaženia ab na procesy nášho servera.
  • zerohttpd.unixism.net: Tu spúšťame naše serverové programy na siedmich rôznych architektúrach, jednu po druhej.
  • redis.unixism.net: Tento server spúšťa démona Redis, kde sú uložené záznamy v knihe návštev a počítadlá návštevníkov.

Všetky servery bežia na rovnakom jadre procesora. Cieľom je vyhodnotiť maximálny výkon každej architektúry. Keďže všetky serverové programy sú testované na rovnakom hardvéri, ide o základ pre porovnanie. Moje testovacie nastavenie pozostáva z virtuálnych serverov prenajatých od Digital Ocean.

Čo meriame?

Môžete merať rôzne ukazovatele. Výkon každej architektúry v danej konfigurácii hodnotíme zaťažením serverov požiadavkami na rôznych úrovniach paralelizmu: záťaž rastie z 20 na 15 000 súbežných používateľov.

Výsledky skúšky

Nasledujúci graf zobrazuje výkon serverov na rôznych architektúrach na rôznych úrovniach paralelizmu. Na osi y je počet požiadaviek za sekundu, na osi x sú paralelné spojenia.

Výkon sieťových aplikácií Linux. Úvod

Výkon sieťových aplikácií Linux. Úvod

Výkon sieťových aplikácií Linux. Úvod

Nižšie je uvedená tabuľka s výsledkami.

žiadostí za sekundu

rovnobežnosť
iteratívny
vidlička
predvidlička
streaming
pred-streamovanie
hlasovanie
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
veľké rozšírenie
2138

5000
-
veľké rozšírenie
1600
1100
2519
-
2235

8000
-
-
1200
veľké rozšírenie
2451
-
2100

10 000
-
-
veľké rozšírenie
-
2200
-
2200

11 000
-
-
-
-
2200
-
2122

12 000
-
-
-
-
970
-
1958

13 000
-
-
-
-
730
-
1897

14 000
-
-
-
-
590
-
1466

15 000
-
-
-
-
532
-
1281

Z grafu a tabuľky je vidieť, že nad 8000 simultánnych požiadaviek nám ostali len dvaja hráči: pre-fork a epoll. Keď sa zaťaženie zvyšuje, server založený na prieskumoch funguje horšie ako streamingový server. Architektúra pred vytvorením vlákien je dôstojným konkurentom epollu, čo je dôkazom toho, ako dobre linuxové jadro plánuje veľké množstvo vlákien.

Zdrojový kód ZeroHTTPd

Zdrojový kód ZeroHTTPd tu. Pre každú architektúru existuje samostatný adresár.

ZeroHTTPd │ ├── 01_iterative │ ├── main.c ├── 02_forking │ ├── main.c ├─── 03_preforking  04 05_ závitovanie │ ├── main.c ├── 06_prethreading │ ├── main.c ├── 07_poll │ ├── main.c ├── XNUMX_epoll │ └─└ main.c ── main.c ─ Zverejniť ├── index .html │ └── tux . png └── šablóny └── kniha návštev └── index.html

Okrem siedmich adresárov pre všetky architektúry sú v adresári najvyššej úrovne ďalšie dva: public a templates. Prvý obsahuje súbor index.html a obrázok z prvej snímky obrazovky. Môžete tam umiestniť ďalšie súbory a priečinky a ZeroHTTPd by mal tieto statické súbory bez problémov obsluhovať. Ak sa cesta v prehliadači zhoduje s cestou vo verejnom priečinku, potom ZeroHTTPd hľadá súbor index.html v tomto adresári. Obsah knihy návštev sa generuje dynamicky. Má iba domovskú stránku a jej obsah je založený na súbore 'templates/guestbook/index.html'. ZeroHTTPd jednoducho pridáva dynamické stránky na rozšírenie. Myšlienkou je, že používatelia môžu do tohto adresára pridávať šablóny a rozširovať ZeroHTTPd podľa potreby.

Ak chcete zostaviť všetkých sedem serverov, spustite make all z adresára najvyššej úrovne - a všetky zostavy sa objavia v tomto adresári. Spustiteľné súbory hľadajú verejné adresáre a adresáre šablón v adresári, z ktorého sa spúšťajú.

Linux API

Aby ste porozumeli informáciám v tejto sérii článkov, nemusíte sa dobre orientovať v Linux API. Odporúčam však prečítať si o tejto téme viac, na internete je množstvo referenčných zdrojov. Aj keď sa dotkneme niekoľkých kategórií linuxových API, zameriame sa predovšetkým na procesy, vlákna, udalosti a sieťový zásobník. Okrem kníh a článkov o Linux API odporúčam prečítať aj manu pre systémové volania a používané funkcie knižnice.

Výkon a škálovateľnosť

Jedna poznámka o výkone a škálovateľnosti. Teoreticky medzi nimi neexistuje žiadna súvislosť. Môžete mať webovú službu, ktorá funguje veľmi dobre, s dobou odozvy niekoľko milisekúnd, no vôbec sa neškáluje. Podobne môže existovať slabo fungujúca webová aplikácia, ktorej odozva trvá niekoľko sekúnd, ale jej rozsah sa zväčší o desiatky, aby zvládla desaťtisíce súbežných používateľov. Kombinácia vysokého výkonu a škálovateľnosti je však veľmi výkonná kombinácia. Vysokovýkonné aplikácie vo všeobecnosti využívajú zdroje šetrne, a tak efektívne obsluhujú viac súbežných používateľov na serveri, čím znižujú náklady.

CPU a I/O úlohy

Nakoniec, vo výpočtovej technike sú vždy dva možné typy úloh: pre I/O a CPU. Prijímanie požiadaviek cez internet (sieťové I/O), obsluhovanie súborov (sieťové a diskové I/O), komunikácia s databázou (sieťové a diskové I/O) sú všetky I/O činnosti. Niektoré databázové dotazy môžu byť trochu náročné na CPU (triedenie, priemerovanie milióna výsledkov atď.). Väčšina webových aplikácií je obmedzená maximálnym možným vstupom/výstupom a procesor je málokedy využívaný na plnú kapacitu. Keď vidíte, že niektorá I/O úloha využíva veľa CPU, je to s najväčšou pravdepodobnosťou znakom zlej aplikačnej architektúry. To môže znamenať, že zdroje CPU sa plytvajú na správu procesov a prepínanie kontextu – a to nie je úplne užitočné. Ak robíte niečo ako spracovanie obrazu, konverziu zvukových súborov alebo strojové učenie, potom aplikácia vyžaduje výkonné zdroje CPU. Ale pre väčšinu aplikácií to tak nie je.

Získajte viac informácií o architektúre serverov

  1. Časť I: Iteratívna architektúra
  2. Časť II. Fork servery
  3. Časť III. Pre-fork servery
  4. Časť IV. Servery s vláknami vykonávania
  5. Časť V. Servery s vopred pripraveným vláknom
  6. Časť VI. Architektúra založená na Pol
  7. Časť VII. architektúra založená na epoll

Zdroj: hab.com

Pridať komentár