Prestazione di l'applicazione di rete Linux. Introduzione

L'applicazioni web sò avà aduprate in ogni locu, è trà tutti i protokolli di trasportu, HTTP occupa a parte di u leone. Quandu studia i sfumaturi di u sviluppu di l'applicazioni web, a maiò parte di a ghjente presta assai poca attenzione à u sistema operatore induve queste applicazioni funzionanu. A separazione di u sviluppu (Dev) è l'operazioni (Ops) hà solu peghju a situazione. Ma cù l'aumentu di a cultura DevOps, i sviluppatori sò diventati rispunsevuli di eseguisce e so applicazioni in u nuvulu, per quessa, hè assai utile per elli à familiarizà bè cù u backend di u sistema operatore. Questu hè soprattuttu utile sè vo circate di implementà un sistema per millaie o decine di millaie di cunnessione simultanee.

I limitazioni in i servizii web sò assai simili à quelli in altre applicazioni. Qu'il s'agisse d'équilibreurs de charges ou de serveurs de bases de données, toutes ces applications ont des problèmes similaires dans un environnement à haut rendement. A capiscitura di sti limitazioni fundamentali è cumu per superà in generale vi aiuterà à valutà u rendiment è a scalabilità di e vostre applicazioni web.

Scrivu sta serie d'articuli in risposta à e dumande di i ghjovani sviluppatori chì volenu diventà architetti di sistemi ben infurmati. Hè impussibile di capisce chjaramente e tecniche di ottimisazione di l'applicazioni Linux senza immersione in i principii di cumu si travaglianu à u livellu di u sistema operatore. Ancu s'ellu ci sò parechji tippi d'applicazioni, in questa serie vogliu esplorà l'applicazioni basate in u web invece di l'applicazioni di desktop cum'è un navigatore o un editore di testu. Stu materiale hè destinatu à i sviluppatori è l'architetti chì volenu capisce cumu funziona i prugrammi Linux o Unix è cumu si strutturanu per un altu rendiment.

Linux hè sala di servitori sistema upirativu, è u più spessu i vostri appiicazioni funzionanu in questu OS. Ancu s'ellu dicu "Linux", a maiò parte di u tempu pudete assicurà in modu sicuru chì vogliu dì tutti i sistemi operativi Unix-like in generale. Tuttavia, ùn aghju micca pruvatu u codice accumpagnatu in altri sistemi. Allora, sè vo site interessatu in FreeBSD o OpenBSD, i vostri risultati pò varià. Quandu pruvu qualcosa specificu à Linux, l'aghju indicatu.

Mentre pudete aduprà sta cunniscenza per custruisce una app da zero è serà perfettamenti ottimizzata, hè megliu micca fà quessa. Se scrivite un novu servitore web in C o C++ per l'applicazione cummerciale di a vostra urganizazione, questu pò esse u vostru ultimu ghjornu nantu à u travagliu. Tuttavia, cunnosce a struttura di sti appiicazioni vi aiuterà à sceglie prugrammi esistenti. Puderete paragunà i sistemi basati in prucessu cù i sistemi basati in filu è ancu quelli basati in l'avvenimenti. Puderete capisce è apprezzà perchè Nginx rende megliu cà Apache httpd, perchè una applicazione Python basata in Tornado pò serve più utenti cumparatu cù una applicazione Python basata in Django.

ZeroHTTPd: Strumenta di apprendimentu

ZeroHTTPd hè un servitore web chì aghju scrittu da zero in C cum'è strumentu d'insignamentu. Ùn hà micca dipendenze esterne, cumpresu l'accessu à Redis. Eseguimu e nostre prucedure Redis. Vede quì sottu per più dettagli.

Ancu s'è puderemu discutiri a teoria in longu, ùn ci hè nunda di megliu cà scrive codice, eseguisce, è paragunà tutte l'architetture di u servitore cù l'altri. Questu hè u metudu più evidenti. Dunque, scriveremu un servitore web ZeroHTTPd simplice utilizendu ogni mudellu: basatu in prucessu, basatu in filu è basatu in avvenimenti. Cuntrollamu ognunu di sti servitori è vede cumu si cumportanu paragunatu à l'altri. ZeroHTTPd hè implementatu in un unicu schedariu C U servitore basatu in l'avvenimentu include uthash, una grande implementazione di a tavola hash chì vene in un unicu file di header. In altri casi, ùn ci sò micca dipendenze, per ùn cumplicà u prugettu.

