Učinkovitost omrežne aplikacije Linux. Uvod

Spletne aplikacije se zdaj uporabljajo povsod, med vsemi transportnimi protokoli pa HTTP zavzema levji delež. Pri preučevanju nians razvoja spletnih aplikacij večina ljudi posveča zelo malo pozornosti operacijskemu sistemu, v katerem se te aplikacije dejansko izvajajo. Ločitev razvoja (Dev) in operacij (Ops) je situacijo le še poslabšala. Toda z vzponom kulture DevOps razvijalci postajajo odgovorni za izvajanje svojih aplikacij v oblaku, zato je zanje zelo koristno, da se temeljito seznanijo z zaledjem operacijskega sistema. To je še posebej uporabno, če poskušate razmestiti sistem za več tisoč ali deset tisoč sočasnih povezav.

Omejitve v spletnih storitvah so zelo podobne tistim v drugih aplikacijah. Ne glede na to, ali gre za izravnalnike obremenitve ali strežnike baz podatkov, imajo vse te aplikacije podobne težave v visoko zmogljivem okolju. Razumevanje teh temeljnih omejitev in kako jih na splošno premagati vam bo pomagalo oceniti učinkovitost in razširljivost vaših spletnih aplikacij.

To serijo člankov pišem kot odgovor na vprašanja mladih razvijalcev, ki želijo postati dobro obveščeni sistemski arhitekti. Nemogoče je jasno razumeti tehnike optimizacije aplikacij Linux, ne da bi se poglobili v osnove njihovega delovanja na ravni operacijskega sistema. Čeprav obstaja veliko vrst aplikacij, želim v tej seriji raziskati spletne aplikacije in ne namizne aplikacije, kot sta brskalnik ali urejevalnik besedila. To gradivo je namenjeno razvijalcem in arhitektom, ki želijo razumeti, kako delujejo programi Linux ali Unix in kako jih strukturirati za visoko zmogljivost.

Linux je strežniška soba operacijski sistem in najpogosteje se vaše aplikacije izvajajo na tem OS. Čeprav rečem "Linux", lahko večino časa varno domnevate, da mislim na vse Unixu podobne operacijske sisteme na splošno. Vendar pa spremne kode nisem testiral na drugih sistemih. Torej, če vas zanima FreeBSD ali OpenBSD, se lahko vaši rezultati razlikujejo. Ko poskusim nekaj, kar je specifično za Linux, to opozorim.

Čeprav lahko to znanje uporabite za izdelavo aplikacije iz nič in bo ta popolnoma optimizirana, je najbolje, da tega ne storite. Če pišete nov spletni strežnik v C ali C++ za poslovno aplikacijo vaše organizacije, je to morda vaš zadnji dan v službi. Vendar pa bo poznavanje strukture teh aplikacij pomagalo pri izbiri obstoječih programov. Sisteme, ki temeljijo na procesih, boste lahko primerjali s sistemi, ki temeljijo na nitih, pa tudi na dogodkih. Razumeli in cenili boste, zakaj Nginx deluje bolje kot Apache httpd, zakaj lahko aplikacija Python, ki temelji na Tornadu, služi več uporabnikom v primerjavi z aplikacijo Python, ki temelji na Djangu.

ZeroHTTPd: Orodje za učenje

ZeroHTTPd je spletni strežnik, ki sem ga napisal iz nič v C kot učno orodje. Nima zunanjih odvisnosti, vključno z dostopom do Redisa. Izvajamo lastne postopke Redis. Glejte spodaj za več podrobnosti.

Čeprav bi lahko na dolgo razpravljali o teoriji, ni nič boljšega od pisanja kode, njenega izvajanja in primerjave vseh strežniških arhitektur med seboj. To je najbolj očitna metoda. Zato bomo napisali preprost spletni strežnik ZeroHTTPd z uporabo vsakega modela: na osnovi procesa, na osnovi niti in na podlagi dogodkov. Oglejmo si vsakega od teh strežnikov in poglejmo, kako delujejo v primerjavi med seboj. ZeroHTTPd je implementiran v eni sami datoteki C. Strežnik na podlagi dogodkov vključuje uthash, odlična implementacija zgoščene tabele, ki je na voljo v eni sami datoteki glave. V drugih primerih ni odvisnosti, da ne bi komplicirali projekta.

