Linux tīkla lietojumprogrammu veiktspēja. Ievads

Mūsdienās tīmekļa lietojumprogrammas tiek lietotas visur, un starp visām pārvades protokoliem lielāko daļu aizņem HTTP. Pētījot tīmekļa lietojumprogrammu izstrādes nianses, vairums uzmanību pievērš ļoti maz operētājsistēmai, kur šīs lietojumprogrammas patiesībā tiek palaistas. Izstrādes (Dev) un ekspluatācijas (Ops) nodalīšana tikai pasliktināja situāciju. Taču ar DevOps kultūras izplatību izstrādātāji sāk uzņemties atbildību par savu lietojumprogrammu palaišanu mākoņos, tāpēc viņiem ļoti noderīgi ir rūpīgi iepazīties ar operētājsistēmas aizmuguri. Tas īpaši noderīgi, ja jūs mēģināt īstenot sistēmu tūkstošiem vai desmitiem tūkstošu vienlaicīgu savienojumu.

Ierobežojumi tīmekļa pakalpojumos ir ļoti līdzīgi ierobežojumiem citās lietojumprogrammās. Neatkarīgi no tā, vai tās ir slodzes līdzsvarotāji vai datu bāzes serveri, visām šīm lietojumprogrammām ir līdzīgas problēmas augstas veiktspējas vidē. Izpratne par šiem fundamentālajiem ierobežojumiem un veidiem, kā tos apiet kopumā, ļaus novērtēt jūsu tīmekļa lietojumprogrammu veiktspēju un mērogojamību.

Es rakstu šo rakstu sēriju, reaģējot uz jaunajiem izstrādātājiem, kuri vēlas kļūt par labi informētiem sistēmu arhitektiem. Nav iespējams skaidri saprast Linux lietojumprogrammu optimizācijas metodes, neiedziļinoties pamatos, kā tās darbojas operētājsistēmas līmenī. Lai gan ir daudz lietojumprogrammu veidu, šajā ciklā vēlos izpētīt tīkla lietojumprogrammas, nevis darbvirsmas, piemēram, pārlūku vai teksta redaktoru. Šis materiāls ir orientēts uz izstrādātājiem un arhitektiem, kuri vēlas saprast, kā darbojas Linux vai Unix programmas un kā tās strukturēt augstai veiktspējai.

Linux ir servera operētājsistēma, un visbiežāk jūsu lietojumprogrammas strādā tieši uz šīs OS. Lai gan es saku „Linux”, lielāko daļu laika jūs varat droši pieņemt, ka tiek domātas visas Unix līdzīgas operētājsistēmas kopumā. Tomēr es neesmu testējis pievienoto kodu citās sistēmās. Tātad, ja jūs interesē FreeBSD vai OpenBSD, rezultāts var atšķirties. Kad es mēģinu kaut ko Linux specifisku, es to norādu.

Lai gan jūs varat izmantot iegūtās zināšanas, lai izveidotu lietotni no nulles, un tā būs lieliski optimizēta, tomēr labāk to nedarīt. Ja jūs uzrakstīsiet jaunu tīmekļa serveri C vai C++ valodā sava uzņēmuma biznesa lietojumam, iespējams, tas būs jūsu pēdējais darba diena. Tomēr zināšanas par šo lietojumu struktūru palīdzēs, izvēloties jau esošās programmas. Jūs varēsiet salīdzināt sistēmas, kas balstītas uz procesiem, ar sistēmām, kas balstītas uz pavedieniem un notikumiem. Jūs sapratīsiet un novērtēsiet, kāpēc Nginx strādā labāk nekā Apache httpd, kāpēc Python lietojumprogramma, kas balstīta uz Tornado, var apkalpot vairāk lietotāju salīdzinājumā ar Python lietojumprogrammu, kas balstīta uz Django.

ZeroHTTPd: mācību rīks

ZeroHTTPd — tīmekļa serveris, kuru es uzrakstīju no nulles C valodā kā mācību rīku. Tam nav ārēju atkarību, tostarp piekļuves Redis. Mēs palaidīsim savas Redis procedūras. Sīkāk skatiet zemāk.

Lai gan mēs varētu ilgi diskusēt par teoriju, nav nekā labāka kā uzrakstīt kodu, to palaist un salīdzināt visas servera arhitektūras. Tas ir visredzamākais metods. Tāpēc mēs uzrakstīsim vienkāršu ZeroHTTPd tīmekļa serveri, pielietojot katru modeli: uz procesu, pavedienu un notikumu pamata. Pārbaudīsim katru no šiem serveriem un redzēsim, kā tie salīdzinās. ZeroHTTPd ir īstenots vienā C failā. Notikumu bāzes servera ietvaros ietilpst uthash, lieliska hash tabulas ieviešana, kas tiek piegādāta vienā galvenes failā. Citās situācijās nav atkarību, lai nevajadzētu sarežģīt projektu.

