Izvedba mrežnih aplikacija na Linuxu. Uvod

Web aplikacije se danas koriste svugdje, a među svim transportnim protokolima HTTP zauzima najveći dio. Kada se proučavaju nijanse razvoja web aplikacija, većina posvećuje vrlo malo pažnje operativnom sustavu na kojem se te aplikacije zapravo pokreću. Razdvajanje razvoja (Dev) i operacija (Ops) samo je pogorÅ”avalo situaciju. No, s porastom DevOps kulture, programeri počinju preuzimati odgovornost za pokretanje svojih aplikacija u oblaku, stoga im je od velike koristi detaljno upoznavanje sa backendom operativnog sustava. To je posebno korisno ako pokuÅ”avate postaviti sustav za tisuće ili desetke tisuća istodobnih veza.

Ograničenja u web uslugama vrlo su slična onima u drugim aplikacijama. Bilo da se radi o balansiranim opterećenjima ili poslužiteljima baza podataka, sva ta rjeÅ”enja imaju slične probleme u visoko performansnim okruženjima. Razumijevanje tih temeljnih ograničenja i načina na koje ih možemo prevladati općenito će omogućiti procjenu performansi i skalabilnosti vaÅ”ih web aplikacija.

PiÅ”em ovu seriju članaka kao odgovor na pitanja mladih programera koji žele postati dobro informirani sistemski arhitekti. Nemoguće je jasno razumjeti metode optimizacije aplikacija na Linuxu bez uranjanja u osnove, kako one rade na razini operativnog sustava. Iako postoji mnogo vrsta aplikacija, u ovom ciklusu želim istražiti mrežne aplikacije, a ne desktop aplikacije poput preglednika ili tekstualnog urednika. Ovaj materijal namijenjen je programerima i arhitektama koji žele shvatiti kako funkcioniraju programi na Linuxu ili Unixu i kako ih strukturirati za visoke performanse.

Linux je poslužiteljski operativni sustav, i najčeŔće vaÅ”e aplikacije rade upravo na ovom OS-u. Iako govorim "Linux", većinu vremena možete s povjerenjem pretpostaviti da se misli na sve Unix-slične operativne sustave općenito. Ipak, nisam testirao prateći kod na drugim sustavima. Dakle, ako vas zanima FreeBSD ili OpenBSD, rezultati se mogu razlikovati. Kada isprobavam neÅ”to Å”to je specifično za Linux, to jasno naglaÅ”avam.

Iako možete iskoristiti stečeno znanje za izradu aplikacije od nule koja će biti odlično optimizirana, bolje je to ne raditi. Ako napiÅ”ete novi web poslužitelj u C ili C++ za poslovnu aplikaciju vaÅ”e organizacije, možda će to biti vaÅ” posljednji dan na poslu. Ipak, poznavanje strukture tih aplikacija pomoći će vam u odabiru već postojećih programa. Moći ćete uspoređivati sustave temeljem procesa, sustavima temeljenim na nitima, kao i temeljenim na događajima. Razumjet ćete i cijeniti zaÅ”to Nginx radi bolje od Apache httpd-a, zaÅ”to aplikacija Python temeljena na Tornadu može opslužiti viÅ”e korisnika u usporedbi s aplikacijom Python temeljene na Djangou.

ZeroHTTPd: alat za učenje

ZeroHTTPd — web poslužitelj koji sam napisao od nule u C-u kao alat za učenje. Nemamo vanjskih ovisnosti, uključujući pristup Redis-u. Pokrećemo vlastite Redis procedure. ViÅ”e informacija možete pronaći u nastavku.

Iako bismo mogli dugo raspravljati o teoriji, nema ničega boljeg od pisanja koda, pokretanja i usporedbe svih arhitektura poslužitelja. Ovo je najjasnija metoda. Zato ćemo napisati jednostavni web poslužitelj ZeroHTTPd, koristeći svaki model: temeljen na procesima, nitima i događajima. Provjerit ćemo svaki od ovih poslužitelja i vidjeti kako rade u usporedbi jedni s drugima. ZeroHTTPd je implementiran u jednoj C datoteci. U sustav poslužitelja temeljenog na događajima uključena je uthash, izvrsna implementacija hash tablice koja dolazi u jednom zaglavlju. U ostalim slučajevima nema ovisnosti kako bi se izbjeglo kompliciranje projekta.