V kodi je veliko komentarjev, ki vam pomagajo razumeti. Ker je ZeroHTTPd preprost spletni strežnik v nekaj vrsticah kode, je tudi minimalno ogrodje za spletni razvoj. Ima omejeno funkcionalnost, vendar lahko streže statične datoteke in zelo preproste "dinamične" strani. Moram reči, da je ZeroHTTPd dober za učenje ustvarjanja visoko zmogljivih aplikacij za Linux. Na splošno večina spletnih storitev čaka na zahteve, jih preverja in obdeluje. Točno to bo storil ZeroHTTPd. To je orodje za učenje, ne za proizvodnjo. Ni dober pri obravnavanju napak in verjetno se ne bo ponašal z najboljšimi varnostnimi praksami (o ja, uporabil sem strcpy) ali premetene zvijače jezika C. Vendar upam, da dobro opravlja svoje delo.

Učinkovitost omrežne aplikacije Linux. Uvod
Domača stran ZeroHTTPd. Lahko izpiše različne vrste datotek, vključno s slikami

Aplikacija Knjiga gostov

Sodobne spletne aplikacije običajno niso omejene na statične datoteke. Imajo zapletene interakcije z različnimi bazami podatkov, predpomnilniki itd. Zato bomo ustvarili preprosto spletno aplikacijo, imenovano "Knjiga gostov", kjer obiskovalci puščajo vnose pod svojim imenom. V knjigi gostov so shranjeni vnosi, ki ste jih pustili prej. Na dnu strani je tudi števec obiskovalcev.

Učinkovitost omrežne aplikacije Linux. Uvod
Spletna aplikacija "Knjiga gostov" ZeroHTTPd

Števec obiskovalcev in vnosi v knjigo gostov so shranjeni v Redisu. Za komunikacijo z Redisom so implementirani lastni postopki, ki niso odvisni od zunanje knjižnice. Nisem velik oboževalec uvajanja homebrew kode, če obstajajo javno dostopne in dobro preizkušene rešitve. Toda namen ZeroHTTPd je preučevanje zmogljivosti Linuxa in dostopa do zunanjih storitev, medtem ko ima streženje zahtev HTTP resen vpliv na zmogljivost. Popolnoma moramo nadzorovati komunikacijo z Redisom v vsaki od naših strežniških arhitektur. V nekaterih arhitekturah uporabljamo blokiranje klicev, v drugih pa postopke, ki temeljijo na dogodkih. Uporaba zunanje odjemalske knjižnice Redis ne bo zagotovila tega nadzora. Poleg tega naš mali odjemalec Redis izvaja le nekaj funkcij (pridobivanje, nastavitev in povečanje ključa; pridobivanje in dodajanje matriki). Poleg tega je protokol Redis izjemno eleganten in preprost. Niti ga ni treba posebej učiti. Že dejstvo, da protokol vse delo opravi v približno stotih vrsticah kode, pove, kako dobro je premišljen.

Naslednja slika prikazuje, kaj aplikacija naredi, ko odjemalec (brskalnik) zahteva /guestbookURL.

Učinkovitost omrežne aplikacije Linux. Uvod
Kako deluje aplikacija knjiga gostov

Ko je treba izdati stran knjige gostov, obstaja en klic v datotečni sistem za branje predloge v pomnilnik in trije omrežni klici v Redis. Datoteka predloge vsebuje večino vsebine HTML za stran na zgornjem posnetku zaslona. Obstajajo tudi posebna mesta za dinamični del vsebine: objave in števec obiskovalcev. Prejmemo jih od Redisa, jih vstavimo na stran in naročniku posredujemo v celoti oblikovano vsebino. Tretjemu klicu Redisa se je mogoče izogniti, ker Redis vrne novo vrednost ključa, ko se poveča. Vendar je za naš strežnik, ki ima asinhrono arhitekturo, ki temelji na dogodkih, veliko omrežnih klicev dober preizkus za učne namene. Zato zavržemo Redisovo vrnjeno vrednost števila obiskovalcev in jo poizvedujemo z ločenim klicem.

