Výkon síťových aplikací Linux. Úvod

Webové aplikace se nyní používají všude a mezi všemi transportními protokoly zaujímá lví podíl HTTP. Při studiu nuancí vývoje webových aplikací většina lidí věnuje velmi malou pozornost operačnímu systému, kde tyto aplikace skutečně běží. Oddělení vývoje (Dev) a operací (Ops) situaci jen zhoršilo. S nárůstem kultury DevOps se ale vývojáři stávají odpovědnými za provoz svých aplikací v cloudu, takže je pro ně velmi užitečné důkladně se seznámit s backendem operačního systému. To je zvláště užitečné, pokud se pokoušíte nasadit systém pro tisíce nebo desetitisíce současných připojení.

Omezení webových služeb jsou velmi podobná omezením v jiných aplikacích. Ať už se jedná o nástroje pro vyrovnávání zatížení nebo databázové servery, všechny tyto aplikace mají ve vysoce výkonném prostředí podobné problémy. Pochopení těchto zásadních omezení a toho, jak je obecně překonat, vám pomůže vyhodnotit výkon a škálovatelnost vašich webových aplikací.

Tuto sérii článků píši jako odpověď na otázky mladých vývojářů, kteří se chtějí stát dobře informovanými systémovými architekty. Je nemožné jasně porozumět technikám optimalizace aplikací pro Linux, aniž bychom se ponořili do základů toho, jak fungují na úrovni operačního systému. Přestože existuje mnoho typů aplikací, v této sérii chci prozkoumat spíše webové aplikace než desktopové aplikace, jako je prohlížeč nebo textový editor. Tento materiál je určen pro vývojáře a architekty, kteří chtějí porozumět tomu, jak programy pro Linux nebo Unix fungují a jak je strukturovat pro vysoký výkon.

Linux je serverovna operační systém a vaše aplikace nejčastěji běží na tomto OS. I když říkám „Linux“, většinou můžete bezpečně předpokládat, že mám na mysli všechny operační systémy podobné Unixu obecně. Doprovodný kód jsem však na jiných systémech netestoval. Pokud vás tedy zajímá FreeBSD nebo OpenBSD, vaše výsledky se mohou lišit. Když zkouším něco specifického pro Linux, upozorním na to.

I když tyto znalosti můžete použít k vytvoření aplikace od nuly a bude dokonale optimalizovaná, je nejlepší to nedělat. Pokud napíšete nový webový server v C nebo C++ pro firemní aplikaci vaší organizace, může to být váš poslední den v práci. Znalost struktury těchto aplikací však pomůže při výběru stávajících programů. Budete moci porovnávat systémy založené na procesech se systémy založenými na vláknech a také systémy založené na událostech. Pochopíte a oceníte, proč Nginx funguje lépe než Apache httpd, proč aplikace Python založená na Tornado může sloužit více uživatelům ve srovnání s aplikací Python založená na Django.

ZeroHTTPd: Výukový nástroj

ZeroHTTPd je webový server, který jsem napsal od začátku v C jako výukový nástroj. Nemá žádné externí závislosti, včetně přístupu k Redis. Provozujeme vlastní postupy Redis. Další podrobnosti naleznete níže.

I když bychom mohli dlouze diskutovat o teorii, není nic lepšího než napsat kód, spustit jej a porovnat všechny serverové architektury mezi sebou. Toto je nejviditelnější metoda. Proto napíšeme jednoduchý webový server ZeroHTTPd pomocí každého modelu: procesního, vláknového a událostí. Pojďme se podívat na každý z těchto serverů a podívat se, jak fungují ve srovnání s ostatními. ZeroHTTPd je implementován v jediném souboru C. Server založený na událostech zahrnuje uthash, skvělá implementace hash tabulky, která je dodávána v jediném souboru záhlaví. V ostatních případech neexistují žádné závislosti, aby se projekt nekomplikoval.