Kod sadrži mnogo komentara kako bi pomogao razumijevanju. Kao jednostavan web poslužitelj u nekoliko redaka koda, ZeroHTTPd također predstavlja minimalni okvir za web razvoj. Ima ograničene funkcionalnosti, ali može isporučivati statične datoteke i vrlo jednostavne "dinamičke" stranice. Moram reći da je ZeroHTTPd dobar alat za učenje kako stvarati visoko performatne Linux aplikacije. Uglavnom, većina web usluga čeka na zahtjeve, provjerava ih i obrađuje. To će raditi ZeroHTTPd. To je alat za učenje, a ne za produkciju. Nije jak u obradi pogreÅ”aka i vjerojatno se ne može pohvaliti najboljim praksama sigurnosti (oh da, koristio sam strcpy) ili neobičnim trikovima jezika C. Ali se nadam da će se dobro snaći u svom zadatku.

Izvedba mrežnih aplikacija na Linuxu. Uvod
Početna stranica ZeroHTTPd. Može izdavati različite tipove datoteka, uključujući slike.

Aplikacija za knjigu gostiju.

Moderne web aplikacije obično nisu ograničene na statičke datoteke. Imaju složene interakcije s raznim bazama podataka, keÅ”ovima itd. Stoga ćemo stvoriti jednostavnu web aplikaciju pod nazivom "Knjiga gostiju", gdje posjetitelji ostavljaju zapise pod svojim imenima. U knjizi gostiju se čuvaju prethodno ostavljeni zapisi. Također, na dnu stranice postoji brojčanik posjetitelja.

Izvedba mrežnih aplikacija na Linuxu. Uvod
Web aplikacija "Knjiga gostiju" ZeroHTTPd.

Brojčanik posjetitelja i zapisi knjige gostiju čuvaju se u Redis-u. Za komunikaciju s Redis-om implementirane su vlastite procedure, koje ne ovise o vanjskoj biblioteci. Nisam veliki obožavatelj koriÅ”tenja domaćeg koda kada postoje javno dostupna i dobro testirana rjeÅ”enja. Ali cilj ZeroHTTPd-a je istražiti performanse Linux-a i pristup vanjskim uslugama, dok održavanje HTTP zahtjeva ozbiljno utječe na performanse. Moramo potpuno kontrolirati komunikaciju s Redis-om u svakoj od naÅ”ih serverskih arhitektura. U jednoj arhitekturi koristimo blokirajuće pozive, a u drugima procedure temeljene na događajima. KoriÅ”tenje vanjske klijentske biblioteke Redis ne bi omogućilo takvu kontrolu. Osim toga, naÅ” mali Redis klijent izvodi samo nekoliko funkcija (dobivanje, postavljanje i povećanje ključa; dobivanje i dodavanje u niz). Također, Redis protokol je iznimno elegantan i jednostavan. Njega čak ne treba posebno učiti. Samo to Å”to cijeli posao protokol obavlja s otprilike stotinjak redaka koda govori koliko je dobro osmiÅ”ljen.

Na sljedećem dijagramu prikazano je ponaÅ”anje aplikacije kada klijent (preglednik) Å”alje zahtjev. /guestbookURL.

Izvedba mrežnih aplikacija na Linuxu. Uvod
Mehanizam rada aplikacije knjige gostiju.

Kada treba prikazati stranicu gostujuće knjige, izvrÅ”ava se jedan poziv prema datotečnom sustavu za učitavanje predloÅ”ka u memoriju i tri mrežna poziva prema Redis-u. Datoteka predloÅ”ka sadrži većinu HTML sadržaja za stranicu na gornjem ekranu. Tu su i posebne oznake za dinamički dio sadržaja: unose i brojač posjetitelja. Dobivamo ih iz Redis-a, umetnemo na stranicu i isporučimo klijentu potpuno oblikovani sadržaj. Treći poziv Redis-u možemo izbjeći, jer Redis vraća novu vrijednost ključa prilikom povećanja. Međutim, za naÅ” poslužitelj s asinkronom arhitekturom temeljenom na događajima, mnogo mrežnih poziva je dobar test u obrazovne svrhe. Tako odbacujemo vraćenu vrijednost Redis-a o broju posjetitelja i tražimo je zasebnim pozivom.

Poslužiteljske arhitekture ZeroHTTPd