Kodā ir daudz komentāru, kas palīdzēs orientēties. Būdams vienkāršs tīmekļa serveris dažās koda rindās, ZeroHTTPd arī ir minimāls ietvars tīmekļa izstrādei. Tam ir ierobežota funkcionalitāte, bet tas spēj piegādāt statiskos failus un ļoti vienkāršas "dinamiskās" lapas. Jāteic, ka ZeroHTTPd labi piemērots mācībām par augstas veiktspējas Linux lietojumprogrammu izstrādi. Lielākajā daļā gadījumu tīmekļa pakalpojumi gaida pieprasījumus, tos pārbauda un apstrādā. Tieši to darīs ZeroHTTPd. Tas ir mācību rīks, nevis produkcijai. Tas nav spēcīgs kļūdu apstrādē un, iespējams, nevar lepoties ar labākajām drošības praksēm (jā, es izmantoju strcpy) vai ar sarežģītiem C valodas trikiem. Bet es ceru, ka tas labi tiks galā ar savu uzdevumu.

Linux tīkla lietojumprogrammu veiktspēja. Ievads
ZeroHTTPd sākumlapas. Tas var izsniegt dažāda veida failus, tostarp attēlus.

Viesu grāmatas lietotne

Mūsdienu tīmekļa lietojumprogrammas parasti nav ierobežotas ar statiskajiem failiem. Tām ir sarežģītas mijiedarbības ar dažādām datu bāzēm, kešatmiņām utt. Tāpēc mēs izveidosim vienkāršu tīmekļa lietojumprogrammu ar nosaukumu «Viesu grāmata», kur apmeklētāji atstāj ierakstus ar saviem vārdiem. Viesu grāmatā tiek saglabāti iepriekš atstātie ieraksti. Apakšā lapas ir arī apmeklētāju skaitītājs.

Linux tīkla lietojumprogrammu veiktspēja. Ievads
ZeroHTTPd viesu grāmatas tīmekļa lietojumprogramma

Apmeklētāju skaitītājs un viesu grāmatas ieraksti tiek glabāti Redis. Komunikācijai ar Redis ir ieviestas pašas procedūras, tās nav atkarīgas no ārējām bibliotēm. Es neesmu liels fanu, kas izdala mākslīgus kodus, kad ir pieejami publiski un labi testēti risinājumi. Bet ZeroHTTPd mērķis ir izpētīt Linux veiktspēju un piekļuvi ārējām pakalpojumiem, kamēr HTTP pieprasījumu apkalpošana ievērojami ietekmē veiktspēju. Mums jānodrošina pilnīga kontroli pār komunikāciju ar Redis katrā no mūsu servera arhitektūrām. Vienā arhitektūrā mēs izmantojam bloķējošas izsaukšanas, citās – procedūras, kas balstītas uz notikumiem. Izmantojot ārējo klientu Redis bibliotēku, mēs nezaudēsim šo kontroli. Turklāt mūsu mazais Redis klients veic tikai dažas funkcijas (iegūšana, iestatīšana un palielināšana atslēgā; iegūšana un pievienošana masīvam). Turklāt, Redis protokols ir ārkārtīgi elegants un vienkāršs. To pat nav nepieciešams īpaši mācīt. Pats fakts, ka visu darbu protokols izdara aptuveni simts rindiņās koda, liecina par to, cik labi tas ir pārdomāts.

Nākamajā attēlā ir parādītas programmas darbības, kad klients (pārlūks) pieprasa /guestbookURL.

Linux tīkla lietojumprogrammu veiktspēja. Ievads
Viesu grāmatas lietotnes darbības mehānisms

Kad jāizdod viesu grāmatas lapa, tiek veikts viens izsaukums uz failu sistēmu, lai lasītu veidni atmiņā, un trīs tīkla izsaukumi uz Redis. Veidņu fails satur lielāko daļu HTML satura, kas redzams augšējā ekrānšāviņā. Tajā ir arī īpaši aizpildītāji dinamiskajai satura daļai: ierakstiem un apmeklētāju skaitītājam. Mēs iegūstam tos no Redis, ieliekam lapā un izsniedzam klientam pilnībā izveidoto saturu. Trešo Redis izsaukumu varētu izvairīties, jo Redis atgriež jauno atslēgas vērtību palielinājuma gadījumā. Tomēr mūsu serverim ar asinkronu notikumu balstītu arhitektūru vairāki tīkla izsaukumi ir labs pārbaudījums mācību nolūkiem. Tādējādi mēs atmetam atgriezto Redis vērtību par apmeklētāju skaitu un pieprasām to atsevišķā izsaukumā.