V kódu je mnoho komentářů, které vám pomohou pochopit. Jako jednoduchý webový server v několika řádcích kódu je ZeroHTTPd také minimálním rámcem pro vývoj webu. Má omezenou funkčnost, ale je schopen obsluhovat statické soubory a velmi jednoduché „dynamické“ stránky. Musím říct, že ZeroHTTPd je dobré pro učení, jak vytvářet vysoce výkonné linuxové aplikace. Celkově vzato většina webových služeb čeká na požadavky, kontroluje je a zpracovává. To je přesně to, co ZeroHTTPd udělá. Toto je nástroj pro učení, ne pro výrobu. Není skvělý ve zpracování chyb a je nepravděpodobné, že se může pochlubit nejlepšími bezpečnostními postupy (ach ano, použil jsem strcpy) nebo chytré triky jazyka C. Ale doufám, že svou práci odvede dobře.

Výkon síťových aplikací Linux. Úvod
Domovská stránka ZeroHTTPd. Může vystupovat různé typy souborů včetně obrázků

Aplikace Kniha návštěv

Moderní webové aplikace se obvykle neomezují pouze na statické soubory. Mají složité interakce s různými databázemi, kešemi atd. Vytvoříme tedy jednoduchou webovou aplikaci s názvem „Kniha hostů“, kde návštěvníci zanechávají záznamy pod svými jmény. V knize návštěv jsou uloženy dříve zanechané záznamy. V dolní části stránky je také počítadlo návštěvníků.

Výkon síťových aplikací Linux. Úvod
Webová aplikace "Kniha hostů" ZeroHTTPd

Počítadlo návštěv a záznamy v knize návštěv jsou uloženy v Redis. Pro komunikaci s Redis jsou implementovány vlastní postupy, které nejsou závislé na externí knihovně. Nejsem velkým fanouškem zavádění homebrew kódu, když existují veřejně dostupná a dobře otestovaná řešení. Ale účelem ZeroHTTPd je studovat výkon Linuxu a přístup k externím službám, zatímco obsluhovaní požadavků HTTP má vážný dopad na výkon. Musíme plně kontrolovat komunikaci s Redis v každé z našich serverových architektur. V některých architekturách používáme blokování volání, v jiných používáme procedury založené na událostech. Použití externí klientské knihovny Redis toto ovládání neposkytne. Náš malý klient Redis navíc provádí pouze několik funkcí (získání, nastavení a zvýšení klíče; získání a připojení k poli). Protokol Redis je navíc mimořádně elegantní a jednoduchý. Nemusíte to ani speciálně učit. Už samotný fakt, že protokol dělá veškerou práci zhruba ve stovce řádků kódu, ukazuje, jak je promyšlený.

Následující obrázek ukazuje, co aplikace dělá, když klient (prohlížeč) požaduje /guestbookURL.

Výkon síťových aplikací Linux. Úvod
Jak funguje aplikace Kniha návštěv

Když je potřeba vydat stránku návštěvní knihy, dojde k jednomu volání do systému souborů k načtení šablony do paměti a ke třem síťovým voláním do Redis. Soubor šablony obsahuje většinu obsahu HTML pro stránku na snímku obrazovky výše. Existují také speciální zástupné symboly pro dynamickou část obsahu: příspěvky a počítadlo návštěvníků. Přijmeme je od Redis, vložíme je na stránku a poskytneme klientovi plně formovaný obsah. Třetímu volání Redis se lze vyhnout, protože Redis při zvýšení vrací novou hodnotu klíče. Pro náš server, který má asynchronní architekturu založenou na událostech, je však mnoho síťových volání dobrým testem pro účely učení. Takže zahodíme návratovou hodnotu Redis počtu návštěvníků a dotazujeme se na ni samostatným voláním.

Serverové architektury ZeroHTTPd