Gradimo sedam verzija ZeroHTTPd s istom funkcionalnoŔću, ali različitim arhitekturama:

  • Iterativna
  • Fork poslužitelj (jedan podproces po zahtjevu)
  • Pre-fork poslužitelj (prethodno forkiranje procesa)
  • Poslužitelj s izvođenjem niti (jedna nit po zahtjevu)
  • Poslužitelj s prethodnim stvaranjem niti
  • Arhitektura temeljena na poll()
  • Arhitektura temeljena na epoll

Mjerimo performanse svake arhitekture opterećujući poslužitelj HTTP zahtjevima. Međutim, prilikom usporedbe arhitektura s visokim stupnjem paralelizma, broj zahtjeva se povećava. Testiramo tri puta i računamo prosjek.

Metodologija testiranja

Izvedba mrežnih aplikacija na Linuxu. Uvod
Postavka za opterećujuće testiranje ZeroHTTPd

Važno je da prilikom izvođenja testova svi sastavni dijelovi ne rade na jednoj maÅ”ini. U tom slučaju, operativni sustav nosi dodatne troÅ”kove planiranja jer se dijelovi natječu za CPU. Mjerenje troÅ”kova operativnog sustava s svakom od odabranih poslužiteljskih arhitektura jedan je od najvažnijih ciljeva ove vježbe. Dodavanje većeg broja varijabli bit će pogubno za proces. Stoga konfiguracija na gornjoj slici najbolje funkcionira.

Što čini svaki od ovih poslužitelja

  • load.unixism.net: ovdje pokrećemo ab, Apache Benchmark alat. Generira opterećenje potrebno za testiranje naÅ”ih poslužiteljskih arhitektura.
  • nginx.unixism.net: ponekad želimo pokrenuti viÅ”e od jednog primjerka poslužiteljske aplikacije. Za to Nginx poslužitelj s odgovarajućim postavkama radi kao balansirnik opterećenja koji dolazi od ab naÅ”e poslužiteljske procese.
  • zerohttpd.unixism.net: ovdje pokrećemo naÅ”e poslužiteljske programe na sedam različitih arhitektura, jedan po jedan.
  • redis.unixism.net: na ovom poslužitelju radi daemon Redis, gdje se pohranjuju zapisi u knjigu gostiju i broj posjetitelja.

Svi poslužitelji rade na jednom procesorskom jezgru. Ideja je procijeniti maksimalnu izvedbu svake od arhitektura. Budući da se svi poslužiteljski programi testiraju na jednoj opremi, to je osnovna razina za njihovo uspoređivanje. Moja testna postavka sastoji se od virtualnih poslužitelja, iznajmljenih od Digital Oceana.

Å to mjerimo?

Mogu se izmjeriti različiti pokazatelji. Procjenjujemo izvedbu svake arhitekture u ovoj konfiguraciji, opterećujući poslužitelje upitima na različitim razinama paralelizma: opterećenje raste od 20 do 15,000 istodobnih korisnika.

Rezultati testova

Na sljedećem dijAGRAMU prikazana je izvedba poslužitelja na različitim arhitekturama pri različitim razinama paralelizma. Na y-osi — broj upita po sekundi, na x-osi — paralelne veze.

Izvedba mrežnih aplikacija na Linuxu. Uvod

Izvedba mrežnih aplikacija na Linuxu. Uvod

Izvedba mrežnih aplikacija na Linuxu. Uvod

Ispod je tablica s rezultatima.

upita po sekundi

paralelizam
iterativno
fork
pre-fork
treding
pre-threading
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
veliki raspon
2138

5000
–
veliki raspon
1600
1100
2519
–
2235

8000
–
–
1200
veliki raspon
2451
–
2100

10Ā 000
–
–
veliki raspon
–
2200
–
2200

11Ā 000
–
–
–
–
2200
–
2122

12Ā 000
–
–
–
–
970
–
1958

13Ā 000
–
–
–
–
730
–
1897

14Ā 000
–
–
–
–
590
–
1466

15Ā 000
–
–
–
–
532
–
1281

Iz grafikona i tablice vidljivo je da iznad 8000 istodobnih upita ostaju samo dva igrača: pre-fork i epoll. Kako opterećenje raste, poslužitelj temeljen na poll radi loÅ”ije od threaded. Arhitektura s prethodnim stvaranjem niti predstavlja dostojnu konkurenciju epoll-u: to je svjedočanstvo koliko dobro kernal Linuxa upravlja velikim brojem niti.

Izvorni kod ZeroHTTPd