ZeroHTTPd Serveru arhitektūras

Mēs būvējam septiņas ZeroHTTPd versijas ar vienādu funkcionalitāti, bet atšķirīgām arhitektūrām:

  • Iteratīvais
  • Fork serveris (viens apakšprocess uz pieprasījumu)
  • Pre-fork serveris (iepriekšējs procesu fork)
  • Izpildes pavediena serveris (viens pavediena uz pieprasījumu)
  • Serveris ar iepriekšēju pavedienu izveidi
  • Arhitektūra, kas balstīta uz poll()
  • Arhitektūra, kas balstīta uz epoll

Mēs mēram katras arhitektūras veiktspēju, noslogojot serveri ar HTTP pieprasījumiem. Taču salīdzinot arhitektūras ar augstu paralēlismu, pieprasījumu skaits palielinās. Mēs testējam trīs reizes un aprēķinām vidējo.

Testēšanas metodoloģija

Linux tīkla lietojumprogrammu veiktspēja. Ievads
ZeroHTTPd slodzes testēšanas konfigurācija

Ir svarīgi, lai testu laikā visi komponenti nedarbotos uz vienas mašīnas. Šajā gadījumā operētājsistēmai ir papildu izdevumi plānošanā, jo komponenti konkurē par CPU. Sistēmas operāciju izdevumu mērīšana ar katru no izvēlētajām serveru arhitektūrām ir viens no šī vingrinājuma vissvarīgākajiem mērķiem. Papildu mainīgo pievienošana varētu būt kaitīga procesam. Tādējādi konfigurācija, kas redzama augšējā attēlā, darbojas vislabāk.

Ko katrs no šiem serveriem dara

  • load.unixism.net: šeit mēs palaidīsim ab, Apache Benchmark rīku. Tas ģenerē slodzi, kas nepieciešama, lai testētu mūsu serveru arhitektūras.
  • nginx.unixism.net: dažkārt mēs vēlamies darbināt vairāk nekā vienu servera programmas instance. Tāpēc Nginx serveris ar atbilstošiem iestatījumiem darbojas kā slodzes balansētājs, kas saņem ab mūsu serveru procesiem.
  • zerohttpd.unixism.net: šeit mēs palaidām mūsu servera programmas septiņās dažādās arhitektūrās, pa vienai reizei.
  • redis.unixism.net: šajā serverī darbojas Redis demons, kur tiek glabātas viesu grāmatas ieraksti un apmeklētāju skaitītājs.

Visi serveri darbojas uz viena procesora kodola. Ideja ir novērtēt maksimālo katras arhitektūras veiktspēju. Tā kā visas servera programmas tiek testētas uz viena aprīkojuma, tas ir pamata līmenis to salīdzināšanai. Mana testēšanas vide sastāv no virtuāliem serveriem, kas iznomāti no Digital Ocean.

Ko mēs mērām?

Varam izmērīt dažādus rādītājus. Mēs novērtējam katras arhitektūras veiktspēju šajā konfigurācijā, noslogojot serverus ar pieprasījumiem dažādos paralelizma līmeņos: slodze pieaug no 20 līdz 15 000 vienlaicīgiem lietotājiem.

Testu rezultāti

Nākamajā diagrammā redzama serveru veiktspēja dažādās arhitektūrās pie dažādiem paralelizma līmeņiem. Y asī — pieprasījumi sekundē, X asī — paralēlie savienojumi.

Linux tīkla lietojumprogrammu veiktspēja. Ievads

Linux tīkla lietojumprogrammu veiktspēja. Ievads

Linux tīkla lietojumprogrammu veiktspēja. Ievads

Zemāk ir tabula ar rezultātiem.

pieprasījumi sekundē

paralelizms
iteratīvais
forku
priekš-fork
plūsmu
priekš-plūsmu
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
liels izkliedējums
2138

5000
–
liels izkliedējums
1600
1100
2519
–
2235

8000
–
–
1200
liels izkliedējums
2451
–
2100

10 000
–
–
liels izkliedējums
–
2200
–
2200

11 000
–
–
–
–
2200
–
2122

12 000
–
–
–
–
970
–
1958

13 000
–
–
–
–
730
–
1897

14 000
–
–
–
–
590
–
1466

15 000
–
–
–
–
532
–
1281

No grafika un tabulas ir redzams, ka virs 8000 vienlaicīgiem pieprasījumiem paliek tikai divi dalībnieki: priekš-fork un epoll. Pieaugot slodzei, serveris, kas balstīts uz poll, darbojas sliktāk nekā plūsmu bāzēts. Arhitektūra ar iepriekšēju plūsmu rada cienīgu konkurenci epoll: tā liecina par to, cik labi Linux kodols plāno lielu skaitu plūsmu.