Strežniške arhitekture ZeroHTTPd

Gradimo sedem različic ZeroHTTPd z enako funkcionalnostjo, vendar različnimi arhitekturami:

  • Iterativno
  • Fork strežnik (en podrejeni proces na zahtevo)
  • Pre-fork strežnik (predhodno razcepljanje procesov)
  • Strežnik z izvajalnimi nitmi (ena nit na zahtevo)
  • Strežnik s predhodnim ustvarjanjem niti
  • Temelji na arhitekturi poll()
  • Temelji na arhitekturi epoll

Učinkovitost vsake arhitekture merimo tako, da strežnik naložimo z zahtevami HTTP. Toda pri primerjavi zelo vzporednih arhitektur se število poizvedb poveča. Testiramo trikrat in izračunamo povprečje.

Metodologija testiranja

Učinkovitost omrežne aplikacije Linux. Uvod
Nastavitev testiranja obremenitve ZeroHTTPd

Pomembno je, da se pri izvajanju testov vse komponente ne izvajajo na istem stroju. V tem primeru ima operacijski sistem dodatne stroške razporejanja, saj komponente tekmujejo za CPE. Merjenje stroškov operacijskega sistema za vsako od izbranih strežniških arhitektur je eden najpomembnejših ciljev te vaje. Dodajanje več spremenljivk bo škodovalo procesu. Zato nastavitev na zgornji sliki deluje najbolje.

Kaj počne vsak od teh strežnikov?

  • load.unixism.net: Tukaj tečemo ab, pripomoček Apache Benchmark. Ustvarja obremenitev, potrebno za testiranje naših strežniških arhitektur.
  • nginx.unixism.net: Včasih želimo zagnati več kot en primerek strežniškega programa. Če želite to narediti, strežnik Nginx z ustreznimi nastavitvami deluje kot izravnalnik obremenitve, ki prihaja iz ab na procese našega strežnika.
  • zerohttpd.unixism.net: Tukaj izvajamo naše strežniške programe na sedmih različnih arhitekturah, eno za drugo.
  • redis.unixism.net: Ta strežnik poganja demon Redis, kjer so shranjeni vnosi v knjigo gostov in števci obiskovalcev.

Vsi strežniki delujejo na istem procesorskem jedru. Ideja je oceniti največjo zmogljivost vsake arhitekture. Ker so vsi strežniški programi testirani na isti strojni opremi, je to osnova za primerjavo. Moja testna nastavitev je sestavljena iz virtualnih strežnikov, najetih pri Digital Ocean.

Kaj merimo?

Izmerite lahko različne kazalnike. Zmogljivost vsake arhitekture v določeni konfiguraciji ocenimo tako, da strežnike naložimo z zahtevami na različnih ravneh vzporednosti: obremenitev naraste z 20 na 15 sočasnih uporabnikov.

Rezultati testiranja

Naslednja tabela prikazuje zmogljivost strežnikov v različnih arhitekturah na različnih ravneh vzporednosti. Y-os je število zahtev na sekundo, x-os so vzporedne povezave.

Učinkovitost omrežne aplikacije Linux. Uvod

Učinkovitost omrežne aplikacije Linux. Uvod

Učinkovitost omrežne aplikacije Linux. Uvod

Spodaj je tabela z rezultati.

zahtev na sekundo

vzporednost
iterativno
vilice
pred vilicami
pretakanje
predhodno pretakanje
Anketa
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
velik razpon
2138

5000
-
velik razpon
1600
1100
2519
-
2235

8000
-
-
1200
velik razpon
2451
-
2100

10
-
-
velik razpon
-
2200
-
2200

11
-
-
-
-
2200
-
2122

12
-
-
-
-
970
-
1958

13
-
-
-
-
730
-
1897

14
-
-
-
-
590
-
1466

15
-
-
-
-
532
-
1281

Iz grafa in tabele je razvidno, da imamo nad 8000 hkratnimi zahtevami le še dva igralca: pre-fork in epoll. Ko se obremenitev poveča, strežnik, ki temelji na anketi, deluje slabše kot pretočni. Arhitektura pred ustvarjanjem niti je vreden tekmec epollu, kar dokazuje, kako dobro jedro Linuxa načrtuje veliko število niti.