Vytváříme sedm verzí ZeroHTTPd se stejnou funkčností, ale různými architekturami:

  • Iterativní
  • Fork server (jeden podřízený proces na požadavek)
  • Pre-fork server (pre-forkování procesů)
  • Server s prováděcími vlákny (jedno vlákno na požadavek)
  • Server s předběžnou tvorbou vláken
  • Architektura založená poll()
  • Architektura založená epoll

Výkon každé architektury měříme zatížením serveru HTTP požadavky. Ale při porovnávání vysoce paralelních architektur se počet dotazů zvyšuje. Testujeme třikrát a vypočítáme průměr.

Metodika testování

Výkon síťových aplikací Linux. Úvod
Nastavení zátěžového testování ZeroHTTPd

Je důležité, aby při spouštění testů neběžely všechny komponenty na stejném stroji. V tomto případě OS nese další režii plánování, protože komponenty soutěží o CPU. Jedním z nejdůležitějších cílů tohoto cvičení je měření režie operačního systému každé z vybraných serverových architektur. Přidání dalších proměnných bude pro proces škodlivé. Nejlépe tedy funguje nastavení na obrázku výše.

Co každý z těchto serverů dělá?

  • load.unixism.net: Tady běžíme ab, nástroj Apache Benchmark. Generuje zátěž potřebnou k testování našich serverových architektur.
  • nginx.unixism.net: Někdy chceme spustit více než jednu instanci serverového programu. Za tímto účelem server Nginx s příslušným nastavením funguje jako vyrovnávání zátěže ab na procesy našeho serveru.
  • zerohttpd.unixism.net: Zde provozujeme naše serverové programy na sedmi různých architekturách, jednu po druhé.
  • redis.unixism.net: Tento server spouští démona Redis, kde jsou uloženy záznamy v návštěvní knize a počítadla návštěv.

Všechny servery běží na stejném jádru procesoru. Cílem je vyhodnotit maximální výkon každé architektury. Vzhledem k tomu, že všechny serverové programy jsou testovány na stejném hardwaru, jedná se o základ pro srovnání. Moje testovací nastavení se skládá z virtuálních serverů pronajatých od Digital Ocean.

Co měříme?

Můžete měřit různé ukazatele. Výkon každé architektury v dané konfiguraci hodnotíme zatěžováním serverů požadavky na různých úrovních paralelismu: zatížení roste z 20 na 15 000 souběžných uživatelů.

Výsledky zkoušek

Následující graf ukazuje výkon serverů na různých architekturách na různých úrovních paralelismu. Na ose y je počet požadavků za sekundu, na ose x jsou paralelní připojení.

Výkon síťových aplikací Linux. Úvod

Výkon síťových aplikací Linux. Úvod

Výkon síťových aplikací Linux. Úvod

Níže je tabulka s výsledky.

požadavků za sekundu

souběžnost
iterativní
Vidlička
před-vidlička
streamování
před-streamování
hlasování
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
velký rozptyl
2138

5000
-
velký rozptyl
1600
1100
2519
-
2235

8000
-
-
1200
velký rozptyl
2451
-
2100

10 000
-
-
velký rozptyl
-
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 tabulky je vidět, že nad 8000 současných požadavků nám zbývají pouze dva hráči: pre-fork a epoll. Se zvyšujícím se zatížením má server založený na průzkumu výkon horší než streamovaný server. Architektura před vytvořením vláken je důstojným konkurentem epollu, což je důkazem toho, jak dobře linuxové jádro plánuje velké množství vláken.

Zdrojový kód ZeroHTTPd

Zdrojový kód ZeroHTTPd zde. Pro každou architekturu existuje samostatný adresář.

ZeroHTTPd │ ├── 01_iterativní │ ├── main.c ├── 02_forking │ ├── main.c ├─└——— 03_preforking  04 závitování │ ├── main.c ├── 05_prethreading │ ├── main.c ├── 06_poll │ ├── main.c ├── 07_epoll │ └─└ main.c— Zveřejnit└️ main.c ─ Zveřejnit ── index.html │ └── tux . png └── šablony └── návštěvní kniha └── index.html