ZeroHTTPd avota kods

ZeroHTTPd avota kods šeit. Katrai arhitektūrai ir atsevišķa mape.

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

Papildus septiņām direktorijām visām arhitektūrām, augšējā direktorijā ir vēl divas: public un templates. Pirmajā atrodas fails index.html un attēls no pirmā ekrāna. Tur var novietot citus failus un mapes, un ZeroHTTPd šos statiskos failus bez problēmām izsniegs. Ja ceļš pārlūkā atbilst ceļam mapē public, tad ZeroHTTPd meklē šajā katalogā failu index.html. Saturu viesu grāmatai ģenerē dinamiski. Tam ir tikai galvenā lapa, un tās saturs balstās uz failu ‘templates/guestbook/index.html’. ZeroHTTPd viegli pievieno dinamiskas lapas paplašināšanai. Ideja ir tāda, ka lietotāji var pievienot šajā katalogā šablonus un paplašināt ZeroHTTPd pēc vajadzības.

Lai uzbūvētu visus septiņus serverus, palaidiet make all no augšējā kataloga - un visi veidlapas parādīsies šajā katalogā. Izpildāmos failus meklē mapes public un templates tajā mapē, no kuras tos palaidīs.

Linux API

Lai saprastu informāciju šajā rakstu ciklā, nav obligāti jāpārzina Linux API. Tomēr iesaku izlasīt vairāk par šo tēmu, internetā ir daudz resursu. Lai gan mēs pieskarsimies vairākām kategorijām Linux API, mūsu uzmanība galvenokārt tiks veltīta procesiem, pavedieniem, notikumiem un tīkla stekiem. Papildus grāmatām un rakstiem par Linux API iesaku arī izlasīt manu par sistēmas izsaukumiem un izmantotajām bibliotēku funkcijām.

Veiktspēja un mērogojamība

Viena piezīme par veiktspēju un mērogojamību. Teorētiski starp tām nav nekādas saistības. Jums var būt tīmekļa pakalpojums, kas darbojas ļoti labi, ar atbildes laiku dažās milisekundēs, bet tas vispār neskalojas. Tieši tāpat var būt slikti darbojošs tīmekļa lietojums, kuram nepieciešamas vairākas sekundes atbildei, bet tas mērogojas desmitos, lai apstrādātu desmitiem tūkstošu vienlaicīgu lietotāju. Tomēr augstas veiktspējas un mērogojamības kombinācija ir ļoti jaudīga kombinācija. Augstas veiktspējas lietojumi parasti ekonomiski izmanto resursus un tādējādi efektīvi apkalpo vairākus vienlaicīgus lietotājus serverī, samazinot izmaksas.

CPU un I/O uzdevumi

Visbeidzot, skaitļošanā ir divi iespējamie uzdevumu veidi: I/O un CPU. Pieprasījumu saņemšana internetā (tīkla ievade/izveide), failu apkalpošana (tīkla un diska ievade/izveide), saziņa ar datu bāzi (tīkla un diska ievade/izveide) — tas viss ir I/O darbības. Daži datu bāzes pieprasījumi var nedaudz noslogot CPU (sacensība, vidējā vērtība no miljoniem rezultātu utt.). Lielākā daļa tīmekļa lietojumprogrammu ir ierobežotas atbilstoši maksimāli iespējamiem I/O, kamēr procesors reti tiek izmantots pilnā jaudā. Kad redzat, ka kādā I/O uzdevumā tiek izmantots daudz CPU, visticamāk, tas norāda uz sliktu lietojumprogrammas arhitektūru. Tas var nozīmēt, ka CPU resursi tiek tērēti procesu pārvaldībai un konteksta maiņai — un tas nav gluži noderīgi. Ja jūs veicat kaut ko līdzīgu attēlu apstrādei, audio failu konvertēšanai vai mašīnmācīšanai, tad lietojumprogramma prasa jaudīgus CPU resursus. Tomēr lielākajai daļai lietojumprogrammu tas tā nav.

Sīkāka informācija par serveru arhitektūrām

  1. 1. daļa. Iteratīvā arhitektūra
  2. 2. daļa. Fork-serveri
  3. 3. daļa. Pre-fork serveri
  4. 4. daļa. Serveri ar izpildes pavedieniem
  5. 5. daļa. Serveri ar iepriekšēju pavedienu izveidi
  6. 6. daļa. Arhitektūra, kas balstīta uz poll
  7. 7. daļa. Arhitektūra, kas balstīta uz epoll

Avots: habr.com

Iegādājieties uzticamu tīmekļa hostingu ar DDoS aizsardzību, VPS VDS serveriem 🔥 Iegādājieties uzticamu tīmekļa hostingu ar DDoS aizsardzību, VPS VDS serveriem | ProHoster