Izvorni kod ZeroHTTPd ovdje. Za svaku arhitekturu zaseban direktorij.

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
└── templates
    └── guestbook
        └── index.html

Osim sedam direktorija za sve arhitekture, u glavnom direktoriju postoje joÅ” dva: public i templates. U prvom se nalazi datoteka index.html i slika s prvog snimka ekrana. Tamo možete staviti druge datoteke i mape, a ZeroHTTPd bi trebao bez problema poslužiti te statične datoteke. Ako putanja u pregledniku odgovara putanji u mapi public, ZeroHTTPd pretražuje ovaj direktorij za datoteku index.html. Sadržaj za gostujuću knjigu generira se dinamički. Ima samo početnu stranicu, a njezin sadržaj temelji se na datoteci ā€˜templates/guestbook/index.html’. U ZeroHTTPd lako se dodaju dinamičke stranice za proÅ”irenje. Ideja je da korisnici mogu dodavati template u ovaj direktorij i proÅ”irivati ZeroHTTPd prema potrebi.

Za izgradnju svih sedam poslužitelja pokrenite make all iz glavnog direktorija — i sve gradnje će se pojaviti u ovom direktoriju. IzvrÅ”ne datoteke traže mape public i templates u onom direktoriju iz kojeg su pokrenute.

Linux API

Da biste razumjeli informacije u ovom ciklusu članaka, nije potrebno dobro poznavati Linux API. Međutim, preporučujem da pročitate viÅ”e o ovoj temi, na mreži ima mnogo referentnih izvora. Iako ćemo se dotaknuti nekoliko kategorija Linux API-ja, naÅ”a će se pažnja uglavnom usredotočiti na procese, niti, događaje i mrežni stog. Osim knjiga i članaka o Linux API-ju, također preporučujem da pročitate mann priručnike za sistemske pozive i koriÅ”tene bibliotečke funkcije.

Performanse i skalabilnost

Jedna napomena o performansama i skalabilnosti. Teoretski, između njih nema nikakve povezanosti. Možete imati web uslugu koja radi vrlo dobro, s vremenom odgovora od nekoliko milisekundi, ali se uopće ne može skalirati. BaÅ” kao Å”to može postojati loÅ”e izvedena web aplikacija koja traži nekoliko sekundi za odgovor, ali se može skalirati za desetine da bi obradila desetke tisuća istovremenih korisnika. Ipak, kombinacija visoke izvedbe i skalabilnosti je vrlo snažna kombinacija. Visoko performansni programi u cjelini ekonomično koriste resurse i tako efikasno opslužuju viÅ”e istovremenih korisnika na poslužitelju, smanjujući troÅ”kove.

Zadaci CPU i I/O

Na kraju, u računanju uvijek postoje dva moguća tipa zadataka: za I/O i CPU. Primanje zahtjeva putem interneta (mrežni ulaz-izlaz), upravljanje datotekama (mrežni i diskovni ulaz-izlaz), komunikacija s bazom podataka (mrežni i diskovni ulaz-izlaz) — sve su to I/O radnje. Neki zahtjevi za BDP-om mogu malo opteretiti CPU (sortiranje, izračunavanje prosjeka milijun rezultata itd.). Većina web aplikacija ograničena je na maksimalnu moguću I/O, dok se procesor rijetko koristi punom snagom. Kada primijetite da se za određeni zadatak ulaz-izlaz koristi mnogo CPU-a, vjerojatno je to znak loÅ”e arhitekture aplikacije. To može značiti da se resursi CPU-a troÅ”e na upravljanje procesima i prebacivanje konteksta — i to nije posve korisno. Ako radite neÅ”to poput obrade slika, konverzije audio datoteka ili strojnog učenja, tada aplikacija zahtijeva jake CPU resurse. No za većinu aplikacija to nije slučaj.

Detaljnije o servernim arhitekturama

  1. Dio I. Iterativna arhitektura
  2. Dio II. Fork-serveri
  3. Dio III. Pre-fork serveri
  4. Dio IV. Serveri s izvrŔnim nitima
  5. Dio V. Serveri s unaprijed stvorеним nitima
  6. Dio VI. Arhitektura temeljena na poll
  7. Dio VII. Arhitektura temeljena na epoll

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaÅ”titom, VPS VDS servere šŸ”„ Kupite pouzdan hosting za web stranice s DDoS zaÅ”titom, VPS VDS servere | ProHoster