Kromě sedmi adresářů pro všechny architektury jsou v adresáři nejvyšší úrovně ještě dva: public a templates. První obsahuje soubor index.html a obrázek z prvního snímku obrazovky. Můžete tam umístit další soubory a složky a ZeroHTTPd by měl tyto statické soubory bez problémů obsluhovat. Pokud se cesta v prohlížeči shoduje s cestou ve veřejné složce, pak ZeroHTTPd hledá soubor index.html v tomto adresáři. Obsah knihy návštěv je generován dynamicky. Má pouze domovskou stránku a její obsah je založen na souboru 'templates/guestbook/index.html'. ZeroHTTPd snadno přidává dynamické stránky pro rozšíření. Myšlenka je taková, že uživatelé mohou do tohoto adresáře přidávat šablony a rozšiřovat ZeroHTTPd podle potřeby.

Chcete-li sestavit všech sedm serverů, spusťte make all z adresáře nejvyšší úrovně - a všechna sestavení se objeví v tomto adresáři. Spustitelné soubory hledají adresář public a templates v adresáři, ze kterého jsou spouštěny.

Linux API

Abyste porozuměli informacím v této sérii článků, nemusíte se dobře orientovat v Linux API. Doporučuji si však o tomto tématu přečíst více, na internetu je mnoho referenčních zdrojů. Přestože se dotkneme několika kategorií linuxových API, zaměříme se především na procesy, vlákna, události a síťový zásobník. Kromě knih a článků o linuxovém API doporučuji číst i manu pro systémová volání a používané funkce knihoven.

Výkon a škálovatelnost

Jedna poznámka o výkonu a škálovatelnosti. Teoreticky mezi nimi není žádná souvislost. Můžete mít webovou službu, která funguje velmi dobře, s dobou odezvy několik milisekund, ale vůbec se neškáluje. Stejně tak může existovat slabě fungující webová aplikace, které trvá několik sekund, než odpoví, ale její rozsah se po desítkách zvýší, aby zvládl desítky tisíc souběžných uživatelů. Kombinace vysokého výkonu a škálovatelnosti je však velmi výkonná kombinace. Vysoce výkonné aplikace obecně využívají zdroje šetrně, a tak efektivně obsluhují více souběžných uživatelů na serveru, což snižuje náklady.

CPU a I/O úlohy

A konečně, v oblasti výpočetní techniky existují vždy dva možné typy úloh: pro I/O a CPU. Přijímání požadavků přes internet (síťové I/O), obsluhování souborů (síťové a diskové I/O), komunikace s databází (síťové a diskové I/O) jsou všechny I/O činnosti. Některé databázové dotazy mohou být trochu náročné na CPU (třídění, průměrování milionu výsledků atd.). Většina webových aplikací je omezena maximálními možnými vstupy a výstupy a procesor je málokdy využíván na plnou kapacitu. Když vidíte, že některá I/O úloha využívá hodně CPU, je to s největší pravděpodobností známkou špatné architektury aplikace. To může znamenat, že se plýtvají prostředky CPU na správu procesů a přepínání kontextu – a to není úplně užitečné. Pokud děláte něco jako zpracování obrazu, konverzi zvukových souborů nebo strojové učení, pak aplikace vyžaduje výkonné CPU zdroje. Ale u většiny aplikací tomu tak není.

Zjistěte více o architektuře serverů

  1. Část I: Iterativní architektura
  2. Část II. Fork servery
  3. Část III. Pre-fork servery
  4. Část IV. Servery s vlákny provádění
  5. Část V. Předvláknové servery
  6. Část VI. Architektura založená na Pol
  7. Část VII. architektura založená na epoll

Zdroj: www.habr.com

Přidat komentář