Ci sò assai cumenti in u codice per aiutà à capiscenu. Essendu un servitore web simplice in uni pochi di linee di codice, ZeroHTTPd hè ancu un framework minimu per u sviluppu web. Hà una funziunalità limitata, ma hè capace di serve schedarii statichi è pagine "dinamiche" assai simplici. Devu dì chì ZeroHTTPd hè bonu per amparà cumu creà applicazioni Linux d'altu rendiment. In generale, a maiò parte di i servizii web aspettanu e dumande, verificate è processate. Questu hè esattamente ciò chì ZeroHTTPd farà. Questu hè un strumentu per l'apprendimentu, micca a produzzione. Ùn hè micca grande in a gestione di l'errore è hè improbabile di vantarà e migliori pratiche di sicurezza (oh sì, aghju utilizatu strcpy) o i trucchi intelligenti di a lingua C Ma spergu chì faci bè u so travagliu.

Prestazione di l'applicazione di rete Linux. Introduzione
Pagina iniziale di ZeroHTTPd. Si pò pruduce diversi tipi di schedari cumpresi images

Applicazione di u Libru d'ospiti

L'applicazioni web muderni sò generalmente micca limitati à i schedari statici. Hanu interazzione cumplessu cù diverse basa di dati, cache, etc. Allora avemu da creà una applicazione web simplice chjamata "Guest Book" induve i visitori lascianu entrate sottu i so nomi. U libru di l'ospiti conserva e entrate lasciate prima. Ci hè ancu un contatore di visitatori à u fondu di a pagina.

Prestazione di l'applicazione di rete Linux. Introduzione
Applicazione Web "Guest Book" ZeroHTTPd

U contatore di i visitori è l'entrata di u libru d'ospiti sò almacenati in Redis. Per a cumunicazione cù Redis, i prucedure propiu sò implementati, ùn dependenu micca di a biblioteca esterna. Ùn sò micca un grande fan di sparghje u codice homebrew quandu ci sò soluzioni publicamente dispunibuli è bè testate. Ma u scopu di ZeroHTTPd hè di studià u rendiment Linux è l'accessu à i servizii esterni, mentre chì serve richieste HTTP hà un impattu seriu di rendiment. Avemu da cuntrullà cumplettamente e cumunicazioni cù Redis in ognuna di e nostre architetture di u servitore. In certi architetture usemu chjamati bluccanti, in altri utilizemu prucedure basate in l'avvenimenti. Utilizà una biblioteca di cliente Redis esterna ùn furnisce micca stu cuntrollu. Inoltre, u nostru picculu cliente Redis eseguisce solu uni pochi di funzioni (ottene, stabilisce è incrementa una chjave; uttene è appendu à un array). Inoltre, u protocolu Redis hè estremamente elegante è simplice. Ùn avete mancu bisognu di insignà in particulare. U fattu stessu chì u protokollu faci tuttu u travagliu in circa un centu di linee di codice mostra quantu ben pensatu hè.

A figura seguente mostra ciò chì l'applicazione face quandu u cliente (navigatore) dumanda /guestbookURL.

Prestazione di l'applicazione di rete Linux. Introduzione
Cumu funziona l'applicazione di u libru d'ospiti

Quandu una pagina di u libru d'ospiti deve esse emessa, ci hè una chjama à u sistema di fugliale per leghje u mudellu in memoria è trè chjama di rete à Redis. U schedariu di mudellu cuntene a maiò parte di u cuntenutu HTML per a pagina in a screenshot sopra. Ci hè ancu un locu speciale per a parte dinamica di u cuntenutu: posti è contatore di visitatori. Ricevemu da Redis, inserite in a pagina è furnisce u cliente cun cuntenutu sanu furmatu. A terza chjama à Redis pò esse evitata perchè Redis torna u novu valore chjave quandu aumenta. In ogni casu, per u nostru servitore, chì hà una architettura asincrona basata nantu à l'avvenimenti, assai chjama di rete sò una bona prova per scopi di apprendimentu. Allora scartamu u valore di ritornu Redis di u numeru di visitatori è l'interroghemu cù una chjama separata.

Architettura di u servitore ZeroHTTPd