Izvorna koda ZeroHTTPd

Izvorna koda ZeroHTTPd tukaj. Za vsako arhitekturo obstaja ločen imenik.

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 └── predloge └── knjiga gostov └── index.html

Poleg sedmih imenikov za vse arhitekture sta v imeniku najvišje ravni še dva: public in templates. Prva vsebuje datoteko index.html in sliko s prvega posnetka zaslona. Tja lahko postavite druge datoteke in mape, ZeroHTTPd pa bi moral brez težav streči te statične datoteke. Če se pot v brskalniku ujema s potjo v javni mapi, ZeroHTTPd poišče datoteko index.html v tem imeniku. Vsebina za knjigo gostov se generira dinamično. Ima samo domačo stran, njena vsebina pa temelji na datoteki 'templates/guestbook/index.html'. ZeroHTTPd enostavno doda dinamične strani za razširitev. Ideja je, da lahko uporabniki dodajajo predloge v ta imenik in po potrebi razširijo ZeroHTTPd.

Če želite zgraditi vseh sedem strežnikov, zaženite make all iz imenika najvišje ravni - in vse gradnje bodo prikazane v tem imeniku. Izvršljive datoteke iščejo javne imenike in imenike predlog v imeniku, iz katerega so zagnane.

API za Linux

Za razumevanje informacij v tem nizu člankov vam ni treba dobro poznati API za Linux. Vendar priporočam, da preberete več o tej temi, saj je na internetu veliko referenčnih virov. Čeprav se bomo dotaknili več kategorij API-jev za Linux, se bomo osredotočili predvsem na procese, niti, dogodke in omrežni sklad. Poleg knjig in člankov o API-ju za Linux priporočam tudi branje mane za sistemske klice in uporabljene knjižnične funkcije.

Zmogljivost in razširljivost

Ena opomba o zmogljivosti in razširljivosti. Teoretično med njima ni povezave. Lahko imate spletno storitev, ki deluje zelo dobro, z odzivnim časom nekaj milisekund, vendar se sploh ne prilagaja. Podobno lahko obstaja slabo delujoča spletna aplikacija, ki potrebuje nekaj sekund, da se odzove, vendar se poveča na desetine, da lahko obravnava več deset tisoč sočasnih uporabnikov. Vendar pa je kombinacija visoke zmogljivosti in razširljivosti zelo močna kombinacija. Visokozmogljive aplikacije na splošno varčno uporabljajo vire in tako učinkovito služijo več sočasnim uporabnikom na strežniku, kar zmanjšuje stroške.

CPE in I/O naloge

Končno sta v računalništvu vedno dve možni vrsti nalog: za I/O in CPE. Prejemanje zahtev prek interneta (omrežni V/I), strežba datotek (omrežni in diskovni V/I), komunikacija z bazo podatkov (omrežni in diskovni V/I) so vse V/I dejavnosti. Nekatere poizvedbe v zbirki podatkov so lahko nekoliko zahtevne za CPE (razvrščanje, povprečenje milijona rezultatov itd.). Večina spletnih aplikacij je omejena z največjim možnim V/I, procesor pa se redko uporablja s polno zmogljivostjo. Ko vidite, da neka V/I naloga uporablja veliko CPE, je to najverjetneje znak slabe arhitekture aplikacije. To lahko pomeni, da se viri procesorja zapravljajo za upravljanje procesov in preklapljanje konteksta - to pa ni povsem uporabno. Če delate nekaj, kot je obdelava slik, pretvorba zvočnih datotek ali strojno učenje, potem aplikacija zahteva zmogljive vire procesorja. Toda za večino aplikacij to ne drži.

Izvedite več o strežniških arhitekturah

  1. Del I: Iterativna arhitektura
  2. del II. Fork strežniki
  3. del III. Pre-fork strežniki
  4. Del IV. Strežniki z izvajalnimi nitmi
  5. Del V. Strežniki s predhodno navojem
  6. del VI. Arhitektura, ki temelji na Pol
  7. del VII. arhitektura, ki temelji na epoll

Vir: www.habr.com

Dodaj komentar