Custruemu sette versioni di ZeroHTTPd cù a listessa funziunalità ma diverse architetture:

  • Iterativu
  • Servitore Fork (un prucessu zitellu per dumanda)
  • Servitore di pre-fork (pre-fork di prucessi)
  • Servitore cù fili di esecuzione (un filu per dumanda)
  • Servitore cù creazione di pre-thread
  • Basatu nantu à l'architettura poll()
  • Basatu nantu à l'architettura epoll

Misuremu a prestazione di ogni architettura carchendu u servitore cù richieste HTTP. Ma quandu paragunate architetture altamente parallele, u numeru di dumande aumenta. Testemu trè volte è calculemu a media.

Metodologia di prova

Prestazione di l'applicazione di rete Linux. Introduzione
Configurazione di teste di carica ZeroHTTPd

Hè impurtante chì quandu eseguite e teste, tutti i cumpunenti ùn viaghjanu micca nantu à a stessa macchina. In questu casu, u sistema operativu incurre un overhead di pianificazione supplementu cum'è cumpunenti compete per CPU. A misurazione di u sistema operatore sopra di ognuna di l'architetture di u servitore sceltu hè unu di i scopi più impurtanti di questu esercitu. Aghjunghjendu più variàbili diventerà preghjudiziu à u prucessu. Per quessa, u paràmetru in a stampa sopra funziona megliu.

Chì facenu ognunu di sti servitori?

  • load.unixism.net: Questu hè induve corremu ab, Utilità Apache Benchmark. Genera a carica necessaria per pruvà e nostre architetture di u servitore.
  • nginx.unixism.net: A volte vulemu eseguisce più di una istanza di un prugramma di servitore. Per fà questu, u servitore Nginx cù i paràmetri appropritati funziona cum'è un equilibratore di carica chì vene da ab à i nostri prucessi di u servitore.
  • zerohttpd.unixism.net: Quì eseguimu i nostri prugrammi di u servitore nantu à sette architetture diverse, una per volta.
  • redis.unixism.net: Stu servitore esegue u daemon Redis, induve l'entrata di u libru d'ospiti è i contatori di visitatori sò almacenati.

Tutti i servitori funzionanu nantu à u stessu core di processore. L'idea hè di valutà a prestazione massima di ogni architettura. Siccomu tutti i prugrammi di u servitore sò pruvati nantu à u stessu hardware, questu hè una basa di paraguni. A mo cunfigurazione di prova hè custituita da servitori virtuali affittati da Digital Ocean.

Chì misuremu ?

Pudete misurà diversi indicatori. Evaluemu u funziunamentu di ogni architettura in una cunfigurazione data carchendu i servitori cù richieste à diversi livelli di parallelismu: a carica cresce da 20 à 15 000 utenti simultanei.

Risultati di test

U graficu seguente mostra a prestazione di i servitori in diverse architetture à diversi livelli di parallelismu. L'assi y hè u numeru di richieste per seconda, l'assi x hè cunnessione parallela.

Prestazione di l'applicazione di rete Linux. Introduzione

Prestazione di l'applicazione di rete Linux. Introduzione

Prestazione di l'applicazione di rete Linux. Introduzione

A sottu hè una tavula cù i risultati.

richieste per seconda

paralelisimu
iterativu
forchetta
pre-furchetta
streaming
pre-streaming
vota
epollu

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
larga diffusione
2138

5000
-
larga diffusione
1600
1100
2519
-
2235

8000
-
-
1200
larga diffusione
2451
-
2100

10
-
-
larga diffusione
-
2200
-
2200

11
-
-
-
-
2200
-
2122

12
-
-
-
-
970
-
1958

13
-
-
-
-
730
-
1897

14
-
-
-
-
590
-
1466

15
-
-
-
-
532
-
1281

Da u graficu è a tavula si pò vede chì sopra à 8000 dumande simultanee avemu solu dui ghjucatori: pre-fork è epoll. Quandu a carica aumenta, un servitore basatu in sondaggi rende peggiu chè un streaming. L'architettura di pre-creazione di filu hè un cuncurrente degnu per epoll, un testimoniu di quantu u kernel Linux pianifica un gran numaru di fili.

Codice Source ZeroHTTPd

Codice Source ZeroHTTPd ccà. Ci hè un repertoriu separatu per ogni architettura.

ZeroHTTPd │ ├── 01_iterative │ ├── main.c ├── 02_forking │ ├── main.c ├── 03_preforking │── ├─ _esima lettura │ ├── main.c ├── 04_prethreading │ ├── main.c ├── 05_poll │ ├── main.c ├── 06_epoll │ └── 07_poll │ ├── main.c ├── XNUMX_epoll │ └── └── rende public.c ├─ ── index html │ └── tux png └── mudelli └── guestbook └── index.html

In più di sette cartulari per tutte l'architetture, ci sò dui più in u cartulare di primu livellu: publicu è mudelli. U primu cuntene u schedariu index.html è l'imaghjini da a prima screenshot. Pudete mette altri schedarii è cartulare, è ZeroHTTPd duveria serve i schedari statici senza prublemi. Se u percorsu in u navigatore currisponde à u percorsu in u cartulare publicu, allora ZeroHTTPd cerca u schedariu index.html in questu repertoriu. U cuntenutu per u libru d'ospiti hè generatu dinamicamente. Hè solu una pagina di casa, è u so cuntenutu hè basatu annantu à u schedariu "templates/guestbook/index.html". ZeroHTTPd aghjunghje facilmente pagine dinamiche per estensione. L'idea hè chì l'utilizatori ponu aghjunghje mudelli à questu repertoriu è allargà ZeroHTTPd quantu necessariu.

Per custruisce tutti i sette servitori, eseguite make all da u cartulare di primu livellu - è tutte e custruzzioni appariscenu in questu cartulare. I fugliali eseguibili cercanu i repertorii publichi è mudelli in u cartulare da quale sò lanciati.

API Linux

Ùn avete bisognu à esse bè versatu in l'API Linux per capisce l'infurmazioni in questa serie d'articuli. Tuttavia, ricumandemu di leghje più nantu à questu tema ci sò parechje risorse di riferimentu in Internet. Ancu s'ellu ci tocca à parechje categurie di API Linux, u nostru focusu serà principalmente nantu à i prucessi, i fili, l'avvenimenti è a pila di rete. In più di libri è articuli nantu à l'API Linux, ricumandemu ancu di leghje mana per i chjami di u sistema è e funzioni di biblioteca utilizati.

Prestazione è scalabilità

Una nota nantu à u rendiment è a scalabilità. In teoria, ùn ci hè micca una cunnessione trà elli. Pudete avè un serviziu web chì travaglia assai bè, cù un tempu di risposta di uni pochi millisecondi, ma ùn scala micca in tuttu. In listessu modu, ci pò esse una applicazione web mal prestata chì pigghia uni pochi di seconde per risponde, ma scala da decine per trattà decine di millaie di utilizatori simultanei. Tuttavia, a cumminazzioni di altu rendiment è scalabilità hè una cumminazione assai putente. L'applicazioni d'altu rendiment generalmente utilizanu risorse cù parsimonia è cusì serve in modu efficiente à l'utilizatori più cuncurrenti in u servitore, riducendu i costi.

CPU è attività I/O

Infine, in l'informatica, ci sò sempre dui tipi di cumpetenze pussibuli: per I/O è CPU. Riceve dumande nantu à Internet (I/O di rete), serve i schedari (I/O di rete è di discu), cumunicà cù a basa di dati (I/O di rete è di discu) sò tutte l'attività I/O. Alcune dumande di basa di dati ponu esse un pocu CPU intensive (selezzione, una media di un milione di risultati, etc.). A maiò parte di l'applicazioni web sò limitati da u massimu I / O pussibule, è u processatore hè raramente utilizatu à piena capacità. Quandu vi vede chì qualchissimu compitu I / O usa assai CPU, hè più prubabile un signu di l'architettura di l'applicazione povera. Questu pò significà chì e risorse di CPU sò sprecate in a gestione di u prucessu è u cambiamentu di u cuntestu - è questu ùn hè micca sanu utile. Sè vo fate qualcosa cum'è trasfurmazioni di l'imaghjini, cunversione di file audio, o apprendimentu automaticu, allora l'applicazione richiede risorse CPU putenti. Ma per a maiò parte di l'applicazioni questu ùn hè micca u casu.

Sapete più nantu à l'architettura di u servitore

  1. Parte I: Architettura iterativa
  2. Parte II. Servitori di furchetta
  3. Parte III. Servitori pre-fork
  4. Parte IV. Servitori cù fili d'esekzione
  5. Part V. Servitori pre-threaded
  6. Part VI. Architettura basatu in Pol
  7. Parte VII. architettura basatu à epoll

Source: www.habr.com

Add a comment